【问题标题】:How to arrange plots of secondary axis to be below plots of primary axis in matplotlib?如何在matplotlib中将次轴图排列在主轴图下方?
【发布时间】:2015-05-28 11:42:15
【问题描述】:

我正在尝试在两个 y 轴上绘制两条曲线,如图所示。但是,即使我将红色图(压力)的 zorder 设置为 1 和 2,但绿色图(提针)仍绘制在主轴图上方。

我使用的代码:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import ticker as tick
data = np.genfromtxt("secondary_axis.dat", skiprows = 2, delimiter = ',')
time = data[:, 0]
pressure = data[:, 1] * 0.006894759086775369
pressure_charge = data[0, 0]
needle_lift = data[:, 2]
figure = plt.figure(figsize=(5.15, 5.15))
figure.clf()
plot = plt.subplot(111)
plot.plot(time, pressure, label = r'\textit{Raw}', zorder = 2)
plot.set_xlabel(r'\textit{X}', labelpad=6)
plot.set_ylabel(r'\textit{Y}', labelpad=6)
primary_ticks = len(plot.yaxis.get_major_ticks())
ax2 = plot.twinx()
ax2.plot(time, needle_lift, color='#4DAF4A', zorder = 1)
ax2.grid(False)
ax2.set_ylabel(r'\textit{Z}', labelpad=6)
ax2.yaxis.set_major_locator(tick.LinearLocator(primary_ticks))
plt.show()

数据可用here

如何使用 matplotlib 将绿色(提针)图置于红色图(压力)下方?

使用 rc 设置更新代码

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc_context
from matplotlib import ticker as tick


def init_plot_dark():
    params = {'backend' : 'agg', 'legend.numpoints' : 1,
    'lines.linewidth' : 1.0, 'lines.linestyle' : '-', 'axes.facecolor' : '#EEEEEE', 'axes.edgecolor' : '#FFFFFF',
    'axes.linewidth' : 0.0, 'axes.grid' : True, 'axes.titlesize' : 'large', 'axes.labelsize' : 12, 'axes.labelweight' : 'normal',
    'axes.labelcolor' : '000000', 'axes.axisbelow' : True, 'polaraxes.grid' : True , 'axes3d.grid' : True,
    'axes.color_cycle' : ('#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33', '#A65628', '#F781BF', '#999999'),
    'xtick.major.size' : 4 ,'xtick.minor.size' : 2 ,'xtick.major.width' : 0 ,'xtick.minor.width' : 0 ,'xtick.major.pad' : 6,
    'xtick.minor.pad' : 6, 'xtick.color' : '#000000' , 'xtick.labelsize' : 10, 'xtick.direction' : 'in',
    'ytick.major.size' : 4, 'ytick.minor.size' : 2 ,'ytick.major.width' : 0 ,'ytick.minor.width' : 0 ,'ytick.major.pad' : 6,
    'ytick.minor.pad' : 6 ,'ytick.color' : '#000000', 'ytick.labelsize' : 10, 'ytick.direction' : 'in',
    'grid.color' : '#FFFFFF', 'grid.linestyle' : '-', 'grid.linewidth' : 0.5, 'grid.alpha' : 1.0,
    'legend.fontsize' : 10, 'legend.borderaxespad' : 0.5, 'legend.shadow' : False, 'legend.frameon' : True}
    plt.rcParams.update(params)

init_plot_dark()

data = np.genfromtxt("secondary_axis.dat", skiprows = 2, delimiter = ',')
time = data[:, 0]
pressure = data[:, 1] * 0.006894759086775369
pressure_charge = data[0, 0]
needle_lift = data[:, 2]
figure = plt.figure(figsize=(5.15, 5.15))
figure.clf()
plot = plt.subplot(111)
plot.plot(time, pressure, label = r'\textit{Raw}', zorder = 2)
plot.set_xlabel(r'\textit{X}', labelpad=6)
plot.set_ylabel(r'\textit{Y}', labelpad=6)
primary_ticks = len(plot.yaxis.get_major_ticks())
ax2 = plot.twinx()
ax2.plot(time, needle_lift, color='#4DAF4A', zorder = 1)
ax2.grid(False)
ax2.set_ylabel(r'\textit{Z}', labelpad=6)
ax2.yaxis.set_major_locator(tick.LinearLocator(primary_ticks))
plt.show()

