Matplotlib: Draw Grid Lines Behind Other Graph Elements

Matplotlib: draw grid lines behind other graph elements

According to this - http://matplotlib.1069221.n5.nabble.com/axis-elements-and-zorder-td5346.html - you can use Axis.set_axisbelow(True)

(I am currently installing matplotlib for the first time, so have no idea if that's correct - I just found it by googling "matplotlib z order grid" - "z order" is typically used to describe this kind of thing (z being the axis "out of the page"))

Matplotlib: draw grid behind everything else

You need to utilize the zorder argument. Make this modification and it will work.

ax.add_artist( Ellipse( xy = (0,0), width = 1, height = 2, angle = 0, edgecolor='b', lw=4, facecolor='green' ,zorder=2) )

Anytime you are plotting multiple items, you can control the order they appear with zorder. Find more information on zoder here.

This simple fix makes the figure go from this:

Grid in front

to this:

Grid behind

How to draw grid lines behind matplotlib bar graph

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.

Matplotlib: keep grid lines behind the graph but the y and x axis above

I have tried matplotlib 1.2.1, 1.3.1rc2 and master (commit 06d014469fc5c79504a1b40e7d45bc33acc00773)

To get the axis spines on top of the the bars you can do the following:

for k, spine in ax.spines.items():  #ax.spines is a dictionary
spine.set_zorder(10)

EDIT

It seems that I can't make the tick lines to go on top of the bars. I've tried

1. ax.tick_params(direction='in', length=10, color='k', zorder=10)
#This increases the size of the lines to 10 points,
#but the lines stays hidden behind the bars
2. for l in ax.yaxis.get_ticklines():
l.set_zorder(10)

and some other way with no results. It seems that when drawing the bars they are put on top and the zorder is ignored

A workaround could be to draw the tick lines outwards

ax.tick_params(direction='out', length=4, color='k', zorder=10)

or both in and outwards, using direction='inout'

EDIT2

I've done some test after @tcaswell comments.

If zorder in the ax.bar function is set to be <=2, the axis, ticklines and grid lines are drawn above the bars. If the valus is >2.01 (the default value for axis) the bars are drawn on top of the axis, ticklines and grid. Then it possible to set larger values to the spines (as above) but any attempt to change the zorder of the ticklines is simply ignored (although the values are updated on the corresponding artists).

I've tried the to use zorder=1 for the bar and zorder=0 for the grid and the grid is drawn on top of the bars. So zorder is ignored.

recap

It seems to me that ticklines and grid zorder are just ignored and kept to the default values. For me this is a bug somehow related with bar or some patches.

BTW, I do remember changing successfully the zorder in ticklines when using imshow

Matplotlib: Grid lines behind bars on twinned axes?

Everything drawn on one axis (including the grid) is always or completely before or completely behind everything drawn on the other axis. The only solution in your case is to only draw a grid for axes1, removing the call to the grid for the other axis.

Set specified grid lines in matplotlib without changing ticklabels

I wouldn't explicitly set the ticks and labels but modify the output matplotlib generates:

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.ticker import MultipleLocator

mdict={"Column1":["A_"+str(i) for i in range(1,21)],"Value":[i for i in range(1,21)]}
df=pd.DataFrame(mdict)

fig, ax = plt.subplots(figsize=(12,8))
ax.barh(df.Column1, df.Value, color="darkgray", edgecolor="black", linewidth=0.5)
ax.set_xlabel("Numbers", fontsize=15)

#set every fourth tick
n=4
ax.xaxis.set_major_locator(MultipleLocator(n))
ax.grid(alpha=0.2,color="black")
#remove unwanted gridlines on the y-axis
ygrd_lines = ax.get_ygridlines()
[grd_line.set_visible(False) for i, grd_line in enumerate(ygrd_lines) if i%n]

plt.show()

Sample output:
Sample Image

Methods used:

MultipleLocator() setting ticks at defined intervals

.get_ygridlines returning gridlines as a list of Line2D objects for further modification

send pyplot grid color to background and percentage values starting from 20 instead of 0

Use ax.set_axisbelow(True) to have the grid lines behind the elements on the plot. plt.ylim() (or ax.set_ylim()) can change the data limits. The PercentFormatter formats the tick labels as percentages.

import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter
import numpy as np

barWidth = 0.8 / 3
r1 = np.arange(4)
r2 = r1 + barWidth
r3 = r2 + barWidth
dao = np.random.uniform(20, 100, 4)
pie_gdp = np.random.uniform(20, 100, 4)
pie_sdp = np.random.uniform(20, 100, 4)

plt.bar(r1, dao, color='blue', width=barWidth, edgecolor='white', label='DAO')
plt.bar(r2, pie_gdp, color='orange', width=barWidth, edgecolor='white', label='PIE- GDP')
plt.bar(r3, pie_sdp, color='gray', width=barWidth, edgecolor='white', label='PIE-SDP')
plt.grid(color='#95a5a6', linestyle='--', linewidth=2, axis='y', alpha=1)
ax = plt.gca()
ax.set_axisbelow(True) # grid lines behind other elements

plt.xticks(r1 + barwidth, ['DNN-Sigmoid', 'CNN-Sigmoid', 'DNN-ReLU', 'CNN-ReLU'])
plt.ylim(20, None) # start from 20
ax.yaxis.set_major_formatter(PercentFormatter(100))
for spine in ['top', 'right']:
ax.spines[spine].set_visible(False) # hide part of the box
plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), ncol=3)

plt.tight_layout() # fit subplot and texts nicely into the figure
plt.show()

bar plots

draw order of grid lines and data in pyplot

Use the zorder kwarg to your plot and axhline calls. The grid is plotted at zorder=2.5, so place the axhline and plot above this:

plot_ax1.axhline(y=0, ls='-', color='0.5', zorder=3)
plot_ax1.plot(self.diff_3[:,0],self.diff_3[:,1], zorder=4)
plot_ax1.grid(b=True, which='major', axis='both', c='0.75', ls='-', linewidth=1)

More info: here, and here.



Related Topics



Leave a reply



Submit