matplotlib中的多轴具有不同的尺度

Jac*_*des 67 python matplotlib

如何在Matplotlib中实现多个尺度?我不是在谈论相对于相同的x轴绘制的主轴和次轴,而是类似于许多趋势,其具有在相同的y轴上绘制的不同尺度并且可以通过它们的颜色来识别.

举例来说,如果我有trend1 ([0,1,2,3,4])trend2 ([5000,6000,7000,8000,9000])对时间绘制,并希望这两个趋势是不同的颜色和Y轴,不同的尺度,我怎么能做到这一点与Matplotlib?

当我调查Matplotlib时,他们说他们现在没有这个,虽然它肯定在他们的心愿单上,有没有办法实现这一目标?

是否有任何其他的python绘图工具可以实现这一目标?

Ste*_*joa 95

如果我理解了这个问题,您可能会对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")
Run Code Online (Sandbox Code Playgroud)

  • -1因为隐藏在链接后面的答案不太有用并且容易腐烂. (5认同)
  • `par1.axis["right"].toggle(all=True)` 丢失! (3认同)

Shi*_*hah 51

如果你想用辅助Y轴进行非常快速的绘图,那么使用Pandas包装函数和仅仅2行代码就有了更简单的方法.只需绘制第一列,然后绘制第二列但使用参数secondary_y=True,如下所示:

df.A.plot(label="Points", legend=True)
df.B.plot(secondary_y=True, label="Comments", legend=True)
Run Code Online (Sandbox Code Playgroud)

这看起来如下所示:

在此输入图像描述

你也可以做更多的事情.看看Pandas密谋文档.

  • secondary_y = True做到了 (5认同)
  • 这是否适用于 2 行以上?似乎这种方法仅限于最多 2 行? (3认同)

Suu*_*hgi 46

由于当我在谷歌搜索多个y轴时,Steve Tjoa的答案总是首先出现并且大多是孤独的,所以我决定添加他的答案的略微修改版本.这是来自这个matplotlib示例的方法.

原因:

  • 在未知的环境和神秘的实习生错误中,他的模块有时会失败.
  • 我不喜欢加载我不知道的奇异模块(mpl_toolkits.axisartist,mpl_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')
Run Code Online (Sandbox Code Playgroud)

  • +1表示允许使用标准matplotlib模块的版本.我还引导当前用户使用现代的,更加pythonic的`subplots()`方法突出显示[here](https://matplotlib.org/users/recipes.html)和jarondl敦促[这里]( /sf/ask/250936381/#comment18305007_3584933).幸运的是,它适用于这个答案.您只需要在导入后用`fig,host = plt.subplots(nrows = 1,ncols = 1)`替换两行. (3认同)
  • 我还注意到这个答案仍然允许应用[Rutger Kassies解决方案](/sf/answers/1410299481/)将辅助轴(也称为寄生虫轴)移动到左侧.在这段代码中,为了做到这一点,你要用以下**四行**代替`par2.spines ['right'].set_position(('向外',60))```par2.spines ['left' ] .set_position(('向外',60))``par2.spines ["left"].set_visible(True)``par2.yaxis.set_label_position('left')``par2.yaxis.set_ticks_position('left' )` (2认同)
  • @Wayne 谢谢你的提示!我在上面合并了它们。 (2认同)

Nas*_*ibi 18

使用@ 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()
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

119772 次

最近记录:

6 年,7 月 前