我正在开发Web应用程序,并希望在页面的不同位置显示图形及其图例。这意味着我需要将图例另存为单独的png文件。在Matplotlib中以某种或多或少的直接方式可能吗?
这可能有效:
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')
使用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")
尽管以自动化方式正确设置图例图形的大小可能很棘手。
您可以使用bbox_inches
的fig.savefig
参数将图形的保存区域限制为图例的边界框。下面是函数版本,您可以简单地调用要保存为参数的图例。您可以使用此处在原始图形中创建的图例(然后将其删除,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()
这会自动计算图例的大小。如果为mode == 1
,则代码类似于史蒂夫·特乔的答案,而mode == 2
与安德烈·霍尔兹纳的答案相似。
[loc
参数必须设置为'center'
以使其起作用(但我不知道为什么这样做是必要的。)。
mode = 1
#mode = 2
import pylab
fig = pylab.figure()
if mode == 1:
lines = fig.gca().plot(range(10), pylab.randn(10), range(10), pylab.randn(10))
legend_fig = pylab.figure(figsize=(3,2))
legend = legend_fig.legend(lines, ('one', 'two'), 'center')
if mode == 2:
fig.gca().plot(range(10), pylab.randn(10), range(10), pylab.randn(10), label='asd')
legend_fig = pylab.figure()
legend = pylab.figlegend(*fig.gca().get_legend_handles_labels(), loc = 'center')
legend.get_frame().set_color('0.70')
legend_fig.canvas.draw()
legend_fig.savefig('legend_cropped.png',
bbox_inches=legend.get_window_extent().transformed(legend_fig.dpi_scale_trans.inverted()))
legend_fig.savefig('legend_original.png')
原始(未裁剪)图例:
裁剪图例:
<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS92V3g4RS5wbmcifQ==” alt =“裁剪图例”>
我发现最简单的方法就是创建您的图例,然后用axis
关闭plt.gca().set_axis_off()
:
# Create a color palette
palette = dict(zip(['one', 'two'], ['b', 'g']))
# Create legend handles manually
handles = [mpl.patches.Patch(color=palette[x], label=x) for x in palette.keys()]
# Create legend
plt.legend(handles=handles)
# Get current axes object and turn off axis
plt.gca().set_axis_off()
plt.show()
可以使用axes.get_legend_handles_labels
从一个axes.get_legend_handles_labels
对象获取图例句柄和标签,并使用它们将它们添加到另一幅图中的轴上。
axes
如果出于某种原因只想隐藏轴标签,则可以使用:
# create a figure with one subplot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3,4,5], [1,2,3,4,5], 'r', label='test')
# save it *without* adding a legend
fig.savefig('image.png')
# then create a new image
# adjust the figure size as necessary
figsize = (3, 3)
fig_leg = plt.figure(figsize=figsize)
ax_leg = fig_leg.add_subplot(111)
# add the legend from the previous axes
ax_leg.legend(*ax.get_legend_handles_labels(), loc='center')
# hide the axes frame and the x/y labels
ax_leg.axis('off')
fig_leg.savefig('legend.png')
或者如果出于某些奇怪的原因,您想隐藏轴框架而不是隐藏可以使用的轴标签:
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
ps:此答案已从我的答案改编为ax.set_frame_on(False)
受到Maxim和ImportanceOfBeingErnest的回答的启发,
duplicate question
这使我可以将图例水平保存在单独的文件中。举例
def export_legend(ax, filename="legend.pdf"):
fig2 = plt.figure()
ax2 = fig2.add_subplot()
ax2.axis('off')
legend = ax2.legend(*ax.get_legend_handles_labels(), frameon=False, loc='lower center', ncol=10,)
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)