在Matplotlib图中间隔多个(> 3)Y轴的算法

时间:2018-04-07 17:44:05

标签: python matplotlib

Web上有很多资源可以在Matplotlib中构建具有多个y轴的图表。

请参阅:
https://matplotlib.org/gallery/ticks_and_spines/multiple_yaxis_with_spines.html
matplotlib: overlay plots with different scales?

构建一个最多包含三个y轴的图表并不困难。但是,具有四个或五个y_axes的图表变得更难以使y_axes的放置间距看起来很好。

是否有可重复的方法来使额外的Y轴间距不重叠?

特别是在下面的代码中调用
fig.subplots_adjust(right=...)
ax.spines["right"].set_position(("axes",...))应该被细化以考虑前面y轴显示的宽度(特别是y轴显示中显示的数字的宽度)。

我在Windows 10上使用Python 3.6.4,Matplotlib 2.1.2和Qt5Agg作为Matplotlib后端。

import matplotlib.pyplot as plt
plt.ioff()

def adjust_extra_yaxes(ax, pct_shift):
    ax.spines["right"].set_position(("axes", 1+pct_shift))
    ax.set_frame_on(True)
    ax.patch.set_visible(False)
    for sp in ax.spines.values():
        sp.set_visible(False)
    ax.spines["right"].set_visible(True)

fig, ax_0 = plt.subplots()

ax_1 = ax_0.twinx()
ax_2 = ax_0.twinx()
ax_3 = ax_0.twinx()
ax_4 = ax_0.twinx()
num_extra_yaxes = 3

pct_width_per_yaxis = 0.1
fig_right_margin = 1.0 - pct_width_per_yaxis*num_extra_yaxes
fig.subplots_adjust(right=fig_right_margin)

i = 1
for ax in [ax_2, ax_3, ax_4]:
    adjust_extra_yaxes(ax, pct_width_per_yaxis*i)
    i+=1

l0, = ax_0.plot([0, 1, 2], [0, 1, 2], linestyle='-', label="Label Name 0", color='Blue')
l1, = ax_1.plot([0, 1, 2], [0, 3000000, 2000000], linestyle='-', label="Label Name 1", color='Green')
l2, = ax_2.plot([0, 1, 2], [5, 3, 1.5], linestyle='-', label="Label Name 2", color='Red')
l3, = ax_3.plot([0, 1, 2], [800000, 200000, 150000], linestyle='-', label="Label Name 3", color='cyan')
l4, = ax_4.plot([0, 1, 2], [50, 55, 200], linestyle='-', label="Label Name 4", color='black')

ax_0.set_xlim(0, 2)
ax_0.set_ylim(0, 2)
ax_1.set_ylim(0, 3000000)
ax_2.set_ylim(1, 5)
ax_3.set_ylim(100000, 800000)
ax_4.set_ylim(0, 200)

ax_0.set_xlabel("X-Axis Label")
ax_0.set_ylabel("Label Name 0")
ax_1.set_ylabel("Label Name 1")
ax_2.set_ylabel("Label Name 2")
ax_3.set_ylabel("Label Name 3")
ax_4.set_ylabel("Label Name 4")

ax_0.yaxis.label.set_color(l0.get_color())
ax_1.yaxis.label.set_color(l1.get_color())
ax_2.yaxis.label.set_color(l2.get_color())
ax_3.yaxis.label.set_color(l3.get_color())
ax_4.yaxis.label.set_color(l4.get_color())

tkw = dict(size=4, width=1.5)
ax_0.tick_params(axis='y', colors=l0.get_color(), **tkw)
ax_1.tick_params(axis='y', colors=l1.get_color(), **tkw)
ax_2.tick_params(axis='y', colors=l2.get_color(), **tkw)
ax_3.tick_params(axis='y', colors=l3.get_color(), **tkw)
ax_4.tick_params(axis='y', colors=l4.get_color(), **tkw)
ax_0.tick_params(axis='x', **tkw)

lines = [l0, l1, l2, l3, l4]
ax_0.legend(lines, [l.get_label() for l in lines])

plt.show()

enter image description here

0 个答案:

没有答案