Python-为double y子图创建两个共享的y轴

时间:2019-12-04 19:52:19

标签: python matplotlib

当前,我的子图中的第一个y轴(概率)对齐。但是,我正在尝试使子图的辅助y轴(样本大小)对齐。我试图简单地设置y轴限制,但是这种解决方案不是很通用。

这是我的代码:

attacks = 5
crit_rate = .5

idealdata = fullMatrix(attacks, crit_rate)
crit_rate = ("crit_%.0f" % (crit_rate*100))
actualdata = trueDataM(attacks, crit_rate)
[enter image description here][1]

fig, axs = plt.subplots(attacks+1, sharex=True, sharey=True)
axs2 = [ax.twinx() for ax in axs]

fig.text(0.5, 0.04, 'State', ha='center')
fig.text(0.04, 0.5, 'Probability', va='center', rotation='vertical')
fig.text(.95, .5, 'Sample Size', va='center', rotation='vertical')
fig.text(.45, .9, 'Ideal vs. Actual Critical Strike Rate', va='center')
cmap = plt.get_cmap('rainbow')
samplesize = datasample(attacks, 'crit_50')
fig.set_size_inches(18.5, 10.5)
for i in range(attacks+1):
    axs[i].plot(idealdata[i], color=cmap(i/attacks), marker='o', lw=3)
    axs[i].plot(actualdata[i], 'gray', marker='o', lw=3, ls='--')
    axs2[i].bar(range(len(samplesize[i])), samplesize[i], width=.1, color=cmap(i/attacks), alpha = .6)

plt.show()

https://i.stack.imgur.com/HKJlE.png

1 个答案:

答案 0 :(得分:0)

没有数据可以证实我的假设,很难说这是否正确。 您没有尝试缩放左y轴,因此数据必须全部具有相同的范围。为了确保所有正确的y轴具有相同的比例/限制,您需要确定在这些轴上绘制的(所有)数据的范围(最大和最小),然后将其应用于所有这些轴。

目前尚不清楚samplesize是Numpy ndarray还是列表列表,我还假设它是带有range(attacks+1) 行。由于您是在第二个y轴上制作条形图,因此只需要在所有数据中找到最大的 height

# for a list of lists
biggest = max(max(row) for row in samplesize)
# or
biggest = max(map(max,samplesize))

# for an ndarray
biggest = samplesize.max()

然后在显示

之前,将比例尺应用到所有正确的y轴。
for ax in axs2:
    ax.set_ylim(top=biggest)

如果在绘图循环之前确定biggest,则可以在该循环中添加一行:

for i in range(attacks+1):
    ...
    axs2[i].set_ylim(top=biggest)

您会发现许多与matplotlib subplots same y scalematplotlib subplots y axis limits或类似词语相关的SO Q&A'a搜索结果。


这是一个玩具示例:

from matplotlib import pyplot as plt
import numpy as np
lines = np.random.randint(0,200,(5,10))
bars = [np.random.randint(0,np.random.randint(0,10000),10) for _ in (0,0,0,0,0,)]

fig, axs = plt.subplots(lines.shape[0], sharex=True, sharey=True)
axs2 = [ax.twinx() for ax in axs]
#xs = np.arange(lines.shape[1])
xs = np.arange(1,11)
biggest = max(map(max,bars))
for ax,ax2,line,row in zip(axs,axs2,lines,bars):
    bars = ax2.bar(xs,row)
    ax.plot(line)
    ax2.set_ylim(top=biggest)

plt.show()
plt.close()