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:
to this:
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:
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()
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
Pyeval_Initthreads in Python 3: How/When to Call It? (The Saga Continues Ad Nauseam)
Timedelta to String Type in Pandas Dataframe
How to Include a Python Package with Hadoop Streaming Job
Add Column with Constant Value to Pandas Dataframe
Getting Standard Errors on Fitted Parameters Using the Optimize.Leastsq Method in Python
How to Reduce the Image File Size Using Pil
Shift Elements in a Numpy Array
What Is the Correct Syntax for 'Else If'
Changing User Agent in Python 3 for Urrlib.Request.Urlopen
How to Enable MySQL Client Auto Re-Connect with MySQLdb
When Should Iteritems() Be Used Instead of Items()
Difference Between Data and JSON Parameters in Python Requests Package
Sqlalchemy Unique Across Multiple Columns
How to Find the First Key in a Dictionary
Replace String Within File Contents
Why Is the Time Complexity of Python's List.Append() Method O(1)