多个y轴转换比例 [英] Multiple y-axis conversion scales

查看:158
本文介绍了多个y轴转换比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建在y轴上包含两组平行转换比例的绘图;使用以下两种不同的样式:

I'm trying to create plots which incorporate parallel conversion scales for two sets of units on the y-axis; using the two different styles of:

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

在随附的示例图像中复制左侧y轴的样式.

to replicate the style of the left-hand y-axes in the attached example images.

我想找到生成上述两个示例图的最简单的通用方法,这也使我可以通过将两组单位之间的关系定义为函数来生成y轴转换比例(在本例中例如:mmHg = kPa * 7.5).

I'd like to find the simplest generic way of producing both of the above example plots, which also allows me to generate the y-axis conversion scales by defining the relationship between the two sets of units as a function (in this example: mmHg = kPa * 7.5).

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

If it's possible to add the third right-hand y axes (vapour concentration and water content) shown in these examples, which are unrelated to the left hand scales, this would be a bonus.

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

I've read related stackoverflow.com postings and examples on using multiple x and y axes using the twinx and twiny functions - e.g. here - as well as the Matplotlib cookbook, but I can't find an example which addresses this particular problem.

对于任何最少的工作示例或链接,我将不胜感激.

I'd be very grateful for any minimal working examples or links.

我在Spyder 2.2.1/Python 2.7.5中使用Matplotlib

I'm using Matplotlib in Spyder 2.2.1 / Python 2.7.5

非常感谢您的期待

戴夫

推荐答案

对于第一个图,我建议axisartist.左侧的两个y轴的自动缩放是通过适用于指定的y-极限的简单缩放因子实现的.第一个示例基于寄生虫轴:

For the first plot, I recommend axisartist. The automatic scaling of the two y-axis on the left-hand-side is achieved through a simple scaling factor that applies to the specified y-limits. This first example is based on the explanations on 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()

您最终将获得以下情节:

You will end up with this plot:

您也可以尝试修改上面的示例以提供第二张图.一种想法是将offset减小为零.但是,使用axisartist,某些刻度功能不支持.其中之一是指定刻度线是在轴的内部还是外部.
因此,对于第二个图,下面的示例(基于 matplotlib:覆盖具有不同比例的图?)是合适的.

You can try to modify the above example to give you the second plot, too. One idea is, to reduce offset to zero. However, with the axisartist, certain tick functions are not supported. One of them is specifying if the ticks go inside or outside the axis.
Therefore, for the second plot, the following example (based on matplotlib: overlay plots with different scales?) is appropriate.

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').

Again, the set_tick_params(direction='out') does not work with the axisartist from the first example.
Somewhat counter-intuitive, both the y1 and y3 ticks have to be set to 'out'. For y1, this makes sense, and for y3 you have to remember that it started as a right-hand-side axis. Therefore, those ticks would appear outside (with the default 'in' setting) when the axis is moved to the left.

这篇关于多个y轴转换比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