无边距保存matplotlib/networkx图形

16

在使用 matplotlib 绘制图形时,如何在保存图像时去除额外的边距?通常情况下,我会将其保存为

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

我观察到有一些边距:

enter image description here

例如:

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() 

更新2:

这些空格设置在坐标轴内部。如果我移除plt.axis('off'),这一点就很清楚了。
因此我认为在使用Networkx包时有一些技巧。

7个回答

11

尝试使用plt.savefig("figure.png", bbox_inches="tight")

编辑:啊,你没有提到你正在使用networkx(虽然现在我看到它已经列在标签中了)。bbox_inches="tight"是紧密裁剪图形的方法。我不知道networkx在做什么,但我想它可能设置了一些绘图参数,导致轴添加了额外的空间。你应该在networkx中寻找解决方案,而不是在matplotlib中。(例如,networkx可能将空格添加到内部,而不是整个图形;如果您删除axis('off')调用会出现什么情况?)


你能举个例子说明你所说的“margins”是什么意思吗? - BrenBarn
谢谢。我不希望保存的图形有额外的空白。我只想让边框完全限制图形的范围。这清楚吗? - Aya
这正是 bbox_inches="tight" 所做的。你能解释一下它为什么不能满足你的需求吗?另外,你使用的是哪个版本的 matplotlib? - BrenBarn
我认为这是版本:Python 2.7 matplotlib-1.1.0。 - Aya
是的,你说得对。空格在轴内。谢谢。 - Aya

9

在保存之前,添加以下代码来控制绘图限制。

尝试不同的cut值,比如从1.05到1.50,直到你满意为止。

# 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)

非常感谢。它可以工作,但需要删除图形的一些小限制部分。我无法完整地获取图形。因此,我认为我只需要进行一些修改即可。 - Aya
2
你可以尝试更保守的裁剪(1.10或1.05而不是1.02),直到画布适合为止。 - nye17
我仍然更喜欢另一种自动修复边界的方法。我认为这将使用Networkx实现,因为节点形状的原因。 - Aya
1
@Aya,你可能想在networkx邮件列表上提出问题,另外,你可以尝试将上述代码封装成一个函数,这样你就可以随时调用它,而不必一遍又一遍地复制和粘贴。 - nye17
1
NetworkX必须根据数据和节点形状来确定x限制和y限制。只需对确切的数据值进行简单的填充,以考虑节点形状即可。您可以使用上述描述的plt.xlim()和plt.ylim()来调整它。调用这些函数而不带参数将给出当前限制。 - Aric
1
这不起作用。我尝试了不同的切割值,但我的图形总是被“裁剪”了。 - Jack Twain

5
请使用以下内容:
plt.margins(0.0)

1
Jurkiewics使用margins(0.15)可以正常绘制图形,而margins(0.0)则无法让图形完全显示在页面中。 - D. O.

1

我最近偶然发现了一个非常好的解决方案:

import matplotlib.pyplot as plt
import networkx as nx


fig, ax = plt.subplots()

#We create our graph.
#...

#We remove the surrounding box.
plt.box(False)

#We save our graph.
fig.savefig(filename)


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Ethan

0
有点取巧,但如果您使用nx.draw,则会更紧密地适合。
所以您可以这样做:
nx.draw(G,pos,node_size=1200,node_shape='o',node_color='0.75', edgelist = [])

这只是绘制节点而没有边缘。然后就可以了

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

0

要制作中心的图形,您可以使用以下方法:

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

如果不了解networkx的具体情况,我无法确定这是否有效,但是要完全从matplotlib中的轴外部删除空格,您可以执行以下操作:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接