多个y轴转换比例尺

6

带有“寄生”平行y轴的转换比例尺

共享y轴的转换比例尺

您好

我正在尝试创建包含两组单位的平行转换比例尺的图表,其中使用了两种不同的样式:

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

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

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

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

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

非常感谢您提供任何最小的工作示例或链接。

我正在使用Spyder 2.2.1 / Python 2.7.5中的Matplotlib。

预先感谢您

Dave

1个回答

8
对于第一个图,我建议使用 axisartist。通过应用于指定的 y 限制的简单缩放因子,实现了左侧两个 y 轴的自动缩放。这个第一个例子基于 寄生轴 的解释。
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()

您最终将得到这个图表:

first figure

你可以尝试修改上面的示例,以获得第二个图。一个想法是将offset减少到零。然而,使用axisartist时,某些刻度函数不受支持。其中之一是指定刻度线是在轴内还是轴外。
因此,对于第二个图,以下示例(基于 matplotlib:如何使用不同比例叠加图形?)是适当的。
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()

这导致产生这个图:

second figure

同样,set_tick_params(direction='out')在第一个示例中与axisartist不兼容。
有点违反直觉,y1y3的刻度线都必须设置为'out'。对于y1,这是有道理的,对于y3,您必须记住它起初是右侧轴。因此,在将轴移动到左侧时,这些刻度线会显示在外面(使用默认的'in'设置)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接