Python 如何将 matplotlib 图的输出作为 SVG 获取?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24525111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get the output of a matplotlib plot as an SVG?
提问by user391339
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.
我需要获取 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()
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.
例如,下面您会看到一个波形。我希望能够将此波形输出或保存为 SVG 路径,以便稍后在 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.
我知道 matplotlib 可以使用一个名为“Cairo”的 SVG 库 ( matplotlib.use('Cairo')
),但是我不清楚这将使我能够访问我需要的 SVG 路径,即使 matplotlib 现在将使用 Cairo 生成绘图.
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.
我确实有 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()
(note that the image displayed here is a png, as stackoverflow doesn't accept svg graphics for display)
(请注意,此处显示的图像是 png,因为 stackoverflow 不接受用于显示的 svg 图形)
采纳答案by DrV
You will most probably want to fix the image size and get rid of all sorts of backgrounds and axis markers:
您很可能想要修复图像大小并摆脱各种背景和轴标记:
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")
The resulting SVG file contains only one extra element, as savefig
really wants to save the figure background. The color of this background is easy to change to 'none', but it does not seem to get rid of it. Anyway, the SVG is very clean otherwise and in the correct scale (1/72" per unit).
生成的 SVG 文件只包含一个额外的元素,因为savefig
真的想保存图形背景。这个背景的颜色很容易改成'none',但它似乎并没有摆脱它。无论如何,SVG 非常干净,并且比例正确(每单位 1/72")。
回答by jonnybazookatone
Depending on the backend you use (I tested on TkAgg and Agg) it should be as easy as specifying it within the savefig() call:
根据您使用的后端(我在 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")