将svg文件导入matplotlib图

bmp9r5qi  于 2023-03-13  发布在  其他
关注(0)|答案(4)|浏览(174)

我喜欢生成高质量的打印,因此尽可能避免光栅化图形。
我正在尝试将一个svg文件导入到matplotlib图中:

import matplotlib.pyplot as plt
earth   = plt.imread('./gfx/earth.svg')
fig, ax = plt.subplots()
im      = ax.imshow(earth)
plt.show()

这在png上运行得很好。有人能告诉我如何用svg来做吗?或者至少给我指一指合适的文档。
我知道有人提出过类似的问题(但没有得到回答):here .之后有什么变化吗?
我知道我可以只导出一个高分辨率的PNG就能达到类似的效果,这不是我要找的解决方案。
下面是我想要导入的图像:


.

s5a0g9ez

s5a0g9ez1#

也许您要查找的是svgutils

import svgutils.compose as sc
from IPython.display import SVG # /!\ note the 'SVG' function also in svgutils.compose
import numpy as np

# drawing a random figure on top of your SVG
fig, ax = plt.subplots(1, figsize=(4,4))
ax.plot(np.sin(np.linspace(0,2.*np.pi)), np.cos(np.linspace(0,2.*np.pi)), 'k--', lw=2.)
ax.plot(np.random.randn(20)*.3, np.random.randn(20)*.3, 'ro', label='random sampling')
ax.legend()
ax2 = plt.axes([.2, .2, .2, .2])
ax2.bar([0,1], [70,30])
plt.xticks([0.5,1.5], ['water  ', ' ground'])
plt.yticks([0,50])
plt.title('ratio (%)')
fig.savefig('cover.svg', transparent=True)
# here starts the assembling using svgutils 
sc.Figure("8cm", "8cm", 
    sc.Panel(sc.SVG("./Worldmap_northern.svg").scale(0.405).move(36,29)),
    sc.Panel(sc.SVG("cover.svg"))
    ).save("compose.svg")
SVG('compose.svg')

输出:

omtl5h9j

omtl5h9j2#

到2021年来到这里的人。
我建议查看一下cairosvg
conda install -c conda-forge cairosvgpip3 install cairosvg
https://cairosvg.org/

import cairosvg
import matplotlib.pyplot as plt
from PIL import Image
from io import BytesIO

img_png = cairosvg.svg2png("... the content of the svg file ...")
img = Image.open(BytesIO(img_png))
plt.imshow(img)
gjmwrych

gjmwrych3#

Yann Zerlaut给出的答案有利有弊:

  • 优点:它适用于任意复杂度的任何SVG图像,因此非常通用。
  • 缺点:SVG图形不是由matplotlib后端处理的,而是由matplotlib图像覆盖SVG图像。

这会导致伪像。例如,SVG图像中的线宽与Matplotlib中的线宽不同。在研究这一点的同时,我找到了Matplotlib中没有SVG支持的一些答案。
为了寻找更好的解决方案,我发现了一些值得在这里列出的解决方案,它们也有优点和缺点。

将SVG路径转换为matplotlib路径的简单解析器

https://matplotlib.org/stable/gallery/showcase/firefox.html#sphx-glr-gallery-showcase-firefox-py

  • Pro:使用matplotlib艺术家绘制SVG路径
  • Con:只适用于简单的SVG,除非您扩展了解析器
臭鼬

https://github.com/whitead/skunk

  • 优点:基本上是Yann Zerlaut在类固醇和库中的解决方案。您可以将SVG绘制到一个由Matplotlib处理的框中,它允许高级布局。
  • 缺点:SVG图像不是由matplotlib本地处理的,这只是一个将一个矢量图形蒙太奇到另一个矢量图形中的聪明方法。

结论

根据to the discussion here,在matplotlib中没有对导入SVG的本地支持,因为编写一个完全兼容的解析器很困难,而且matplotlib开发人员可能也不想引入外部解析库。
然而,编写一个用于路径的原语解析器实际上非常容易,正如您在matplotlib演示中所看到的,对于OP这样的简单用例,这可能就足够了。
对于复杂的情况,skunk很好地自动化了SVG图像的合成。

aemubtdh

aemubtdh4#

SVG(可缩放矢量图形)是一种矢量格式,这意味着图像不是由像素组成的,而是由可以任意缩放的相对路径组成的。
NumPy/Matplotlib,作为数值软件,只能处理像素图形,不能处理svg。我建议首先将svg文件转换为png文件,方法是在Inkscape(免费)等软件中打开并保存它。然后,在Python中打开导出的png
或者,使用wikimedia提供的pngthe picture's information page (click on the download button to the right of the picture)文件版本。
如果你真的认为你需要矢量形式,那么,没有办法做到这一点。你总是可以手动地将matplotlib图形叠加到图形上(使用matplotlib Artist在绘图画布上绘图),或者通过一些pycairo魔法,并保存它。但是Matplotlib不能直接处理svg内容。

相关问题