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

2

130

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)

Jalousie answered 2/7, 2014 at 7:19 Comment(0)
J
132

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

Jorrie answered 2/7, 2014 at 15:45 Comment(7)
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.Jalousie
@Jalousie Great spot. I was having a real issue with the blank-white-save. Is it known why this happens?Hasp
@josh this is not just for SVG. see here: #9012987Casuist
plt.show() clears the whole thing, so anything afterwards will happen on a new empty figure.Overstate
Is there a way to send the raw svg text to a string, rather than having to output it to the filesystem?Calc
How about using transparent=True on the savefig call?Negate
@Thomas Kimber from io import StringIO f = StringIO() plt.savefig(f, format='svg') print(f.getvalue())Morbihan
T
48

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")
Trafalgar answered 2/7, 2014 at 15:0 Comment(3)
What if the figure is completely white?Sportswoman
@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.Dinger
Just to be precise, Make sure to use savefig() right before show() since that was what causes completely white SVG.Laudable

© 2022 - 2024 — McMap. All rights reserved.