2011-11-25 7 views
12

Mam projekt pet do tworzenia obrazów map, gdzie rysuję drogi i inne rzeczy na konturze z rzędem elewacji terenu. Jest przeznaczony do planowania tras rowerowych (w przeszłości wykonałem ręcznie wektorowe rysunki i świetnie się sprawdzają przy wizualizacji).Ukryj kontur linestroke na pyplot.contourf, aby uzyskać tylko wypełnienia

Obecnie pobrać cyfrowego modelu terenu, w GeoTIFF, stąd: http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar

a następnie utworzyć wykres z funkcją GDAL i matplotlib contourf:

from osgeo import gdal 
import matplotlib 
import matplotlib.pyplot as plt 
from pylab import cm 
import numpy 

f = 'rs.tif' 

elev = gdal.Open(f) 

a = elev.GetRasterBand(1).ReadAsArray() 

w = elev.RasterXSize 
h = elev.RasterYSize 
print w, h 

altura = (0.35, 0.42) 
largura = (0.70, 0.82) 

a = a[int(h*altura[0]):int(h*altura[1]), 
     int(w*largura[0]):int(w*largura[1])] 


cont = plt.contourf(a, origin='upper', cmap=cm.gist_earth, levels=numpy.arange(0,1000,20)) 
plt.title('Altitudes - max: %d m; min: %d m' % (numpy.amax(a), numpy.amin(a))) 
plt.show() 

co daje:

enter image description here

Problem polega na tym, że linie konturu są "biały" i generuje pewne zanieczyszczenie wizualne, co jest niepożądane, ponieważ chcę rysować drogi i rzeki później.

Tak, staram się zmienić sposób contourf tworzenia tych jaśniejszych linii, albo poprzez ustawienie parametru, lub poprzez włamania (zmiana kodu źródłowego), podobna do tej, proponowana tutaj:

How to format contour lines from Matplotlib

także , jeśli ktoś wie, jak wygenerować taką mapę w bardziej elegancki sposób, korzystając z innych bibliotek, byłbym bardzo wdzięczny za wskazówkę!

Dzięki za przeczytanie.

Odpowiedz

20

końcu znaleźć odpowiednie rozwiązanie do tego dawna problemem matplotlib (obecnie 2,0), co nie wymaga wiele połączeń do konturu lub rasteryzacja postać.

Należy zauważyć, że problem przedstawiony na pytaniu pojawia się tylko w zapisanych formatach liczb o jakości publikacji, takich jak PDF, a nie w plikach rastrowych niskiej jakości, takich jak PNG.

Moje rozwiązanie zostało zainspirowane odpowiedzią this, dotyczącą podobnego problemu z paskiem kolorów. Podobne rozwiązanie okazuje się rozwiązać wykresy liniowe, jak również, co następuje:

import numpy as np 
import matplotlib.pyplot as plt 

np.random.seed(123) 
x, y = np.random.uniform(size=(100, 2)).T 
z = np.exp(-x**2 - y**2) 
levels = np.linspace(0, 1, 100) 

cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean") 

# This is the fix for the white lines between contour levels 
for c in cnt.collections: 
    c.set_edgecolor("face") 

plt.savefig("test.pdf")  

Tu poniżej jest przykładem konturów przed fix

enter image description here

A tu poniżej jest taka sama figura po powyższa poprawka

enter image description here

+2

Cóż, oczywiście jest to teraz akceptowana odpowiedź, ponieważ wydaje się słusznie i nie-hackishly rozwiązać podstawowy problem. Dzięki za wysyłkę nawet po tak wiele czas !! – heltonbiker

+1

Dzięki @heltonbiker za aktualizację antage tego rozwiązania jest to, że nie zwiększa rozmiaru pliku i nie pogarsza jakości obrazu. – divenex

+1

Awesome! Czekałem na to i mam nadzieję, że nie zapomnę sprawdzić ulubionych postów następnym razem, kiedy tego potrzebuję;) –

3

Spróbuj dodać kw argrument do połączenia plt.contourf(...): albo lw=0 lub ls=None. http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.contourf

+0