【问题讨论】:

    标签: python matplotlib plot


    【解决方案1】:

    您需要将第一个轴的 zorder 设置为高于您的第二个轴的 zorder,但您需要在绘制它们之后执行此操作。在 plt.show() 之前添加这两行

    plot.set_zorder(ax2.get_zorder()+1)
    plot.set_frame_on(False)
    

    第一行得到正确的 zorder,但会完全隐藏第二个轴。因此,我们还需要使用第二行删除画布。


    注意:在此答案的旧版本中,我使用的是 plot.patch.set_visible(False),而不是 plot.set_frame_on(False),但这不再起作用(至少截至 2021 年 11 月,matplotlib v3.4.2,但是可能比这更早)


    编辑

    要使用rcParams 正确设置网格线,您可以执行以下操作:切换在plot 轴和ax2 轴上绘制哪条线(即ax2 上的压力和针头提升plot),然后更改它们的轴和刻度标签在哪一侧:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import rc_context
    from matplotlib import ticker as tick
    
    
    def init_plot_dark():
        params = {'backend' : 'agg', 'legend.numpoints' : 1,
        'lines.linewidth' : 1.0, 'lines.linestyle' : '-', 'axes.facecolor' : '#EEEEEE', 'axes.edgecolor' : '#FFFFFF',
        'axes.linewidth' : 0.0, 'axes.grid' : True, 'axes.titlesize' : 'large', 'axes.labelsize' : 12, 'axes.labelweight' : 'normal',
        'axes.labelcolor' : '000000', 'axes.axisbelow' : True, 'polaraxes.grid' : True , 'axes3d.grid' : True,
        'axes.color_cycle' : ('#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33', '#A65628', '#F781BF', '#999999'),
        'xtick.major.size' : 4 ,'xtick.minor.size' : 2 ,'xtick.major.width' : 0 ,'xtick.minor.width' : 0 ,'xtick.major.pad' : 6,
        'xtick.minor.pad' : 6, 'xtick.color' : '#000000' , 'xtick.labelsize' : 10, 'xtick.direction' : 'in',
        'ytick.major.size' : 4, 'ytick.minor.size' : 2 ,'ytick.major.width' : 0 ,'ytick.minor.width' : 0 ,'ytick.major.pad' : 6,
        'ytick.minor.pad' : 6 ,'ytick.color' : '#000000', 'ytick.labelsize' : 10, 'ytick.direction' : 'in',
        'grid.color' : '#FFFFFF', 'grid.linestyle' : '-', 'grid.linewidth' : 0.5, 'grid.alpha' : 1.0,
        'legend.fontsize' : 10, 'legend.borderaxespad' : 0.5, 'legend.shadow' : False, 'legend.frameon' : True}
        plt.rcParams.update(params)
    
    init_plot_dark()
    
    data = np.genfromtxt("secondary_axis.dat", skiprows = 2, delimiter = ',')
    time = data[:, 0]
    pressure = data[:, 1] * 0.006894759086775369
    pressure_charge = data[0, 0]
    needle_lift = data[:, 2]
    figure = plt.figure(figsize=(5.15, 5.15))
    figure.clf()
    plot = plt.subplot(111)
    plot.plot(time, needle_lift, color='#4DAF4A', zorder = 1)
    plot.set_xlabel(r'\textit{X}', labelpad=6)
    plot.set_ylabel(r'\textit{Z}', labelpad=6)
    ax2 = plot.twinx()
    ax2.plot(time, pressure, label = r'\textit{Raw}', zorder = 2)
    ax2.grid(False)
    ax2.set_ylabel(r'\textit{Y}', labelpad=6)
    primary_ticks = len(ax2.yaxis.get_major_ticks())
    plot.yaxis.set_major_locator(tick.LinearLocator(primary_ticks))
    
    plot.yaxis.tick_right()
    plot.yaxis.set_label_position("right")
    
    ax2.yaxis.tick_left()
    ax2.yaxis.set_label_position("left")
    
    plt.show()
    

    【讨论】:

    • 它可以工作,但我的网格线位于图上方。
    • 但我在 matplotlib rc 参数文件中有它们。
    • 在不知道你用来制作情节的所有代码的情况下,很难修复它。
    • @nxkryptor 我已经更新了答案以应对您的网格线
    【解决方案2】:

    上面的答案是正确的,但我想写一个更短更简单的。

    给定:

    fig, ax1 = plt.subplots()
    ax2 = ax1.twiny()
    

    只需添加(某处,在绘图之前或之后):

    ax1.set_zorder(1)  # default zorder is 0 for ax1 and ax2
    ax1.patch.set_visible(False)  # prevents ax1 from hiding ax2
    

    【讨论】:

    • 使用 ax1.set_frame_on(False) 获取较新版本的 matplotlib。 ax1.patch.set_visible(False) 不再适合我了
    猜你喜欢
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2021-09-14
    • 1970-01-01
    • 2020-07-01
    相关资源
    最近更新 更多