7
votes

This is a simple code that reproduces the kind of graph i`m trying to plot:

import matplotlib.pyplot as plt
import seaborn as sb
import numpy as np

x  = np.arange(1,11)
y1 = x[::-1]
y2 = 2 ** x

fig  = plt.figure(figsize = (8,6))
ax1 = fig.add_subplot(111)
plt.bar(x, y1, 1, color = 'blue')
ax1.grid(axis = 'y')
ax2 = ax1.twinx()
ax2.plot(x+0.5, y2, color = 'red')

Which produces:

Plot image

The grid lines from the last line plot are appearing above the bars. How can I put them behind the bars?

2
From this it seems you want to use set_axisbelow(True) with the documentation here. I just seem to be doing a terrible job of implementing it so maybe you get there before me. - roganjosh
I really don't get this. As far as I can tell I'm following all of the documentation and examples properly, I don't get any error, but it's just being completely ignored. I'm not sure I can solve this one sorry. - roganjosh

2 Answers

0
votes
import matplotlib.pyplot as plt
import numpy as np

x  = np.arange(1,11)
y1 = x[::-1]
y2 = 2 ** x

fig  = plt.figure(figsize = (8,6))
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()

# from back to front
ax1.grid(axis="both", color="black")
ax1.bar(x, y1, 1, alpha=.9, edgecolor="black", facecolor='blue', zorder=1)

ax2.grid(axis="y", color="green")
#ax2.grid(False)
ax2.plot(x+0.5, y2, color='red')

plt.show()

which produce the below graph which illustrate the zorder of the elements.

ax1.grid => ax1.bar => ax2.grid => ax2.line

zorder of elements in plot

the only workaround i can think of is to plot the grid in ax1 and turn off ax2 grid (if you really want to plot the horizontal grid line for ax2, then you might have to plot the line with ax1.

ax1.grid(True, axis="both", color="yellow")
ax1.bar(x, y1, 1, alpha=.9, edgecolor="black", facecolor='blue', zorder=1)

ax2.grid(False)
ax2.plot(x+0.5, y2, color='red')

some workaround

0
votes

After some searches and tries I'm sharing the solution I found, so others can use it as a reference in the future. This is not exactly what I was looking for, since I would like horizontal grid lines just for the right axis, however, it provided a much better visualization than the original plot.

From this, i found out how to align the left and right axis ticks (this problem also happens with line plots, but the effect is not as disturbing as in a bar plot).

import matplotlib.pyplot as plt
import seaborn as sb
import numpy as np

x  = np.arange(1,11)
y1 = x[::-1]
y2 = 2 ** x

fig  = plt.figure(figsize = (8,6))
ax1 = fig.add_subplot(111)
plt.bar(x, y1, 1, color = 'blue')
ax2 = ax1.twinx()
ax2.plot(x+0.5, y2, color = 'red')
ax2.set_yticks(np.linspace(ax2.get_yticks()[0],ax2.get_yticks()[-1],len(ax1.get_yticks())))

enter image description here

The grid lines are still above the bars. However, since the tick marks are aligned, we can now remove the grid of the second line plot by adding the explicit command: ax2.grid(False) at the end of the previous code.

enter image description here

IMPORTANT: Note that in this example the labels in both left and right axis are pretty nice. However, in a real situation this approach may to lead to ugly labels (floats or rough integers) on the right axis. Using this approach we are still not able to set the position of the right tick marks, so it is not an exact answer for the question.