83
x = ['01-02', '02-02', '03-02', '04-02', '05-02']
y = [2, 2, 3, 7, 2]

fig, ax = plt.subplots(1, 1)
ax.bar(range(len(y)), y, width=0.3,align='center',color='skyblue')
plt.xticks(range(len(y)), x, size='small')
plt.savefig('/home/user/graphimages/foo2.png')
plt.close()

I want to draw grid lines (of x & y) behind the bar graph.

Ani Menon
  • 27,209
  • 16
  • 105
  • 126
Adithya
  • 1,687
  • 3
  • 19
  • 34

5 Answers5

128

To add a grid you simply need to add

ax.grid()

If you want the grid to be behind the bars then add

ax.grid(zorder=0)
ax.bar(range(len(y)), y, width=0.3, align='center', color='skyblue', zorder=3)

The important part is that the zorder of the bars is greater than grid. Experimenting it seems zorder=3 is the lowest value that actually gives the desired effect. I have no idea why zorder=1 isn't sufficient.

EDIT: I have noticed this question has already been answered here using a different method although it suffers some link rot. Both methods yield the same result as far as I can see but andrew cooke's answer is more elegant.

Community
  • 1
  • 1
Greg
  • 11,654
  • 3
  • 44
  • 50
  • 8
    Though not part of this problem, it may be good to note that this solution will not work if there are error bars specified through the `yerr` or `xerr` (the filled bar will obscure them); using `ax.set_axisbelow()` does work for this case. – aseagram Sep 11 '17 at 17:39
  • 8
    As noted above this does not work with error bars. For completeness, the command `ax.set_axisbelow()` needs a true statement, as `ax.set_axisbelow(True)`. – Austin Downey Jan 16 '18 at 07:25
  • What if I'm using `ax.yaxis.grid(True)` to show only horizontal grid? adding `ax.grid(zorder=0)` will make vertical grid show up. – weefwefwqg3 May 24 '18 at 18:08
  • maybe the figure face is at zorder==0 and the axes face is at zorder==1? Didn't test the theory. – spacecowboy Feb 13 '20 at 02:39
  • 1
    this link worked for me https://stackoverflow.com/questions/1726391/matplotlib-draw-grid-lines-behind-other-graph-elements , the approach with zorder didn't – baxx Oct 17 '20 at 20:44
  • It appears that setting the zorder of the bars is what matters. I can set the zorder of the bars to 2, and the zorder of the grid to 100, but the bars still appear over the grid. I don't understand this behavior. I've actually tried several numbers from -1 to 100, and all I've tried work when bar zorder=2. – amquack May 18 '22 at 15:50
25

I am suggesting another solution since the most voted answer did not work for me. You can use the following code to set the gridlines behind the plot.

ax.set_axisbelow(True)
ax.grid(color='gray', linestyle='dashed')

I got this code from this answer.

Federico
  • 612
  • 7
  • 7
2
plt.grid(True, color = "grey", linewidth = "1.4", linestyle = "-.")

This worked for me, the grid lines will be in grey border color,if you want can change border design to linestyle = ".." Like this

plt.grid(True, color = "grey", linewidth = "1.4", linestyle = "..")

Summing up entire code block:

fig, ax = plt.subplots(1, 1)
ax.bar(range(len(y)), y, width=0.3,align='center',color='skyblue')
plt.xticks(range(len(y)), x, size='small')
plt.grid(True, color = "grey", linewidth = "1.4", linestyle = "-.")
plt.savefig('/home/user/graphimages/foo2.png')
plt.close()
Dulangi_Kanchana
  • 1,135
  • 10
  • 21
  • `ValueError: '..' is not a valid value for ls; supported values are '-', '--', '-.', ':', 'None', ' ', '', 'solid', 'dashed', 'dashdot', 'dotted'` – Michel de Ruiter Sep 22 '22 at 09:19
0

use .grid() it makes the order go to 0 (back)

ax.grid(zorder=0)
Pythoneer
  • 319
  • 1
  • 16
-3

ax.grid(zorder=0) Woud work. But First Place the Bar and then Place the Grid.Not the orther way.

ax = df.plot.bar(x='Index', y='Values', rot=90)
ax.grid(zorder=0)

I took some currency Correlation with Year and Sorted it as my Data Frame df, and below is the result of the code run. I took some currency Correlation with Year and Sorted it as my Data Frame df

user2458922
  • 1,691
  • 1
  • 17
  • 37