2015-07-16 16 views
11

Lubię tworzyć wysokiej jakości działki, a tym samym unikać rasteryzacji grafiki tak bardzo, jak to możliwe.Importowanie pliku svg matplotlib figure

próbuję zaimportować plik SVG do figury matplotlib:

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

ten współpracuje z png doskonale. Czy ktoś może mi powiedzieć, jak to zrobić z svg lub przynajmniej wskazać mi odpowiednią dokumentację.

Wiem, że podobne pytanie zostało zadane (ale nie udzielono odpowiedzi): here. Czy od tego czasu coś się zmieniło?

P.S. Wiem, że mogę wyeksportować png o wysokiej rozdzielczości i osiągnąć podobny efekt. To nie jest rozwiązanie, którego szukam.

Oto obraz, który chciałbym zaimportować: Earth_from_above.

Wszelkie wskazówki są mile widziane. Dzięki!

Odpowiedz

10

Może to, czego szukasz, jest 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

Tego właśnie szukałem. Wielkie dzięki! – Sasha

0

SVG (Scalable Vector Graphics) jest formatem wektorowym, co oznacza, że ​​obraz nie składa się z pikseli, ale zamiast względnych ścieżek, które można dowolnie skalować.

NumPy/Matplotlib, jako oprogramowanie numeryczne, działa tylko z grafiką pikseli i nie może obsłużyć svg. Proponuję najpierw przekonwertować plik svg na np. plik png, otwierając i zapisując go w oprogramowaniu takim jak Inkscape (który jest bezpłatny). Następnie otwórz wyeksportowany plik png w języku Python.

Można również użyć dostarczonych wersji pliku wikimedia w formacie png na the picture's information page (click on the download button to the right of the picture).

Jeśli naprawdę wierzysz, że potrzebujesz formy wektorowej, cóż, nie ma sposobu, aby to zrobić. Zawsze możesz nałożyć figurkę matplotlib na figurę ręcznie (używając artysty matplotlib, aby narysować na płótnie) lub magię pycairo i zachować ją. Ale Matplotlib nie może pracować bezpośrednio z zawartością svg.

+1

Dziękuję za odpowiedź. Jednak z mojego pytania wynika, że ​​rozumiem cechy obu tych formatów. Wyraźnie stwierdziłem również, że wszystko działa dobrze z png. Ponadto matplotlib działa ze ścieżkami. Za każdym razem, gdy zapisujesz obraz jako eps lub svg, oszczędzasz grafikę wektorową. Większość fabuł, zanim je zapiszesz, to grafika wektorowa, którą można dowolnie skalować. – Sasha

+0

Matplotlib może pracować wewnętrznie z ścieżkami, podobnie jak 'svg', ale dwie rzeczy związane ze ścieżkami nie oznaczają, że te dwie rzeczy pracują razem. Uwaga: Zasugerowałem także wygenerowanie figury matplotlib osobno i połączenie ich w drugim kroku ręcznym lub skryptowym. Dopóki nie zagłębisz się w artystów Matplotlib i jesteś przygotowany do ręcznego analizowania pliku 'svg', zdecydowanie wątpię, że będziesz mógł pozwolić Matplotlibowi użyć tego pliku jako tła. – rubenvb

+0

Nie sądziłem, że to jest tak skomplikowane, spróbuję zobaczyć, jak działa parsowanie. Czy możesz edytować swoją odpowiedź, aby móc ją głosować w górę? – Sasha