0% found this document useful (0 votes)
269 views

Python - Draw Polygons More Efficiently With Matplotlib - Stack Overflow

This document is a question posted on Stack Overflow asking how to draw polygons more efficiently in matplotlib. The top response recommends using PolygonCollections instead of individual polygons, which can speed up drawing thousands of shapes significantly. An example is provided showing how to create a PolygonCollection from longitude and latitude data and add it to a plot. The asker then updates saying they tried this approach and were able to draw 60,000 shapes in 32 seconds instead of the original 1.5 minutes.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
269 views

Python - Draw Polygons More Efficiently With Matplotlib - Stack Overflow

This document is a question posted on Stack Overflow asking how to draw polygons more efficiently in matplotlib. The top response recommends using PolygonCollections instead of individual polygons, which can speed up drawing thousands of shapes significantly. An example is provided showing how to create a PolygonCollection from longitude and latitude data and add it to a plot. The asker then updates saying they tried this approach and were able to draw 60,000 shapes in 32 seconds instead of the original 1.5 minutes.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

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

You might also like