How can I get the output of a matplotlib plot as an SVG?

I need to take the output of a matplotlib plot and turn it into an SVG path that I can use on a laser cutter.

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()

For example, below you see a waveform. I would like to be able to output or save this waveform as an SVG path that I can later work with in a program such as Adobe Illustrator.

I am aware of an SVG library called "Cairo" that matplotlib can use (matplotlib.use('Cairo')), however it's not clear to me that this will give me access to the SVG path that I need, even though matplotlib will now be using Cairo to generate the plot.

enter image description here

I do have cairo working on my system, and can successfully draw an example composed of SVG paths that I can indeed edit in Illustrator, but I don't have a way to take my equation above into an SVG path.

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()

enter image description here

(note that the image displayed here is a png, as stackoverflow doesn't accept svg graphics for display)

152800 次浏览

根据所使用的后端(我在 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")

你最有可能想修改图像的大小,去掉各种背景和轴标记:

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“每单位)。