web-dev-qa-db-fra.com

Dessinez des polygones plus efficacement avec matplotlib

J'ai un ensemble de dates d'environ 60000 formes (avec les coordonnées lat/lon de chaque coin) que je veux dessiner sur une carte en utilisant matplotlib et fond de carte.

Voici comment je le fais en ce moment:

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)

Cependant, cela prend environ 1,5 minute sur ma machine et je me demandais s'il était possible d'accélérer un peu les choses. Existe-t-il un moyen plus efficace de dessiner des polygones et de les ajouter à la carte?

22
HyperCube

Vous pouvez envisager de créer des collections de polygones au lieu de polygones individuels.

Les documents pertinents peuvent être trouvés ici: http://matplotlib.org/api/collections_api.html Avec un exemple à choisir ici: http://matplotlib.org/examples/ api/collections_demo.html

Par exemple:

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,

35
pelson

J'ai ajusté mon code et maintenant il fonctionne parfaitement :)

Voici l'exemple de travail:

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
HyperCube