2012-10-14 11 views
20

Mam zestaw dat z około 60000 kształtów (ze współrzędnymi długości/szerokości każdego rogu), które chcę narysować na mapie przy użyciu matplotlib i mapy bazowej.Narysuj wielokąty wydajniej z matplotlib

ten sposób robię to w tej chwili:

for ii in range(len(data)): 
    lons = np.array([data['lon1'][ii],data['lon3'][ii],data['lon4'][ii],data['lon2'][ii]],'f2') 
    lats = np.array([data['lat1'][ii],data['lat3'][ii],data['lat4'][ii],data['lat2'][ii]],'f2') 
    x,y = m(lons,lats) 
    poly = Polygon(zip(x,y),facecolor=colorval[ii],edgecolor='none') 
    plt.gca().add_patch(poly) 

Jednak ta trwa około 1,5 minuty na moim komputerze i myślałem, czy możliwe jest, aby przyspieszyć trochę. Czy istnieje skuteczniejszy sposób rysowania wielokątów i dodawania ich do mapy?

Odpowiedz

31

Można rozważyć utworzenie kolekcji wielokątów zamiast pojedynczych wielokątów.

odpowiednimi docs można znaleźć tutaj: http://matplotlib.org/api/collections_api.html Z przykładu warto zbieranie appart tutaj: http://matplotlib.org/examples/api/collections_demo.html

Jako przykład:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.collections import PolyCollection 
import matplotlib as mpl 

# Generate data. In this case, we'll make a bunch of center-points and generate 
# verticies by subtracting random offsets from those center-points 
numpoly, numverts = 100, 4 
centers = 100 * (np.random.random((numpoly,2)) - 0.5) 
offsets = 10 * (np.random.random((numverts,numpoly,2)) - 0.5) 
verts = centers + offsets 
verts = np.swapaxes(verts, 0, 1) 

# In your case, "verts" might be something like: 
# verts = zip(zip(lon1, lat1), zip(lon2, lat2), ...) 
# If "data" in your case is a numpy array, there are cleaner ways to reorder 
# things to suit. 

# Color scalar... 
# If you have rgb values in your "colorval" array, you could just pass them 
# in as "facecolors=colorval" when you create the PolyCollection 
z = np.random.random(numpoly) * 500 

fig, ax = plt.subplots() 

# Make the collection and add it to the plot. 
coll = PolyCollection(verts, array=z, cmap=mpl.cm.jet, edgecolors='none') 
ax.add_collection(coll) 
ax.autoscale_view() 

# Add a colorbar for the PolyCollection 
fig.colorbar(coll, ax=ax) 
plt.show() 

enter image description here

HTH,

+13

nadzieję, że to w porządku, że dodałem przykład! –

+0

Thx, ładny przykład! Myślę, że PolyCollection jest kluczem. Jednak jestem zdezorientowany, jak włączyć moje lony/łaty w wielokątów. W twoim przypadku "wersety". – HyperCube

+0

@JoeKington: Świetny dodatek. Niestety dostanę za ciebie całą ciężką pracę ... – pelson

3

I dostosowałem mój kod i teraz działa bezbłędnie :)

Oto przykład praca:

lons = np.array([data['lon1'],data['lon3'],data['lon4'],data['lon2']]) 
lats = np.array([data['lat1'],data['lat3'],data['lat4'],data['lat2']]) 
x,y = m(lons,lats) 
pols = zip(x,y) 
pols = np.swapaxes(pols,0,2) 
pols = np.swapaxes(pols,1,2) 
coll = PolyCollection(pols,facecolor=colorval,cmap=jet,edgecolor='none',zorder=2) 
plt.gca().add_collection(coll) 
+3

Bezbłędnie i szybko? Ile czasu udało ci się zaoszczędzić od oryginalnego 1,5 minuty? – pelson

+3

Teraz zajmuje to 32 sekundy, więc naprawdę przyspiesza sprawę! – HyperCube

+2

co to jest 'm'? Dodanie importu/definicji byłoby miłe. –