python - Draw polygons more efficiently with matplotlib - Stack Overflow
1 de 5
http://stackoverflow.com/questions/12881848/draw-polygons-more-efficiently-with-matplotlib
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.
Draw polygons more efficiently with matplotlib
I have a dateset of around 60000 shapes (with lat/lon coordinates of each corner) which I want to draw on a map using matplotlib and
basemap.
This is the way I am doing it at the 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)
However, this takes around 1.5 minutes on my machine and I was thinking whether it is possible to speed things up a little. Is there a
more efficient way to draw polygons and add them to the map?
python
numpy
matplotlib
scipy
matplotlib-basemap
edited May 12 '13 at 21:40
Saullo Castro
19.3k
35
asked Oct 14 '12 at 11:37
HyperCube
87
911
26
01/10/2015 21:32
python - Draw polygons more efficiently with matplotlib - Stack Overflow
2 de 5
http://stackoverflow.com/questions/12881848/draw-polygons-more-efficiently-with-matplotlib
2 Answers
You could consider creating Collections of polygons instead of individual polygons.
The relevant docs can be found here: http://matplotlib.org/api/collections_api.html With a
example worth picking appart here: http://matplotlib.org/examples/api/collections_demo.html
As an example:
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.
#
#
#
z
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
= 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)
01/10/2015 21:32
python - Draw polygons more efficiently with matplotlib - Stack Overflow
3 de 5
http://stackoverflow.com/questions/12881848/draw-polygons-more-efficiently-with-matplotlib
plt.show()
HTH,
edited Oct 14 '12 at 16:30
Joe Kington
93.3k
13
12
answered Oct 14 '12 at 15:32
pelson
204
244
7,224
27
50
Hope it's alright that I added the example! Joe Kington Oct 14 '12 at 16:30
01/10/2015 21:32
python - Draw polygons more efficiently with matplotlib - Stack Overflow
4 de 5
http://stackoverflow.com/questions/12881848/draw-polygons-more-efficiently-with-matplotlib
Thx, nice example! I think PolyCollection is the key. However, I am confused how to turn my lons/lats into
polygons. In your case "verts". HyperCube Oct 15 '12 at 10:07
@JoeKington : Great addition. Unfortunately I will get the credit for all of your hard work... pelson Oct 15
'12 at 10:37
I adjusted my code and now it is working flawlessly :)
Here is the working example:
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)
answered Oct 16 '12 at 12:59
HyperCube
911
26
01/10/2015 21:32
python - Draw polygons more efficiently with matplotlib - Stack Overflow
5 de 5
http://stackoverflow.com/questions/12881848/draw-polygons-more-efficiently-with-matplotlib
Flawlessly and fast? How much time did you save from the original 1.5 minutes? pelson Oct 17 '12 at
18:15
Now it takes 32 seconds, so it really speeds thing up! HyperCube Oct 18 '12 at 18:40
what is m ? Adding the imports/definitions would be nice. Skylar Saveland Apr 30 '14 at 19:00
@SkylarSaveland m is a Basemap object(in module mpl_toolkits.basemap). It can convert longitude and
latitude into axes units for plotting a map. Sub Struct Aug 22 '14 at 10:45
01/10/2015 21:32