7

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?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Victor Mayrink
  • 1,064
  • 1
  • 13
  • 24
  • 1
    From [this](http://stackoverflow.com/questions/1726391/matplotlib-draw-grid-lines-behind-other-graph-elements) it seems you want to use `set_axisbelow(True)` with the documentation [here](http://matplotlib.org/api/axes_api.html). I just seem to be doing a terrible job of implementing it so maybe you get there before me. – roganjosh Feb 02 '17 at 16:22
  • 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 Feb 02 '17 at 16:35

2 Answers2

0
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

Dyno Fu
  • 8,753
  • 4
  • 39
  • 64
  • Thank you, this provides a better visualization. In fact, i'm using a similar approach, since i removed this line `ax1.grid(axis = 'y')` and added `ax2.grid(False)` at the end. However it is not exactly what i was looking for (i would like the horizontal grid lines just for the right axis, ax2). From [this](http://stackoverflow.com/a/29542999/4862402), i found out that it's possible to align the right and left tick marks, but it may lead to ugly labels on the right axis (floats not rounded), which happened in my real situation. – Victor Mayrink Feb 09 '17 at 00:15
0

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.

Community
  • 1
  • 1
Victor Mayrink
  • 1,064
  • 1
  • 13
  • 24