matplotlib - 在subploted数字中没有xxel和xticks用于双轴

时间:2016-02-04 20:37:44

标签: python pandas matplotlib subplot

我想要做的是在子图中使用2x2图表。然后,对于每个图,我将使用两个y轴。因此,我为每个图使用了twinx()方法。您在我分享的图中看到的问题是它没有显示第一行的xlabel和xticks。对于第二行,一切都很好。我在图中用红色字体指定了问题("没有xlabel和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()

它生成以下数字:

output figure that I get from above code in python

编辑:

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

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

2 个答案:

答案 0 :(得分:4)

这就是我处理这类问题的方法。首先尝试通过将代码降至最低来隔离问题。例如,此代码显示相同的问题:

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

wrong plot

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

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

  2. 此代码中有两个不寻常的事情:

    • 下图是在上图之前创建的。
    • 创建双轴后,数据框在主轴上绘制。
  3. 不寻常的事情更有可能触发底层库中的隐藏错误,因此如果可能的话,最好避免它们。现在让我们看看如果我们按照通常的自上而下的顺序创建子图,会发生什么:

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

    correct plot

    它似乎有效,所以让我们尝试使用原始代码:

    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()
    

    problem solved

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

答案 1 :(得分:3)

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

test run

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

我建议在$ aws s3api get-object-acl \ --bucket my \ --key deploy/tool1/license.key 之前移动ax.set_xlabel,例如:

twinx

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

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()

以上产生了这个:

gridspec example