matplotlib - 子图中的 twinx 轴没有 xlabel 和 xticks

matplotlib - No xlabel and xticks for twinx axes in subploted figures

我想做的是在子图中绘制 2x2 图。然后,对于每个图形,我将使用两个 y 轴。因此,我对每个图表都使用了 twinx() 方法。正如您在我分享的图中看到的问题,它没有在第一行显示 xlabel 和 xticks。对于第二行,一切都很好。我在图中用红色字体指出了问题("No xlabel and xticks!!!")。

每个图表都有自己的 x 轴和 y 轴,并且没有共享。

我对这段代码做了很多调整,缩小了问题制造者的范围。这是因为我在上排使用了 twinx() 。如果我尝试删除次要 y 轴,一切都会恢复正常,并且正确显示上面几行的 xlabel 和 ylabel。

不知道是什么问题!

这是我正在处理的代码。

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import StringIO

s = StringIO(u"""     amount     price
A     40929   4066443
B     93904   9611272
C    188349  19360005
D    248438  24335536
E    205622  18888604
F    140173  12580900
G     76243   6751731
H     36859   3418329
I     29304   2758928
J     39768   3201269
K     30350   2867059""")

df = pd.read_csv(s, index_col=0, delimiter=' ', skipinitialspace=True)

fig = plt.figure() 

ax_2 = fig.add_subplot(222, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.plot([1, 3, 5, 7, 9])
ax_22.plot([1.0/x for x in [1, 3, 5, 7, 9]])
ax_2.set_xlabel("AX2 X Lablel")
ax_2.set_ylabel("AX2 Y Lablel")
ax_22.set_ylabel("AX2_Twin Y Lablel")


ax_2 = fig.add_subplot(223, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.plot([100, 300, 500, 700, 900])
ax_22.plot([x*x for x in [100, 300, 500, 700, 900]])
ax_2.set_xlabel("AX3 X Lablel")
ax_2.set_ylabel("AX3 Y Lablel")
ax_22.set_ylabel("AX3_Twin Y Lablel")




ax_2 = fig.add_subplot(224, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.set_xlabel("AX4 X Lablel")
ax_2.set_ylabel("AX4 Y Lablel")
ax_22.set_ylabel("AX4_Twin Y Lablel")






ax = fig.add_subplot(221, sharex=None, sharey=None) 
ax2 = ax.twinx() 
width = 0.4
df.amount.plot(kind='bar', color='red', ax=ax, width=width, position=1, sharex=False, sharey=False)
df.price.plot(kind='bar', color='blue', ax=ax2, width=width, position=0, sharex=False, sharey=False)

ax.set_xlabel("Alphabets")
ax.set_ylabel('Amount')
ax2.set_ylabel('Price')



plt.subplots_adjust(wspace=0.8, hspace=0.8)
plt.savefig("t1.png", dpi=300)
plt.show()

生成如下图:

已编辑:

感谢您的回答。但是,在绘图中使用 Pandas 时,我的问题仍然存在。我开了一个新问题。请看一下:

matplotlib - pandas - no xlabel and xticks for twinx axes in subploted figures

您提供的代码似乎产生了预期的结果。

这让我认为您的控制台或 matplotlib 版本存在问题 - 或许您可以提供更多有关 运行 代码的信息。

我建议将 ax.set_xlabel 移到 twinx 之前,例如:

ax_2 = fig.add_subplot(222, sharex=None, sharey=None)
ax_22 = ax_2.twinx()
ax_2.set_xlabel("AX2 X Lablel")
ax_2.plot([1, 3, 5, 7, 9])

# Becomes...

ax_2 = fig.add_subplot(222, sharex=None, sharey=None)
ax_2.set_xlabel("AX2 X Lablel")
ax_2.plot([1, 3, 5, 7, 9])
ax_22 = ax_2.twinx()

EDIT 我建议改用 gridspec。请参阅以下工作示例:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gspec
import numpy as np

fig = plt.figure()
gs = gspec.GridSpec(2, 2)
gs.update(hspace=0.7, wspace=0.7)
ax1 = plt.subplot(gs[0, 0])
ax2 = plt.subplot(gs[1, 0])
ax3 = plt.subplot(gs[0, 1])
ax4 = plt.subplot(gs[1, 1])


x1 = np.linspace(1,10,10)

ax1.plot(x1, x1**2)
ax1.set_xlabel('ax1 x')
ax1_2 = ax1.twinx()
ax1_2.plot(x1, x1**3)
ax1_2.set_ylabel('ax1_2 y')
ax1.set_ylabel('ax1 y')

# To save time I left the other cells blank, but it should work fine.

plt.show()

上面的结果是这样的:

这就是我处理此类问题的方式。首先尝试通过将代码减少到最低限度来隔离问题。例如,这段代码显示了同样的问题:

fig = plt.figure()
fig.add_subplot(212)
ax = fig.add_subplot(211)
ax2 = ax.twinx()
pd.Series(range(10)).plot(ax=ax)

现在我们可以看到两件事:

  1. 如果我只在 5 行代码中犯了错误,应该很容易找到(至少比原始代码更容易)。由于我找不到任何错误,我猜这是 pandas 或 matplotlib 中的错误。从评论来看,这可能是 matplotlib 1.5.1 中引入的回归。

  2. 这段代码有两个不寻常的地方:

    • 下图先于上图创建。
    • 数据框在创建双轴后绘制在主轴上。

不寻常的事情更有可能触发底层库中隐藏的错误,所以尽可能避免它们。现在让我们看看如果我们以通常的自上而下的顺序创建子图会发生什么:

fig = plt.figure() 
ax = fig.add_subplot(211)
ax2 = ax.twinx()
pd.Series(range(10)).plot(ax=ax)
fig.add_subplot(212)

似乎可行,所以让我们用原始代码尝试一下:

fig = plt.figure() 

ax = fig.add_subplot(221, sharex=None, sharey=None) 
ax2 = ax.twinx() 
width = 0.4
df.amount.plot(kind='bar', color='red', ax=ax, width=width, position=1, sharex=False, sharey=False)
df.price.plot(kind='bar', color='blue', ax=ax2, width=width, position=0, sharex=False, sharey=False)

ax_2 = fig.add_subplot(222, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.plot([1, 3, 5, 7, 9])
ax_22.plot([1.0/x for x in [1, 3, 5, 7, 9]])
ax_2.set_xlabel("AX2 X Lablel")
ax_2.set_ylabel("AX2 Y Lablel")
ax_22.set_ylabel("AX2_Twin Y Lablel")

ax_2 = fig.add_subplot(223, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.plot([100, 300, 500, 700, 900])
ax_22.plot([x*x for x in [100, 300, 500, 700, 900]])
ax_2.set_xlabel("AX3 X Lablel")
ax_2.set_ylabel("AX3 Y Lablel")
ax_22.set_ylabel("AX3_Twin Y Lablel")

ax_2 = fig.add_subplot(224, sharex=None, sharey=None) 
ax_22 = ax_2.twinx()
ax_2.set_xlabel("AX4 X Lablel")
ax_2.set_ylabel("AX4 Y Lablel")
ax_22.set_ylabel("AX4_Twin Y Lablel")

ax.set_xlabel("Alphabets")
ax.set_ylabel('Amount')
ax2.set_ylabel('Price')

plt.subplots_adjust(wspace=0.8, hspace=0.8)
plt.savefig("t1.png", dpi=300)
plt.show()

所以问题通过解决方法解决了(至少对我而言)。实际修复会更好,但完美是好的敌人,现在子图以更合乎逻辑的顺序创建,这提高了可读性。