matplotlib 对齐twinx刻度线

jgwigjjp  于 2023-06-06  发布在  其他
关注(0)|答案(3)|浏览(215)

是否可以用两个独立的y轴绘制一张图,使刻度线对齐?
下面是解决方案的一半示例。我已经使用twinx将y轴加倍,但是刻度线没有对齐,网格线在图中形成了一个尴尬的模式。有没有办法使刻度线共享相同的位置,但对应不同的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)

本练习的主要要点是使两个轴的轴线重叠。

plicqrtu

plicqrtu1#

您需要手动设置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))

其中,我们使用轴边界之间的5个点的数组设置ytick位置。因为你有一个直方图,你可以在每种情况下将下限设置为零,你可能希望上限稍微大一点,所以我会有

ax1.set_yticks(np.linspace(0, ax1.get_ybound()[1]+1, 5))
ax2.set_yticks(np.linspace(0, ax2.get_ybound()[1]+1, 5))

给出一个图(为了清晰起见,颜色和透明度(alpha)发生了变化):

qxgroojn

qxgroojn2#

我知道这是旧的,但这可能会帮助一些人在未来。
我基于上面的解决方案创建了一个函数,以确保标签最终不会变成含有大量小数的东西:

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

其使用方式如下:

ax1.set_yticks(calculate_ticks(ax1, 10))
ax2.set_yticks(calculate_ticks(ax2, 10))

输出:

ijxebb2r

ijxebb2r3#

在答案后面加上:对于那些在他们的情节中既有负值又有正值的人,我发现的解决方案如下:

max1 = np.nanmax(ax1.get_ybound()) #in case you have nan values
max2 = np.nanmax(ax2.get_ybound())
nticks = 5 #or other odd number
ax1.set_yticks(np.linspace(-max1, max1, nticks))
ax2.set_yticks(np.linspace(-max2, max2, nticks))

这导致与零的对称轴距离,其中y轴上的零“线”对齐。
set_yticks的困难在于它在minmax之间进行计算,而不是min0max

相关问题