Rug*_*man 30 python matplotlib
我正在开发一个Web应用程序,并希望在页面的不同位置显示一个图形及其图例.这意味着我需要将图例保存为单独的png文件.这在Matplotlib中是否可能以一种或多或少的直接方式实现?
Ste*_*joa 20
这可能有效:
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')
Run Code Online (Sandbox Code Playgroud)

And*_*ner 15
使用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")
Run Code Online (Sandbox Code Playgroud)
虽然以自动方式获得图例图形的大小,但这可能很棘手.
Imp*_*est 11
您可以使用bbox_inches参数to 将图形的保存区域限制为图例的边界框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()
Run Code Online (Sandbox Code Playgroud)
如果图例周围有边框,则上述解决方案可能不是最理想的.在这种情况下,将边界框扩展一些像素以将边框包含在其中是有意义的.
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()
Run Code Online (Sandbox Code Playgroud)
我发现最简单的方法就是创建您的图例,然后关闭axiswith 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()
Run Code Online (Sandbox Code Playgroud)
这会自动计算图例的大小.如果mode == 1,代码类似于Steve Tjoa的回答,那么mode == 2类似于Andre Holzner的回答.
该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')
Run Code Online (Sandbox Code Playgroud)
原始(未剪切)传奇:

裁剪的传奇:

受到 Maxim 和 ImportanceOfBeingErnest 答案的启发,
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)
Run Code Online (Sandbox Code Playgroud)
这允许我将图例水平保存在单独的文件中。举个例子
可以用于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')
Run Code Online (Sandbox Code Playgroud)
如果出于某种原因只想隐藏轴标签,则可以使用:
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
Run Code Online (Sandbox Code Playgroud)
或者,由于某些奇怪的原因,您想隐藏轴框架而不是隐藏可以使用的轴标签:
ax.set_frame_on(False)
Run Code Online (Sandbox Code Playgroud)
ps:此答案已从我的答案改编为重复的问题
| 归档时间: |
|
| 查看次数: |
16809 次 |
| 最近记录: |