web-dev-qa-db-fra.com

Comment puis-je obtenir la sortie d'un graphique matplotlib en tant que SVG?

Je dois prendre la sortie d'un graphique matplotlib et le transformer en un chemin SVG que je peux utiliser sur un cutter laser.

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

Par exemple, ci-dessous, vous voyez une forme d'onde. J'aimerais pouvoir sortir ou enregistrer cette forme d'onde en tant que chemin SVG que je pourrai utiliser ultérieurement dans un programme tel que Adobe Illustrator.

Je connais une bibliothèque SVG appelée "Cairo" que matplotlib peut utiliser (matplotlib.use('Cairo')), mais je ne suis pas certain que cela me donnera accès au chemin SVG dont j'ai besoin, même si matplotlib le fera maintenant. être en utilisant Cairo pour générer l'intrigue.

enter image description here

Cairo fonctionne sur mon système et je peux tracer avec succès un exemple composé de chemins SVG que je peux effectivement éditer dans Illustrator, mais je n'ai pas le moyen de prendre mon équation ci-dessus dans un chemin 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()

enter image description here

(notez que l'image affichée ici est un png, car stackoverflow n'accepte pas les graphiques svg pour l'affichage)

45
user391339

Vous voudrez probablement corriger la taille de l'image et vous débarrasser de toutes sortes d'arrière-plans et de marqueurs d'axe:

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

Le fichier SVG résultant ne contient qu'un seul élément supplémentaire, car savefig veut vraiment sauvegarder l'arrière-plan de la figure. Il est facile de changer la couleur de ce fond en "aucun", mais il ne semble pas s’en débarrasser. Quoi qu'il en soit, le SVG est très propre sinon et à la bonne échelle (1/72 "par unité).

57
DrV

Selon le backend que vous utilisez (j'ai testé sur TkAgg et Agg), il devrait être aussi simple que de le spécifier dans l'appel de 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")
24
jonnybazookatone