2013-04-04 13 views
5

Generuję wypełniony wykres warstwowy za pomocą funkcji matplotlib.pyplot.contourf(). Argumenty w wywołaniu funkcji są:Aliasy podczas zapisywania matplotlib wypełnionego konturu do .pdf lub .eps

contourf(xvec,xvec,w,levels,cmap=matplotlib.cm.jet) 

gdzie

xvec = numpy.linspace(-3.,3.,50) 
levels = numpy.linspace(-0.01,0.25,100) 

i w jest moje dane.

Wynikowa fabuła wygląda całkiem nieźle na ekranie, ale kiedy zapisuję do pdf za pomocą wywołania matplotlib.pyplot.savefig(), wynikowy plik pdf ma wiele aliasów (myślę, że to właśnie to się dzieje) . Wywołanie savefig jest po prostu savefig('filename.pdf'). Próbowałem użyć argumentu dpi, ale bez powodzenia. Połączenie z matplotlib.get_backend() wypluwa "TkAgg".

będę załączyć rysunek zapisany w formacie PDF, w porównaniu do wielkości zapisanej jako PNG (podobny do tego, co wygląda na ekranie), aby wykazać problem:

png wihtout aliasing: https://dl.dropbox.com/u/6042643/wigner_g0.17.png

PDF z aliasing: https://dl.dropbox.com/u/6042643/wigner_g0.17.pdf

Proszę dać mi znać, jeśli są jakieś inne szczegóły, które mogę podać, aby pomóc ci udzielić odpowiedzi. Powinienem wspomnieć, że zapisywanie jako .eps daje podobne złe wyniki, jak zapisywanie do pdf. Ale dokument PDF pokazuje problem jeszcze jaśniej. Moim celem jest uzyskanie jakości produkcji .eps, którą mogę dołączyć do dokumentu z lateksu, który ma zostać opublikowany jako dokument naukowy. Byłbym szczęśliwy z jakąś pracą, w której zapisuję w jednym formacie, a następnie ją konwertuję, jeśli uda mi się znaleźć sposób, który da satysfakcjonujące rezultaty.

Best,

Arne

+0

Ci wyglądać [mory] (https://en.wikipedia.org/wiki/Moir%C3%A9_pattern) mi. W formacie PDF wzór zmienia się w zależności od poziomu powiększenia. – tacaswell

+2

@arne: Połączone pliki nie istnieją - istnieje szansa na ich zastąpienie? –

Odpowiedz

5

Po użyciu przydatnej odpowiedzi przez @pelson przez jakiś czas, w końcu znalazłem właściwe rozwiązanie tego długotrwałego problemu (obecnie w Matplotlib 2.0), który nie wymaga wielokrotnych wywołań konturu lub rasteryzacji postaci.

Odwołuję się do mojej oryginalnej odpowiedzi here po szersze wyjaśnienia i przykłady.

Podsumowując, rozwiązanie składa się z następujących pozycji:

cnt = plt.contourf(x, y, z) 

for c in cnt.collections: 
    c.set_edgecolor("face") 

plt.savefig('test.pdf') 
6

nie miałem pojęcia, że ​​konturowe w pdf było tak źle. Masz rację, myślę, że kontury są wygładzane przez renderery PDF poza matplotlib. Z tego powodu uważam, że musisz szczególnie uważać, której aplikacji używasz do przeglądania wynikowego pliku PDF - najlepsze zachowanie, jakie widziałem, jest z GIMP, ale jestem pewien, że jest mnóstwo innych przeglądających, którzy mają dobre wyniki.

Aby rozwiązać ten problem (podczas przeglądania PDF z GIMP), udało mi się „rasteryzację” kontury wytwarzane z matplotlib, aby uniknąć brzydkiego biała linia problem:

import matplotlib.pyplot as plt 
import numpy as np 


xs, ys = np.mgrid[0:30, 0:40] 
data = (xs - 15) ** 2 + (ys - 20) ** 2 + (np.sin(ys) + 10) ** 2 

cs = plt.contourf(xs, ys, data, 60, cmap='jet') 

# Rasterize the contour collections 
for c in cs.collections: 
    c.set_rasterized(True) 

plt.savefig('test.pdf') 

Ten produkowany wykresy liniowe, które nie wykazywał problemów, które pokazałeś.

Innym alternatywnym, może lepszym podejściem byłoby oszukanie antyaliasingu poprzez umieszczenie kolorowych linii poniżej konturu.

import matplotlib.pyplot as plt 
import numpy as np 


xs, ys = np.mgrid[0:30, 0:40] 
data = (xs - 15) ** 2 + (ys - 20) ** 2 + (np.sin(ys) + 10) ** 2 

# contour the plot first to remove any AA artifacts 
plt.contour(xs, ys, data, 60, cmap='jet', lw=0.1) 
cs = plt.contourf(xs, ys, data, 60, cmap='jet') 

plt.savefig('test.pdf') 

Należy zauważyć, że nie widzę tych problemów, gdybym zapisać rysunek jako „.ps” raczej niż „.pdf” - chyba, że ​​jest trzecia alternatywa.

Mam nadzieję, że dzięki temu papier będzie wyglądał dokładnie tak, jak tego chcesz.

+1

Cześć pelson. Poszedłem na twoje drugie rozwiązanie i działało naprawdę dobrze. Wielkie dzięki. – arne

+0

Potrafię również potwierdzić to zachowanie, jeśli zapisuję 'contourf()' z poziomami, zarówno w PS, EPS, PDF, ale nie na wyjściu SVG. Uruchomienie tego rodzaju PS/EPS/PDF przez GhostScript i wyprowadzanie na przykład PNG w rozdzielczości 300dpi, nie stanowi problemu, ale przeglądanie plików PDF w Acrobat, SumatraPDF (wykorzystuje silnik mupdf, desygnowany przez te same osoby za GhostScript), CorelDraw, Ipe, .. wszystkie pokazują ten artefakt jako widoczny. – theta

+0

Co więcej, nie chodzi o to, że kontury mają kontury, ale istnieje niewielka szczelina między konturami, a białe tło okna wykresu przedstawia kontur konturu. – theta

Powiązane problemy