It appears, by default, that the artists are drawn on ax
first, then the
artists on the twin axes ax2
on top. So since in your code the line plot was drawn on ax
and the bar plot on ax2
, the bar plot sits on top of (and obscures) the line.
(I thought I could change this by specifying zorder
, but that attempt did not
work... )
So one way to solve the problem is to use ax
to draw the bar plot and ax2
to draw the line. That will place the line on top of the bars. It will also, by default, place the ytick labels for ax
(the bar plot) on the left, and the ytick labels for ax2
(the line) on the right. However, you can use
ax.yaxis.set_ticks_position("right")
ax2.yaxis.set_ticks_position("left")
to swap the location of the left and right ytick labels.
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()
yields
![enter image description here](https://i.stack.imgur.com/3MHBx.png)
Alternatively, the zorder
of the axes can be set so as to draw ax
above ax2
. Paul 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'
Thus,
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()
yields the same result without having to swap the roles played by ax
and ax2
.