2016-02-04 105 views
4

我想要做的就是在一个插曲一个2x2图。然后,对于每个图形,我将使用两个y轴。因此,我为每个图使用了twinx()方法。我在图中看到的问题是,它没有显示第一行的xlabel和xticks。对于第二排,一切都很好。我已经在图中以红色字体指定了问题(“无xlabel和xticks !!!”)。matplotlib - 在subploted数字没有xlabel和twinx轴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

编辑:

感谢您的答案。但是,在绘制图表中使用“熊猫”时,我的问题仍然存在。我开了一个新问题。请看一看吧:

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

回答

3

您所提供的代码似乎产生期望的结果。

test run

这让我觉得,可能是您的控制台或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() 

编辑我会用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() 

上述方法产生这样的:

gridspec example

+1

谢谢Oniow。即使你提到的变化,图中没有变化! 我使用Ubuntu 14.04 64位在我的Mac上运行我的脚本。 Python:2.7.11(与GCC 4.4.7编译) Matplotlib:1.5.1 而且,我使用Anaconda 2.4.0作为我的Python包的包管理器。 – Millad

+0

您是否以任何方式更改我的代码?我问这是因为我需要生成图表,我想知道我是否犯了一个错误。我提到的上述系统配置是否与您的不同?谢谢你的时间。 – Millad

+0

Hello Millad - 我能够使用Python 3.4和Matplotlib 1.5.0制作剧情,并使用Anaconda。我没有改变你的代码来获得所需的结果。它可能是一个python 3与2的东西 - 但我怀疑它。你使用什么接口?你是直接保存数字还是将它输出到Ipython控制台? – Oniow

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的代码它应该行犯了一个错误很容易找到(至少比原始代码更容易)。由于我找不到任何错误,我想这是熊猫或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) 

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

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

+0

哦,我的上帝。我很困惑!它以前没有工作,但它现在正常工作!我认为这可能是由于我在我的Python软件包(matplotlib和pandas)上进行了升级。我还应该提一下,我之所以推迟生成我的上层情节的代码,是因为它没有起作用,我想也许这是一种错误,这种向下移动的变化会对此有所帮助。不过,我真的很感谢你的时间和精力(我也接受了你的回答)。 – Millad

+0

如果您定义了“ax3 = fig.add_subplot(212)”并调用“pd.Series(range(10))。plot(ax = ax3)”,则ax的x轴仍然消失(?)。 – Pat

+0

@Pat我不知道你想在哪里添加代码,但我鼓励你自己尝试。 – Goyo