Matplotlib使用EPS格式的imshow

19

有没有办法使用PIL和matplotlib将EPS或SVG(或任何可伸缩矢量格式)中的标志放置在图形上,并将最终文件输出为EPS。现在,我得到了一个极其糟糕的渲染图形,因为有一个.png文件试图被转换为EPS格式,而目标是将图像保存为.eps或.svg。

我认为这可能是由于后端的限制,我可以更改使用哪个后端。

以下内容无法正常工作:

    ax1.set_axis_bgcolor('#fafafa')
    
    img = image.imread('./static/images/logo.png')
    image_axis = fig.add_axes(ax1.get_position())
    image_axis.patch.set_visible(False)
    image_axis.yaxis.set_visible(False)
    image_axis.xaxis.set_visible(False)
    image_axis.set_xlim(0,19.995)
    image_axis.set_ylim(0,11.25)

    image_axis.imshow(img, extent=(11.79705,18.99525,.238125,1.313625), zorder=-1, alpha=0.15) #need to keep a 5.023 x by y ratio (.4 x .079)

    fig.savefig('static/images/graphs/'+filename+'.eps', format='eps', bbox_inches='tight')

有更新吗?


你刚试过吗?文档暗示如果传递给imshow的图像是非PNG格式,matplotlib将会退而求其次使用PIL来处理EPS文件(文档)。我手头没有EPS文件可以测试,但明天可以尝试一下。 - J Richard Snape
3个回答

2
这是一个老问题,但值得回答,以帮助当前和未来的访问者想要做相同的事情。
有一种方法可以加载SVG文件并将其转换为Path对象,实现在svgpath2mpl软件包中。从该项目页面上可以看到:

SVG中的路径是由包含“d =(路径数据)”属性的“路径”元素定义的,该属性包含moveto、line、curve(二次和三次Béziers)、arc和closepath指令。 Matplotlib实际上本地支持所有这些指令,但不提供解析器或完全兼容的API。

Matplotlib自定义标记/符号中看到。

0

我删除了我的代码片段,因为它没有用。

在Matplotlib中不可能使用本地SVG作为图像。Matplotlib仅原生支持png格式,然后退回到Pillow,但Pillow也不支持svg格式,请参见http://pillow.readthedocs.io/en/latest/handbook/image-file-formats.html或Matplotlib图像文档。

Pillow支持eps格式,所以这将起作用!(我不确定Matplotlib内部会怎么处理)

我是这样使用它的:

# Pillow must be there
import matplotlib.image as mpimg

def Save_svg(fig):
    # expects a matplotlib figure
    # And puts a logo into a frameless new axes
    imagefile = 'logo.eps'
    svgfile   = 'output.svg'
    logoax    = [0.265, 0.125, 0.3, 0.3]
    img=mpimg.imread(imagefile)
    #
    newax = fig.add_axes(logoax, anchor='SW', zorder=100)
    newax.imshow(img)
    newax.axis('off')
    #
    fig.savefig(svgfile,dpi=300)

1
你的示例嵌入了一个jpg标志-OP想要嵌入eps/svg。我认为重点是他们想要始终保持矢量图形。 - J Richard Snape
@JRichardSnape 没错 - 目标是将输出转换为SVG/EPS格式。我还没有解决这个问题,但如果我解决了,我会更新的。 - Jared
我最近解决了这个问题,因此我完全更新了上面的答案。 - JRM

0

在这种情况下,我通常使用类似以下的方式来实现更好的渲染效果:

from PIL import Image

logo = Image.open('icons\logo.png')
# TODO define bbox as a matplotlib.transforms.Bbox
image_axis.imshow(logo, clip_box=bbox, aspect='equal',
   origin='lower', interpolation='nearest')

(如果您使用旧版本)Matplotlib 1.4.2,玩弄interpolationorigin选项可能会有所帮助。

这是否适用于矢量图形 - 而不是PNG? - Jared
PIL可以处理.eps文件。虽然它们会被栅格化,但你可以控制点的数量(请参阅链接)。 - GBy
目标是将图形保存为eps或其他可缩放的矢量图形,并包含标志。 - Jared
好的。使用这段代码,您可以将图形保存为PDF(可能也支持EPS,但未经测试),并包含标志 - 但它将被嵌入为光栅图像。 - GBy

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