在Matplotlib中单独获取图例图片
我正在开发一个网页应用,想把图形和它的说明文字放在页面的不同位置。这就意味着我需要把说明文字单独保存为一个png格式的文件。请问在Matplotlib中,有没有比较简单的方法可以做到这一点?
11 个回答
18
使用 pylab.figlegend(..)
和 get_legend_handles_labels(..)
:
import pylab, numpy
x = numpy.arange(10)
# create a figure for the data
figData = pylab.figure()
ax = pylab.gca()
for i in xrange(3):
pylab.plot(x, x * (i+1), label='line %d' % i)
# create a second figure for the legend
figLegend = pylab.figure(figsize = (1.5,1.3))
# produce a legend for the objects in the other figure
pylab.figlegend(*ax.get_legend_handles_labels(), loc = 'upper left')
# save the two figures to files
figData.savefig("plot.png")
figLegend.savefig("legend.png")
不过,要自动调整图例的大小可能会有点棘手。
30
你可以通过在调用 fig.savefig
时使用 bbox_inches
参数,来限制保存的图像区域为图例的边界框。下面有两个版本的函数,你只需要把想要保存的图例作为参数传入就可以了。你可以使用原始图形中创建的图例(然后再把它移除,使用 legend.remove()
),或者你也可以为图例创建一个新的图形,直接使用这个函数。
导出图例边界框
如果你想保存完整的图例,那么传给 bbox_inches
参数的边界框就是图例的变换后的边界框。如果图例周围没有边框,这个方法效果很好。
import matplotlib.pyplot as plt
colors = ["crimson", "purple", "gold"]
f = lambda m,c: plt.plot([],[],marker=m, color=c, ls="none")[0]
handles = [f("s", colors[i]) for i in range(3)]
labels = colors
legend = plt.legend(handles, labels, loc=3, framealpha=1, frameon=False)
def export_legend(legend, filename="legend.png"):
fig = legend.figure
fig.canvas.draw()
bbox = legend.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
fig.savefig(filename, dpi="figure", bbox_inches=bbox)
export_legend(legend)
plt.show()
导出扩展的图例边界框
如果图例周围有边框,上面的解决方案可能就不太理想了。在这种情况下,扩展边界框几像素,以包含完整的边框是有意义的。
import numpy as np
import matplotlib.pyplot as plt
colors = ["crimson", "purple", "gold"]
f = lambda m,c: plt.plot([],[],marker=m, color=c, ls="none")[0]
handles = [f("s", colors[i]) for i in range(3)]
labels = colors
legend = plt.legend(handles, labels, loc=3, framealpha=1, frameon=True)
def export_legend(legend, filename="legend.png", expand=[-5,-5,5,5]):
fig = legend.figure
fig.canvas.draw()
bbox = legend.get_window_extent()
bbox = bbox.from_extents(*(bbox.extents + np.array(expand)))
bbox = bbox.transformed(fig.dpi_scale_trans.inverted())
fig.savefig(filename, dpi="figure", bbox_inches=bbox)
export_legend(legend)
plt.show()
35
这可能有效:
import pylab
fig = pylab.figure()
figlegend = pylab.figure(figsize=(3,2))
ax = fig.add_subplot(111)
lines = ax.plot(range(10), pylab.randn(10), range(10), pylab.randn(10))
figlegend.legend(lines, ('one', 'two'), 'center')
fig.show()
figlegend.show()
figlegend.savefig('legend.png')