matplotlib对齐twinx刻度线

jun*_*er- 16 python matplotlib

是否可以制作具有两个独立y轴的绘图,使刻度线对齐?

以下是一半解决方案的示例.我使用了y轴加倍twinx,但是刻度标记没有对齐,并且网格线在图上形成了一个尴尬的图案.有没有办法让刻度线共享相同的位置,但对应不同的y值?在下面的例子中,我希望左边的5的刻度线与右边的6的刻度线标记处于同一垂直位置.

import numpy as np

a = np.random.normal(10, 3, size=20)
b = np.random.normal(20, 5, size=40)

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.hist(a)
ax2.hist(b)
Run Code Online (Sandbox Code Playgroud)

直方图

本练习的首要目的是使两条轴的网格线重叠.

Gre*_*reg 19

您需要手动设置yticks现状,这些是自动计算的,从而导致变化.添加这样的东西:

ax1.set_yticks(np.linspace(ax1.get_ybound()[0], ax1.get_ybound()[1], 5))
ax2.set_yticks(np.linspace(ax2.get_ybound()[0], ax2.get_ybound()[1], 5))
Run Code Online (Sandbox Code Playgroud)

我们ytick使用轴的边界之间的5个点的数组来设置位置.由于你有直方图,你可以在每种情况下将较低的值设置为零,并且你可能希望上限稍大一些,所以我宁愿

ax1.set_yticks(np.linspace(0, ax1.get_ybound()[1]+1, 5))
ax2.set_yticks(np.linspace(0, ax2.get_ybound()[1]+1, 5))
Run Code Online (Sandbox Code Playgroud)

给出一个情节(为了清晰起见,改变颜色和透明度(alpha)):

在此输入图像描述

  • 由于边界始终由两个数字定义(除非未定义),因此以下代码还在已定义的轴边界之间创建 5 个点:`ax1.set_yticks(np.linspace(*ax1.get_ybound(),5)`。 (2认同)
  • @ HAL9001,您的建议中缺少一个右括号。它应该是:`ax1.set_yticks(np.linspace(*ax1.get_ybound(),5))`。 (2认同)

Flo*_*aan 5

我知道这很旧,但这可能会在将来对某些人有所帮助。

我根据上面的解决方案制作了一个函数,以确保标签最终不会成为带有很多小数的东西:

def calculate_ticks(ax, ticks, round_to=0.1, center=False):
    upperbound = np.ceil(ax.get_ybound()[1]/round_to)
    lowerbound = np.floor(ax.get_ybound()[0]/round_to)
    dy = upperbound - lowerbound
    fit = np.floor(dy/(ticks - 1)) + 1
    dy_new = (ticks - 1)*fit
    if center:
        offset = np.floor((dy_new - dy)/2)
        lowerbound = lowerbound - offset
    values = np.linspace(lowerbound, lowerbound + dy_new, ticks)
    return values*round_to
Run Code Online (Sandbox Code Playgroud)

其使用方式如下:

ax1.set_yticks(calculate_ticks(ax1, 10))
ax2.set_yticks(calculate_ticks(ax2, 10))
Run Code Online (Sandbox Code Playgroud)

输出:

在此处输入图片说明