2015-05-10 33 views
3

我正在尝试使用twinx()来创建一个条形/线条组合图,并在条形顶部显示这条线。目前,这是它如何出现:顶部带有直线的多轴图形。 Matplotlib

Bar/Line Combo

我还需要线图上左边的垂直轴(AX)和右边(AX2)条被绘制,因为它是目前。如果我上绘制它的顶部出现在第二轴的线条,但显然它出现在了错误的轴(右)

这里是我的代码:

self.ax2=ax.twinx() 
    df[['Opportunities']].plot(kind='bar', stacked=False, title=get_title, color='grey', ax=self.ax2, grid=False) 
    ax.plot(ax.get_xticks(),df[['Percentage']].values, linestyle='-', marker='o', color='k', linewidth=1.0) 
    lines, labels = ax.get_legend_handles_labels() 
    lines2, labels2 = self.ax2.get_legend_handles_labels() 
    ax.legend(lines + lines2, labels + labels2, loc='lower right') 

还分别具有与标签的麻烦,但一一次一件事。

回答

3

默认情况下,艺术家出现在ax上,然后 艺术家在双轴ax2上。所以,因为在你的代码中,线条图是在ax上绘制的,而条形图在ax2上,条形图位于线条的顶部(并且模糊了)。

(我想我可以通过指定zorder改变这一点,但尝试没有 工作...)

所以要解决这个问题的方法之一是使用ax绘制条形图和ax2画该线。这将把线放在条的上面。此外,默认情况下,将左侧的ax(条形图)的ytick标签和右侧的ax2(线条)的ytick标签放在一起。但是,您可以使用

ax.yaxis.set_ticks_position("right") 
ax2.yaxis.set_ticks_position("left") 

交换左侧和右侧ytick标签的位置。


import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 
import pandas as pd 
np.random.seed(2015) 

N = 16 
df = pd.DataFrame({'Opportunities': np.random.randint(0, 30, size=N), 
        'Percentage': np.random.randint(0, 100, size=N)}, 
        index=pd.date_range('2015-3-15', periods=N, freq='B').date) 
fig, ax = plt.subplots() 

df[['Opportunities']].plot(kind='bar', stacked=False, title='get_title', 
          color='grey', ax=ax, grid=False) 
ax2 = ax.twinx() 
ax2.plot(ax.get_xticks(), df[['Percentage']].values, linestyle='-', marker='o', 
     color='k', linewidth=1.0, label='percentage') 

lines, labels = ax.get_legend_handles_labels() 
lines2, labels2 = ax2.get_legend_handles_labels() 
ax.legend(lines + lines2, labels + labels2, loc='best') 
ax.yaxis.set_ticks_position("right") 
ax2.yaxis.set_ticks_position("left") 

fig.autofmt_xdate() 
plt.show() 

产生

enter image description here


可替代地,轴的zorder可以被设置,以便绘制ax以上ax2Paul Ivanov shows how

ax.set_zorder(ax2.get_zorder()+1) # put ax in front of ax2 
ax.patch.set_visible(False) # hide the 'canvas' 
ax2.patch.set_visible(True) # show the 'canvas' 

因此,

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 
import pandas as pd 
np.random.seed(2015) 

N = 16 
df = pd.DataFrame({'Opportunities': np.random.randint(0, 30, size=N), 
       'Percentage': np.random.randint(0, 100, size=N)}, 
index=pd.date_range('2015-3-15', periods=N, freq='B').date) 
fig, ax = plt.subplots() 
ax2 = ax.twinx() 
df[['Opportunities']].plot(kind='bar', stacked=False, title='get_title', 
          color='grey', ax=ax2, grid=False) 

ax.plot(ax.get_xticks(), df[['Percentage']].values, linestyle='-', marker='o', 
     color='k', linewidth=1.0, label='percentage') 

lines, labels = ax.get_legend_handles_labels() 
lines2, labels2 = ax2.get_legend_handles_labels() 
ax.legend(lines + lines2, labels + labels2, loc='best') 

ax.set_zorder(ax2.get_zorder()+1) # put ax in front of ax2 
ax.patch.set_visible(False) # hide the 'canvas' 
ax2.patch.set_visible(True) # show the 'canvas' 

fig.autofmt_xdate() 
plt.show() 

产生同样的结果,而无需交换由axax2扮演的角色。

+0

这太好了。非常感谢! – user2229838