16
votes

When I draw a figure using matplotlib how do I save it without extra margins? Usually when I save it as

plt.savefig("figure.png") # or .pdf

I get it with some margins:

enter image description here

Example:

import matplotlib.pyplot as plt
import networkx as nx

G=nx.Graph()

G.add_edge('a','b',weight=1)
G.add_edge('a','c',weight=1)
G.add_edge('a','d',weight=1)
G.add_edge('a','e',weight=1)
G.add_edge('a','f',weight=1)
G.add_edge('a','g',weight=1)

pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos,node_size=1200,node_shape='o',node_color='0.75')

nx.draw_networkx_edges(G,pos,
                width=2,edge_color='b')

plt.axis('off')
plt.savefig("degree.png", bbox_inches="tight")
plt.show() 

Update 2:

The spaces are set inside the axes.. This is clear if I remove plt.axis('off')
So I think there is some trick to use with the package Networkx.

6

6 Answers

11
votes

Try plt.savefig("figure.png", bbox_inches="tight").

Edit: Ah, you didn't mention you were using networkx (although now I see it's listed in a tag). bbox_inches="tight" is the way to crop the figure tightly. I don't know what networkx is doing, but I imagine it's setting some plot parameters that are adding extra space to the axes. You should look for a solution in networkx rather than matplotlib. (It may be, for instance, that networkx is adding the space inside the axes, not the figure; what does it look like if you remove that axis('off') call?)

9
votes

add the codes below to control plot limits before saving.

try different values of cut, like from 1.05 to 1.50, until you see fit.

# adjust the plot limits
cut = 1.05
xmax= cut*max(xx for xx,yy in pos.values())
ymax= cut*max(yy for xx,yy in pos.values())
plt.xlim(0,xmax)
plt.ylim(0,ymax)
1
votes

Use the following:

plt.margins(0.0)
0
votes

A bit of a hack, but if you use nx.draw, then it does a tighter fit.

So you could do

nx.draw(G,pos,node_size=1200,node_shape='o',node_color='0.75', edgelist = [])

which just draws the nodes and no edges. Then it's fine to do

nx.draw_networkx_edges(G, pos, width=2, edge_color='b')
0
votes

To make the figure at the center you can use the following:

cut             = 1.1
xmax            = max(xx for xx,yy in pos.values())
ymax            = max(yy for xx,yy in pos.values())
xmin            = min(xx for xx,yy in pos.values())
ymin            = min(yy for xx,yy in pos.values())

xincrease       = (cut - 1)*xmax
yincrease       = (cut - 1)*ymax

plt.xlim(xmin - xincrease, cut*xmax)
plt.ylim(ymin - yincrease, cut*ymax)
-1
votes

Without knowing the specifics of networkx I cannot be certain that this will work, but to remove the whitespace completely from the outside of an axes in matplotlib, you can do something along the lines of:

import matplotlib.pyplot as plt
ax = plt.axes([0, 0, 1, 1])
plt.plot(range(10))