Setting grid line spacing for plot
Asked Answered
F

3

11

I have an undirected graph created by Networkx that I am displaying using pyplot and I want to allow the user to specify the spacing between grid lines. I don't want to manually enter the ticks as this requires knowing the final size of the plot (if there's a way to do this I would like to know) which could vary based on the graph being displayed.

Is there any method that allows you to set the spacing amount? I've looked for a while and can't find anything, thanks.

The code below relates to the creating of the plot not the graph.

#Spacing between each line
intervals = float(sys.argv[1])

nx.draw(displayGraph, pos, node_size = 10)
plt.axis('on')
plt.grid('on')
plt.savefig("test1.png")

I need to find a way to get the grid to have spacing intervals that are defined by the user. I've found ways to do it but it relies on also saying how many grid lines you want and that causes the lines to not be evenly spaced over the plot

Finnish answered 27/5, 2015 at 12:39 Comment(1)
Can you share some of your code?Lapotin
S
24

Not sure if this contravenes your desire not to manually play with ticks, but you can use matplotlib.ticker to set the ticks to your given interval:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

fig,ax=plt.subplots()

#Spacing between each line
intervals = float(sys.argv[1])

loc = plticker.MultipleLocator(base=intervals)
ax.xaxis.set_major_locator(loc)
ax.yaxis.set_major_locator(loc)

# Add the grid
ax.grid(which='major', axis='both', linestyle='-')
Shareeshareholder answered 27/5, 2015 at 14:34 Comment(6)
This works perfectly! What would make it ideal is if I could remove the axis labels (such as the line numbers) so I just have the lines, any suggestions?Finnish
How about ax.set_xticklabels([]) and ax.set_yticklabels([])?Shareeshareholder
Works but there's still some annoying whitespace around. Just using plt.grid('on') gives me this which is more desirable (obviously with the correct grid spacing) this isn't a deal breaker would be nice to avoid :)Finnish
plt.tight_layout() might do it.Shareeshareholder
or fig.subplots_adjust(left=0,right=1,bottom=0,top=1)Shareeshareholder
The first does reduce it but the second works perfectly, thanks very much for all your help!Finnish
C
18

You can use ticker to set the tick locations for the grid. The user can specify the input to MultipleLocator which will "Set a tick on every integer that is multiple of base in the view interval." Here's an example:

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

# Two example plots
fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)

spacing = 0.5 # This can be your user specified spacing. 
minorLocator = MultipleLocator(spacing)
ax1.plot(9 * np.random.rand(10))
# Set minor tick locations.
ax1.yaxis.set_minor_locator(minorLocator)
ax1.xaxis.set_minor_locator(minorLocator)
# Set grid to use minor tick locations. 
ax1.grid(which = 'minor')

spacing = 1
minorLocator = MultipleLocator(spacing)
ax2.plot(9 * np.random.rand(10))
# Set minor tick locations.
ax2.yaxis.set_minor_locator(minorLocator)
ax2.xaxis.set_minor_locator(minorLocator)
# Set grid to use minor tick locations. 
ax2.grid(which = 'minor')

plt.show()

Two subplots with different grids.

Edit

To use this along with Networkx you can either create the axes using subplot (or some other function) as above and pass that axes to draw like this.

nx.draw(displayGraph, pos, ax=ax1, node_size = 10)

Or you can call nx.draw as you do in your question and use gca to get the current axis afterwards:

nx.draw(displayGraph, pos, node_size = 10)
ax1 = plt.gca()
Canzone answered 27/5, 2015 at 14:32 Comment(3)
This looks exactly like what I need but one question. For the add_subplot() what should my values be as the plotting is handled by the Networkx library for the graphFinnish
You can either pass the axis to nx.draw() or get the current axis after it's plotted. I edited my answer to include more details.Canzone
Great, thanks for all your help would give +1 if I had enough repFinnish
P
0

You can for example use xlim to get the range of x-axis and with the user specified interval, you should be able to draw the grid yourself using ax.axvline as in this example https://mcmap.net/q/150986/-how-to-create-major-and-minor-gridlines-with-different-linestyles

hope this help.

(edit) here's a sample.

from pylab import *

fig = figure()
ax = fig.add_subplot(111)

ax.plot([1,2,3, 15],[2,3,4, 25],'ro')
xmin,xmax = xlim()
user_interval = 1.5
for _x in np.arange(xmin, xmax, user_interval):
    ax.axvline(x=_x, ls='-')
draw()
Phocaea answered 27/5, 2015 at 14:4 Comment(1)
Bit confused at how the code in the link can allow user specified intervals? Could you clarify for me? ThanksFinnish

© 2022 - 2024 — McMap. All rights reserved.