python - Matplotlib:将右轴的原点与特定的左轴值对齐

标签 python numpy matplotlib scipy

在 Matplotlib 中绘制多个 y 轴时,是否可以指定如何将右轴的原点(和/或一些 ytick 标签)与左轴的特定值对齐?

这是我的问题:我想绘制两组数据及其差异(基本上,我正在尝试重现 this kind of graph )。

我可以重现它,但我必须手动调整右轴的 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()

最佳答案

你可以编写一个小函数来计算ax2的对齐方式:

def align_yaxis(ax1, v1, ax2, v2):
    """adjust ax2 ylimit so that v2 in ax2 is aligned to v1 in ax1"""
    _, y1 = ax1.transData.transform((0, v1))
    _, y2 = ax2.transData.transform((0, v2))
    inv = ax2.transData.inverted()
    _, dy = inv.transform((0, 0)) - inv.transform((0, y1-y2))
    miny, maxy = ax2.get_ylim()
    ax2.set_ylim(miny+dy, maxy+dy)

通过使用align_yaxis(),您可以快速对齐轴:

#...... your code

# adjustment so the origin is aligned width left group2
ax2.set_ylim((0, 2.7))
align_yaxis(ax, np.mean(grp2), ax2, 0)
plt.show()

关于python - Matplotlib:将右轴的原点与特定的左轴值对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7630778/

相关文章:

python - 如何在 Seaborn 按 YearMonth 订购 X 轴

python - 为什么转置一个 numpy 数组将它旋转 90 度?

Python 递归,为什么我的函数不起作用?

python - 我如何复制此 try/except 代码中的所有其他输入?

python - 为什么这个 Numpy 函数链中需要命名表达式?

python - 在尝试组合两个数组时,我在 numpy 中遇到类型问题

python - 如何在装饰器中注册它装饰的所有功能?

Python OpenCv,只读取图像的一部分

python - 有没有办法通过分散的 X、Y 坐标绘制 'tight' 最佳拟合线?

python - Win 7 32 matplotlib 日期工具