matplotlib 中是否可以有给定数量(n>2)的 y 轴?

prices = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),

                   columns=['a', 'b', 'c'])

我有我的prices数据框,它目前有 3 列。但在其他时候,它可能有更多或更少的列。有没有办法使用某种twinx()循环来创建具有(可能)无限数量的 y 轴的所有不同时间序列的折线图?


我尝试了下面的双循环,但我得到了typeError'd:bTypeError: 'AxesSubplot' object does not support item assignment


# for i in range(0,len(prices.columns)):

#     for column in list(prices.columns):

#         fig, ax[i] = plt.subplots()

#         ax[i].set_xlabel(prices.index()) 

#         ax[i].set_ylabel(column[i]) 

#         ax[i].plot(prices.Date, prices[column]) 

#         ax[i].tick_params(axis ='y') 

#         ax[i+1] = ax[i].twinx() 

#         ax[i+1].set_ylabel(column[i+1]) 

#         ax[i+1].plot(prices.Date, column[i+1]) 

#         ax[i+1].tick_params(axis ='y') 

#         fig.suptitle('matplotlib.pyplot.twinx() function \ Example\n\n', fontweight ="bold") 

#         plt.show() 

# =============================================================================

我相信我明白为什么会收到错误 -ax对象不允许分配变量i。我希望有一些巧妙的方法来实现这一目标。


largeQ
浏览 106回答 1
1回答

慕运维8079593

事实证明,主要问题是您不应该将 pandas 绘图函数与 matplotlib 混合使用,这会导致轴重复。否则,实现是相当直接的,改编自这个matplotlib 示例。from mpl_toolkits.axes_grid1 import host_subplotimport mpl_toolkits.axisartist as AAfrom matplotlib import pyplot as pltfrom itertools import cycleimport pandas as pd#fake data creation with different spread for different axes#this entire block can be deleted if you import your dffrom pandas._testing import rands_arrayimport numpy as npfakencol=5fakenrow=7np.random.seed(20200916)df = pd.DataFrame(np.random.randint(1, 10, fakenrow*fakencol).reshape(fakenrow, fakencol), columns=rands_array(2, fakencol))df = df.multiply(np.power(np.asarray([10]), np.arange(fakencol)))df.index = pd.date_range("20200916", periods=fakenrow)#defining a color scheme with unique colors#if you want to include more than 20 axes, well, what can I saysc_color = cycle(plt.cm.tab20.colors)#defining the size of the figure in relation to the number of dataframe columns#might need adjustment for optimal data presentationoffset = 60plt.rcParams['figure.figsize'] = 10+df.shape[1], 5#host figure and first plothost = host_subplot(111, axes_class=AA.Axes)h, = host.plot(df.index, df.iloc[:, 0], c=next(sc_color), label=df.columns[0])host.set_ylabel(df.columns[0])host.axis["left"].label.set_color(h.get_color())host.set_xlabel("time")#plotting the rest of the axesfor i, cols in enumerate(df.columns[1:]):      curr_ax = host.twinx()           new_fixed_axis = curr_ax.get_grid_helper().new_fixed_axis    curr_ax.axis["right"] = new_fixed_axis(loc="right",                                axes=curr_ax,                                offset=(offset*i, 0))        curr_p, = curr_ax.plot(df.index, df[cols], c=next(sc_color), label=cols)        curr_ax.axis["right"].label.set_color(curr_p.get_color())    curr_ax.set_ylabel(cols)    curr_ax.yaxis.label.set_color(curr_p.get_color())plt.legend()plt.tight_layout()plt.show()想想看 - 将轴平均分配到图的左侧和右侧可能会更好。那好吧。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python