2015-07-16 14 views
11

Mi piace produrre trame di alta qualità e quindi evitare il più possibile la grafica rasterizzata.Importazione di un file svg una figura matplotlib

Sto cercando di importare un file in formato SVG a una figura matplotlib:

import matplotlib.pyplot as plt 
earth = plt.imread('./gfx/earth.svg') 
fig, ax = plt.subplots() 
im  = ax.imshow(earth) 
plt.show() 

Questo funziona con png perfettamente. Qualcuno può dirmi come farlo con svg o almeno puntare alla mia documentazione adeguata.

So che una domanda simile è stata posta (ma non ha risposto): here. Da allora qualcosa è cambiato?

P.S. So che potrei semplicemente esportare un png ad alta risoluzione e ottenere un effetto simile. Questa non è la soluzione che sto cercando.

Ecco l'immagine che vorrei importare: Earth_from_above.

Qualsiasi consiglio è apprezzato. Grazie!

risposta

10

Forse quello che stai cercando è svgutils

import svgutils.compose as sc 
from IPython.display import SVG # /!\ note the 'SVG' function also in svgutils.compose 
import numpy as np 

# drawing a random figure on top of your SVG 
fig, ax = plt.subplots(1, figsize=(4,4)) 
ax.plot(np.sin(np.linspace(0,2.*np.pi)), np.cos(np.linspace(0,2.*np.pi)), 'k--', lw=2.) 
ax.plot(np.random.randn(20)*.3, np.random.randn(20)*.3, 'ro', label='random sampling') 
ax.legend() 
ax2 = plt.axes([.2, .2, .2, .2]) 
ax2.bar([0,1], [70,30]) 
plt.xticks([0.5,1.5], ['water ', ' ground']) 
plt.yticks([0,50]) 
plt.title('ratio (%)') 
fig.savefig('cover.svg', transparent=True) 
# here starts the assembling using svgutils 
sc.Figure("8cm", "8cm", 
    sc.Panel(sc.SVG("./Worldmap_northern.svg").scale(0.405).move(36,29)), 
    sc.Panel(sc.SVG("cover.svg")) 
    ).save("compose.svg") 
SVG('compose.svg') 

Here is the output

+0

Questo è esattamente quello che stavo cercando. Molte grazie! – Sasha

0

SVG (Scalable Vector Graphics) è un formato vettoriale, che significa che l'immagine non è composta da pixel, ma invece di percorsi relativi che possono essere ridimensionati in modo arbitrario.

NumPy/Matplotlib, come software numerico, funziona solo con la grafica a pixel e non può gestire svg. Suggerirei innanzitutto di convertire il file svg ad es. un file png aprendolo e salvandolo in software come Inkscape (che è gratuito). Quindi, apri lo png esportato in Python.

In alternativa, utilizzare le versioni del file fornite da wikimedia nel formato png su the picture's information page (click on the download button to the right of the picture).

Se davvero credi di aver bisogno del modulo vettoriale, beh, non c'è modo di farlo. Puoi sempre sovrapporre manualmente la figura matplotlib alla figura (usando l'artista matplotlib per disegnare sulla trama della trama), o attraverso qualche magia pycairo e salvarla. Ma Matplotlib non può funzionare direttamente con il contenuto di svg.

+1

Grazie per la risposta. Tuttavia, dalla mia domanda, avresti potuto vedere che ho una comprensione delle caratteristiche dei due formati. Ho anche affermato esplicitamente che tutto funziona bene con un png. Inoltre, matplotlib funziona con i percorsi. Ogni volta che salvi un'immagine come eps o svg, stai salvando la grafica vettoriale. La maggior parte dei grafici, prima di salvarli, sono grafici vettoriali che possono essere ridimensionati in modo arbitrario. – Sasha

+0

Matplotlib potrebbe funzionare internamente con i percorsi come 'svg', ma due cose che funzionano con i percorsi non implicano che queste due cose funzionino insieme. Nota Ho anche suggerito di generare separatamente la figura matplotlib e di unirli in una seconda fase manuale o programmata. A meno che non ci si tuffi negli artisti di Matplotlib e si sia pronti a analizzare manualmente il file 'svg', dubito fortemente che sia possibile consentire a Matplotlib di utilizzare il file come sfondo. – rubenvb

+0

Non pensavo fosse così complicato, proverò a vedere come funziona la cosa del parsing. Potresti modificare la tua risposta in modo da poterla votare? – Sasha

Problemi correlati