Matplotlib:将右轴的原点与特定的左轴值对齐
在 Matplotlib 中绘制多个 y 轴时,有没有办法指定如何将右轴的原点(和/或一些 ytick 标签)与左轴的特定值对齐?
这是我的问题:我想绘制两组数据以及它们的差异(基本上,我试图重现 这种图)。
我可以重现它,但我必须手动调整右轴的 ylim ,以便原点与我想要的左轴值对齐。
我在下面给出了我使用的代码的简化版本的示例。如您所见,我必须手动调整右轴的比例以对齐右轴和正方形的原点。
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
grp1 = np.array([1.202, 1.477, 1.223, 1.284, 1.701, 1.724, 1.099,
1.242, 1.099, 1.217, 1.291, 1.305, 1.333, 1.246])
grp2 = np.array([1.802, 2.399, 2.559, 2.286, 2.460, 2.511, 2.296,
1.975])
fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([0.17, 0.13, 0.6, 0.7])
# remove top and right spines and turn ticks off if no spine
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('left')
# postition of tick out
ax.tick_params(axis='both', direction='out', width=3, length=7,
labelsize=24, pad=8)
ax.spines['left'].set_linewidth(3)
# plot groups vs random numbers to create dot plot
ax.plot(np.random.normal(1, 0.05, grp2.size), grp2, 'ok', markersize=10)
ax.plot(np.random.normal(2, 0.05, grp1.size), grp1, 'ok', markersize=10)
ax.errorbar(1, np.mean(grp2), fmt='_r', markersize=50,
markeredgewidth=3)
ax.errorbar(2, np.mean(grp1), fmt='_r', markersize=50,
markeredgewidth=3)
ax.set_xlim((0.5, 3.5))
ax.set_ylim((0, 2.7))
# create right axis
ax2 = fig.add_axes(ax.get_position(), sharex=ax, frameon=False)
ax2.spines['left'].set_color('none')
ax2.spines['top'].set_color('none')
ax2.spines['bottom'].set_color('none')
ax2.xaxis.set_ticks_position('none')
ax2.yaxis.set_ticks_position('right')
# postition of tick out
ax2.tick_params(axis='both', direction='out', width=3, length=7,
labelsize=24, pad=8)
ax2.spines['right'].set_linewidth(3)
ax2.set_xticks([1, 2, 3])
ax2.set_xticklabels(('gr2', 'gr1', 'D'))
ax2.hlines(0, 0.5, 3.5, linestyle='dotted')
#ax2.hlines((np.mean(adult)-np.mean(nrvm)), 0, 3.5, linestyle='dotted')
ax2.plot(3, (np.mean(grp1)-np.mean(grp2)), 'sk', markersize=12)
# manual adjustment so the origin is aligned width left group2
ax2.set_ylim((-2.3, 0.42))
ax2.set_xlim((0.5, 3.5))
plt.show()
When plotting several y axis in Matplotlib, is there a way to specify how to align the origin (and/or some ytick labels) of the right axis with a specific value of the left axis?
Here is my problem: I would like to plot two set of data as well as their difference (basically, I am trying to reproduce this kind of graph).
I can reproduce it, but I have to manually adjust the ylim of the right axis so that the origin is aligned with the value I want from the left axis.
I putted below an example of a simplified version of the code I use. As you can see, I have to manually adjust scale of the right axis to align the origin of the right axis as well as the square.
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
grp1 = np.array([1.202, 1.477, 1.223, 1.284, 1.701, 1.724, 1.099,
1.242, 1.099, 1.217, 1.291, 1.305, 1.333, 1.246])
grp2 = np.array([1.802, 2.399, 2.559, 2.286, 2.460, 2.511, 2.296,
1.975])
fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([0.17, 0.13, 0.6, 0.7])
# remove top and right spines and turn ticks off if no spine
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
ax.xaxis.set_ticks_position('none')
ax.yaxis.set_ticks_position('left')
# postition of tick out
ax.tick_params(axis='both', direction='out', width=3, length=7,
labelsize=24, pad=8)
ax.spines['left'].set_linewidth(3)
# plot groups vs random numbers to create dot plot
ax.plot(np.random.normal(1, 0.05, grp2.size), grp2, 'ok', markersize=10)
ax.plot(np.random.normal(2, 0.05, grp1.size), grp1, 'ok', markersize=10)
ax.errorbar(1, np.mean(grp2), fmt='_r', markersize=50,
markeredgewidth=3)
ax.errorbar(2, np.mean(grp1), fmt='_r', markersize=50,
markeredgewidth=3)
ax.set_xlim((0.5, 3.5))
ax.set_ylim((0, 2.7))
# create right axis
ax2 = fig.add_axes(ax.get_position(), sharex=ax, frameon=False)
ax2.spines['left'].set_color('none')
ax2.spines['top'].set_color('none')
ax2.spines['bottom'].set_color('none')
ax2.xaxis.set_ticks_position('none')
ax2.yaxis.set_ticks_position('right')
# postition of tick out
ax2.tick_params(axis='both', direction='out', width=3, length=7,
labelsize=24, pad=8)
ax2.spines['right'].set_linewidth(3)
ax2.set_xticks([1, 2, 3])
ax2.set_xticklabels(('gr2', 'gr1', 'D'))
ax2.hlines(0, 0.5, 3.5, linestyle='dotted')
#ax2.hlines((np.mean(adult)-np.mean(nrvm)), 0, 3.5, linestyle='dotted')
ax2.plot(3, (np.mean(grp1)-np.mean(grp2)), 'sk', markersize=12)
# manual adjustment so the origin is aligned width left group2
ax2.set_ylim((-2.3, 0.42))
ax2.set_xlim((0.5, 3.5))
plt.show()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以编写一个小函数来计算ax2的对齐方式:
通过使用align_yaxis(),您可以快速对齐轴:
You can make a little function that calculates the alignment of
ax2
:by using
align_yaxis()
, you can align the axes quickly:上面的答案是好的,但有时会删掉数据,这里的第二个答案中有更彻底的回答,
Matplotlib 轴具有两个比例共享原点
或快速破解
The above answer is Okay, but sometimes cuts out data, it is more thoroughly answered in the second answer here,
Matplotlib axis with two scales shared origin
or with a quick hack