ChatGPT解决这个技术问题 Extra ChatGPT

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.

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

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

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

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

@jonnybazookatone was almost right, add transparent=True

S
Seenu S

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


Thanks. Interestingly I needed to do the above before calling plt.show(). If I called plt.show() before savefig the svg ended up being just a white background when opened in illustrator.
@user391339 Great spot. I was having a real issue with the blank-white-save. Is it known why this happens?
plt.show() clears the whole thing, so anything afterwards will happen on a new empty figure.
Is there a way to send the raw svg text to a string, rather than having to output it to the filesystem?
@Thomas Kimber from io import StringIO f = StringIO() plt.savefig(f, format='svg') print(f.getvalue())
j
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:

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

What if the figure is completely white?
@ZloySmiertniy then it didn't work. Make sure to use savefig() right after plot(). If you call it after show() it will make a completely white SVG.
Just to be precise, Make sure to use savefig() right before show() since that was what causes completely white SVG.