matplotlib中的多轴,具有不同的比例

如何在Matplotlib中实现多个比例? 我不是在讨论与同一个x轴绘制的主轴和副轴,而是像许多不同尺度的趋势,这些趋势在同一个y轴上绘制并且可以通过它们的颜色来标识。

例如,如果我将trend1 ([0,1,2,3,4])trend2 ([5000,6000,7000,8000,9000])与时间作图,并希望两个趋势具有不同的颜色而在Y轴,不同的尺度,我怎样才能完成Matplotlib这个?

当我看着Matplotlib,他们说他们现在没有这个,虽然这绝对是他们的愿望清单,有没有办法做到这一点?

有没有其他的绘图工具可以使这种情况发生?

如果我明白这个问题,你可能会对Matplotlib库中的这个例子感兴趣。

在这里输入图像说明

Yann上面的评论提供了一个类似的例子。


编辑 – 链接上面的固定。 从Matplotlib库复制相应的代码:

 from mpl_toolkits.axes_grid1 import host_subplot import mpl_toolkits.axisartist as AA import matplotlib.pyplot as plt host = host_subplot(111, axes_class=AA.Axes) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() offset = 60 new_fixed_axis = par2.get_grid_helper().new_fixed_axis par2.axis["right"] = new_fixed_axis(loc="right", axes=par2, offset=(offset, 0)) par2.axis["right"].toggle(all=True) host.set_xlim(0, 2) host.set_ylim(0, 2) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.legend() host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) plt.draw() plt.show() #plt.savefig("Test") 

如果你想使用二级Y轴做快速绘图,那么使用Pandas包装函数和仅仅两行代码就容易得多。 只需绘制你的第一列,然后绘制第二个,但参数secondary_y=True ,如下所示:

 df.A.plot(label="Points", legend=True) df.B.plot(secondary_y=True, label="Comments", legend=True) 

这看起来像下面这样:

在这里输入图像说明

你也可以做更多的事情。 看看大pandas密谋文件 。

使用@ joe-kington的答案快速引导一些东西来绘制多个共享x轴的y轴: 在这里输入图像说明

 # d = Pandas Dataframe, # ys = [ [cols in the same y], [cols in the same y], [cols in the same y], .. ] def chart(d,ys): from itertools import cycle fig, ax = plt.subplots() axes = [ax] for y in ys[1:]: # Twin the x-axis twice to make independent y-axes. axes.append(ax.twinx()) extra_ys = len(axes[2:]) # Make some space on the right side for the extra y-axes. if extra_ys>0: temp = 0.85 if extra_ys<=2: temp = 0.75 elif extra_ys<=4: temp = 0.6 if extra_ys>5: print 'you are being ridiculous' fig.subplots_adjust(right=temp) right_additive = (0.98-temp)/float(extra_ys) # Move the last y-axis spine over to the right by x% of the width of the axes i = 1. for ax in axes[2:]: ax.spines['right'].set_position(('axes', 1.+right_additive*i)) ax.set_frame_on(True) ax.patch.set_visible(False) ax.yaxis.set_major_formatter(matplotlib.ticker.OldScalarFormatter()) i +=1. # To make the border of the right-most axis visible, we need to turn the frame # on. This hides the other plots, however, so we need to turn its fill off. cols = [] lines = [] line_styles = cycle(['-','-','-', '--', '-.', ':', '.', ',', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd', '|', '_']) colors = cycle(matplotlib.rcParams['axes.color_cycle']) for ax,y in zip(axes,ys): ls=line_styles.next() if len(y)==1: col = y[0] cols.append(col) color = colors.next() lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color)) ax.set_ylabel(col,color=color) #ax.tick_params(axis='y', colors=color) ax.spines['right'].set_color(color) else: for col in y: color = colors.next() lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color)) cols.append(col) ax.set_ylabel(', '.join(y)) #ax.tick_params(axis='y') axes[0].set_xlabel(d.index.name) lns = lines[0] for l in lines[1:]: lns +=l labs = [l.get_label() for l in lns] axes[0].legend(lns, labs, loc=0) plt.show() 

由于史蒂夫Tjoa的答案总是首先popup,当我在谷歌search多个Y轴,大多是孤独的,我决定添加一个稍微修改他的答案的版本。

原因:

  • 在未知的情况下,他的模块有时会失败,而且隐晦的实习生错误。
  • 我不喜欢加载我不知道的外来模块( mpl_toolkits.axisartistmpl_toolkits.axes_grid1 )。
  • 下面的代码包含了人们常常偶然发现的问题的更明确的命令(比如多个轴的单个图例,使用viridis,…)而不是隐式行为。

情节

 import matplotlib.pyplot as plt fig = plt.figure() host = fig.add_subplot(111) par1 = host.twinx() par2 = host.twinx() host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") color1 = plt.cm.viridis(0) color2 = plt.cm.viridis(0.5) color3 = plt.cm.viridis(.9) p1, = host.plot([0, 1, 2], [0, 1, 2], color=color1,label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], color=color2, label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], color=color3, label="Velocity") lns = [p1, p2, p3] host.legend(handles=lns, loc='best') # right, left, top, bottom par2.spines['right'].set_position(('outward', 60)) # no x-ticks par2.xaxis.set_ticks([]) # Sometimes handy, same for xaxis #par2.yaxis.set_ticks_position('right') host.yaxis.label.set_color(p1.get_color()) par1.yaxis.label.set_color(p2.get_color()) par2.yaxis.label.set_color(p3.get_color()) plt.savefig("pyplot_multiple_y-axis.png", bbox_inches='tight')