【问题标题】:Multiple y-axis conversion scales多个 y 轴转换刻度
【发布时间】:2014-09-29 08:03:52
【问题描述】:

我正在尝试创建包含 y 轴上两组单位的平行转换比例的图;使用两种不同的风格:

  1. 偏移(“寄生”)y 轴和
  2. 重叠/共享 y 轴

复制所附示例图像中左侧 y 轴的样式。

我想找到生成上述两个示例图的最简单通用方法,它还允许我通过将两组单位之间的关系定义为函数来生成 y 轴转换比例(在此例如:mmHg = kPa * 7.5)。

如果可以添加这些示例中显示的与左侧刻度无关的第三个右侧 y 轴(蒸汽浓度和水含量),这将是一个奖励。

我已经阅读了有关使用 twinx 和 twiny 函数使用多个 x 和 y 轴的相关 stackoverflow.com 帖子和示例 - 例如 here - 以及 Matplotlib 食谱,但我找不到解决此特定问题的示例。

我将非常感谢任何最小的工作示例或链接。

我在 Spyder 2.2.1 / Python 2.7.5 中使用 Matplotlib

非常感谢期待

戴夫

【问题讨论】:

    标签: python matplotlib plot axis-labels data-conversion


    【解决方案1】:

    对于第一个情节,我推荐axisartist。左侧两个y 轴的自动缩放是通过适用于指定y 限制的简单缩放因子实现的。第一个例子是基于parasite axes上的解释:

    import numpy as np
    from mpl_toolkits.axes_grid1 import host_subplot
    import mpl_toolkits.axisartist as AA
    import matplotlib.pyplot as plt
    
    # initialize the three axis:
    host = host_subplot(111, axes_class=AA.Axes)
    plt.subplots_adjust(left=0.25)
    
    par1 = host.twinx()
    par2 = host.twinx()
    
    # secify the offset for the left-most axis:
    offset = -60
    new_fixed_axis = par2.get_grid_helper().new_fixed_axis
    par2.axis["right"] = new_fixed_axis(loc="left", axes=par2, offset=(offset, 0))
    par2.axis["right"].toggle(all=True)
    
    # data ratio for the two left y-axis:
    y3_to_y1 = 1/7.5
    
    # y-axis limits:
    YLIM = [0.0, 150.0,
            0.0, 150.0]
    
    # set up dummy data
    x = np.linspace(0,70.0,70.0)
    y1 = np.asarray([xi**2.0*0.032653 for xi in x])
    y2 = np.asarray([xi**2.0*0.02857 for xi in x])
    
    # plot data on y1 and y2, respectively:
    host.plot(x,y1,'b')
    par1.plot(x,y2,'r')
    
    # specify the axis limits:
    host.set_xlim(0.0,70.0)
    host.set_ylim(YLIM[0],YLIM[1])
    par1.set_ylim(YLIM[2],YLIM[3])
    
    # when specifying the limits for the left-most y-axis
    # you utilize the conversion factor:
    par2.set_ylim(YLIM[2]*y3_to_y1,YLIM[3]*y3_to_y1)
    
    # set y-ticks, use np.arange for defined deltas
    # add a small increment to the last ylim value
    # to ensure that the last value will be a tick
    host.set_yticks(np.arange(YLIM[0],YLIM[1]+0.001,10.0))
    par1.set_yticks(np.arange(YLIM[2],YLIM[3]+0.001,10.0))
    par2.set_yticks(np.arange(YLIM[2]*y3_to_y1,YLIM[3]*y3_to_y1+0.001, 2.0))
    
    plt.show()
    

    你最终会得到这个情节:

    您也可以尝试修改上面的示例以提供第二个情节。一个想法是,将offset 减少到零。但是,对于axisartist,某些刻度功能are not supported。其中之一是指定刻度是在轴的内部还是外部。
    因此,对于第二个图,以下示例(基于matplotlib: overlay plots with different scales?)是合适的。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # initialize the three axis:
    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax2 = ax1.twinx()
    ax3 = ax1.twinx()
    
    # data ratio for the two left y-axis:
    y3_to_y1 = 1/7.5
    
    # y-axis limits:
    YLIM = [0.0, 150.0,
            0.0, 150.0]
    
    # set up dummy data
    x = np.linspace(0,70.0,70.0)
    y1 = np.asarray([xi**2.0*0.032653 for xi in x])
    y2 = np.asarray([xi**2.0*0.02857 for xi in x])
    
    # plot the data
    ax1.plot(x,y1,'b')
    ax2.plot(x,y2,'r')
    
    # define the axis limits
    ax1.set_xlim(0.0,70.0)
    ax1.set_ylim(YLIM[0],YLIM[1])
    ax2.set_ylim(YLIM[2],YLIM[3])
    
    # when specifying the limits for the left-most y-axis
    # you utilize the conversion factor:
    ax3.set_ylim(YLIM[2]*y3_to_y1,YLIM[3]*y3_to_y1)
    
    # move the 3rd y-axis to the left (0.0):
    ax3.spines['right'].set_position(('axes', 0.0))
    
    # set y-ticks, use np.arange for defined deltas
    # add a small increment to the last ylim value
    # to ensure that the last value will be a tick
    ax1.set_yticks(np.arange(YLIM[0],YLIM[1]+0.001,10.0))
    ax2.set_yticks(np.arange(YLIM[2],YLIM[3]+0.001,10.0))
    ax3.set_yticks(np.arange(YLIM[2]*y3_to_y1,YLIM[3]*y3_to_y1+0.001, 2.0))
    
    # for both letf-hand y-axis move the ticks to the outside:
    ax1.get_yaxis().set_tick_params(direction='out')
    ax3.get_yaxis().set_tick_params(direction='out')
    
    plt.show()
    

    结果如下图:

    同样,set_tick_params(direction='out') 不适用于第一个示例中的 axisartist
    有点违反直觉,y1y3 刻度都必须设置为'out'。对于y1,这是有道理的,对于y3,您必须记住它从右侧轴开始。因此,当轴向左移动时,这些刻度会出现在外部(使用默认的'in' 设置)。

    【讨论】:

      猜你喜欢
      • 2021-03-06
      • 1970-01-01
      • 2017-05-11
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      • 2016-01-10
      相关资源
      最近更新 更多