zrobiłem, jak pan powiedział, a ja przypomniałem sobie próbując coś podobnego wcześniej, ale niestety to nie zadziałało. Podejrzewam, że te linie lightstroke mogą być w rzeczywistości problemem renderowania z powodu niewłaściwego wygładzania, ale skąd można wiedzieć? – heltonbiker

+0

Szczerze mówiąc, tak naprawdę nie wiem :-(Nieco zaskakujące jest to, że w tym przykładzie http://matplotlib.sourceforge.net/examples/pylab_examples/contourf_log.html nie ma tam linii. Gdybym był tobą, zacząłem od tego przykładu, aby zobaczyć, gdzie te linie zaczynają się pojawiać –

+0

Wow! Teraz to było zaskakujące, aby zobaczyć Czas na odrabianie lekcji teraz, jak tylko dostanę jakiś wynik, przyjdę wróć ze sprzężeniem zwrotnym Dziękujemy! – heltonbiker

5

heltonbiker, czy znalazłeś rozwiązanie swojego problemu? Przypadkowo natknąłem się na to pytanie i przez jakiś czas miałem ten sam problem. Próbowałem sugestii Zhenyi, jednak one też nie działają dla mnie. Rozwiązanie problemu, mimo że nie jest prawdziwym rozwiązaniem, ale bardziej obejściem problemu, jest proste: wystarczy powtórzyć to samo polecenie contourf, co spowoduje magiczne pozbywanie się fałszywych konturów.

Zgodnie z instrukcją operacyjną, kontury pozorne pojawiają się podczas wypełniania konturu (contourf) w odstępach zbyt blisko siebie. Możemy odtworzyć ten problem przez ustawienie bardzo dużą liczbę interwałów, np

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # 2001 intervals 

To daje nam jako wyjście:

enter image description here

Cienkie fałszywych konturów oczywiście wpływa na kolor netto konturu napełnić.

Jeśli do polecenia dwukrotnie:

plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # Not once, 
plt.contourf(plon,plat,ssh,np.arange(-1,1.001,0.001)) # but twice! 

daje mi:

enter image description here

teraz znacznie lepiej.Oto jeden z najlepszych, z 3 kolejnych contourf poleceń:

enter image description here

nie widzę żadnych cienkie kontury już! Niestety może to znacznie spowolnić twoje skrypty, w zależności od rozmiaru tablicy i liczby interwałów między konturami. Kontury pozorne wyróżniają się bardziej, jeśli zastosowano więcej interwałów między konturami. To, co zwykle działa najlepiej dla mnie, to użycie 50 do 100 interwałów międzykręgowych i dwukrotne wykonanie contourf.

Zauważ, że wersja matplotlib, której używam, nie jest najnowsza. Ten problem mógł zostać rozwiązany w wersji 1.1.0. Jeśli tak, proszę dać mi znać.

Python 2.7.1 |EPD 7.0-2 (32-bit)| (r271:86832, Nov 29 2010, 13:52:51) 
In [1]: matplotlib.__version__ 
Out[1]: '1.0.1' 
+0

Dziękuję bardzo za zainteresowanie starym pytaniem! Jestem prawie pewien, że problem jest związany z efektami aliasingu, a piksele nie mają "kolorowego koloru" na granicach. To bardzo odpowiada twojemu rozwiązaniu, ponieważ malowanie półprzezroczystych (lub pół-bezbarwnych) pikseli ma tendencję do "wypełniania ich" i nadawania im koloru. Nie mogę teraz wypróbować tej sugestii, ale na pewno zrobię to, gdy nadejdzie czas (moje wątki nie są tak gęste, aby mieć wygórowane problemy z wydajnością). Dzięki!! – heltonbiker

+0

(a szkoda, że ​​najnowsze wersje dystrybucji związanych z Ubuntu nadal używają Matplotlib 0.9 ...) – heltonbiker

+0

@heltonbiker To jest. Używam Enthought Python Distribution na Fedorze, RHEL i CentOS, i zdecydowanie polecam.Program matplotlib 1.1.0 jest dostępny wraz z wieloma innymi modułami zorientowanymi naukowo. Najwyraźniej nie używam najnowszej wersji EPD :). http://enthought.com/products/epd.php (nie jestem związany z Enthought) – milancurcic

Powiązane problemy