ChatGPT解决这个技术问题 Extra ChatGPT

如何将 matplotlib 图的输出作为 SVG?

我需要获取 matplotlib 绘图的输出并将其转换为可在激光切割机上使用的 SVG 路径。

import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0,100,0.00001)
y = x*np.sin(2*pi*x)
plt.plot(y)
plt.show()

例如,您可以在下面看到一个波形。我希望能够将此波形输出或保存为 SVG 路径,以便以后在 Adobe Illustrator 等程序中使用。

我知道 matplotlib 可以使用一个名为“Cairo”的 SVG 库(matplotlib.use('Cairo')),但是我不清楚这是否可以让我访问我需要的 SVG 路径,即使 matplotlib 现在将使用 Cairo生成情节。

https://i.stack.imgur.com/RVWFF.png

我确实有 cairo 在我的系统上工作,并且可以成功绘制一个由 SVG 路径组成的示例,我确实可以在 Illustrator 中编辑它,但是我没有办法将上面的等式带入 SVG 路径。

import cairo
from cairo import SVGSurface, Context, Matrix    
s = SVGSurface('example1.svg', WIDTH, HEIGHT)
c = Context(s)

# Transform to normal cartesian coordinate system
m = Matrix(yy=-1, y0=HEIGHT)
c.transform(m)

# Set a background color
c.save()
c.set_source_rgb(0.3, 0.3, 1.0)
c.paint()
c.restore()

# Draw some lines
c.move_to(0, 0)
c.line_to(2 * 72, 2* 72)
c.line_to(3 * 72, 1 * 72)
c.line_to(4 * 72, 2 * 72)
c.line_to(6 * 72, 0)
c.close_path()
c.save()
c.set_line_width(6.0)
c.stroke_preserve()
c.set_source_rgb(0.3, 0.3, 0.3)
c.fill()
c.restore()

# Draw a circle
c.save()
c.set_line_width(6.0)
c.arc(1 * 72, 3 * 72, 0.5 * 72, 0, 2 * pi)
c.stroke_preserve()
c.set_source_rgb(1.0, 1.0, 0)
c.fill()
c.restore()

# Save as a SVG and PNG
s.write_to_png('example1.png')
s.finish()

https://i.stack.imgur.com/nRSpW.png

(请注意,此处显示的图像是 png,因为 stackoverflow 不接受 svg 图形进行显示)

@jonnybazookatone 几乎是对的,添加 transparent=True

S
Seenu S

您很可能希望修复图像大小并摆脱各种背景和轴标记:

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=[6, 6])
x = np.arange(0, 100, 0.00001)
y = x*np.sin(2* np.pi * x)
plt.plot(y)
plt.axis('off')
plt.gca().set_position([0, 0, 1, 1])
plt.savefig("test.svg")

生成的 SVG 文件仅包含一个额外元素,因为 savefig 确实想要保存图形背景。此背景的颜色很容易更改为“无”,但似乎并没有摆脱它。无论如何,SVG 在其他方面非常干净,并且比例正确(每单位 1/72 英寸)。


谢谢。有趣的是,我需要在调用 plt.show() 之前执行上述操作。如果我在 savefig 之前调用 plt.show() ,则在 illustrator 中打开时,svg 最终只是一个白色背景。
@user391339 好地方。我对空白-白色-保存有一个真正的问题。知道为什么会发生这种情况吗?
plt.show() 清除整个事情,因此之后的任何事情都会发生在一个新的空人物上。
有没有办法将原始 svg 文本发送到字符串,而不必将其输出到文件系统?
@Thomas Kimber from io import StringIO f = StringIO() plt.savefig(f, format='svg') print(f.getvalue())
j
jonnybazookatone

根据您使用的后端(我在 TkAgg 和 Agg 上测试过),它应该像在 savefig() 调用中指定它一样简单:

import matplotlib.pyplot as plt                                                                                                                                                               
import numpy as np
x = np.arange(0,100,0.00001)
y = x*np.sin(2*np.pi*x)
plt.plot(y)
plt.savefig("test.svg", format="svg")

如果图形是全白的呢?
@ZloySmiertniy 然后它没有用。确保在 plot() 之后立即使用 savefig()。如果你在 show() 之后调用它,它会生成一个完全白色的 SVG。
准确地说,确保在 show() 之前使用 savefig(),因为那是导致完全白色 SVG 的原因。