In [1]:
import geopandas as gpd, numpy as np, matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from descartes import PolygonPatch
from shapely.geometry import Point
%matplotlib inline
In [2]:
# create a geopandas GeoDataFrame with 10,000 random points
n = 10000
np.random.seed(1)
x = np.random.random(n)
y = np.random.random(n)
points = [Point(xy) for xy in zip(x, y)]
gdf = gpd.GeoDataFrame({'geometry':points})
gdf.head()
Out[2]:
In [3]:
# this is painfully slow
gdf.plot()
plt.show()
In [4]:
# instead, extract coordinates into separate numpy arrays...
xy = gdf['geometry'].map(lambda point: point.xy)
x, y = zip(*xy)
# ...and then scatter plot with a single call to matplotlib
fig, ax = plt.subplots(figsize=(5,5))
ax.scatter(x=x, y=y, s=2, color='#3399cc', linewidth=0, alpha=0.7)
ax.set_xlim((0,1))
ax.set_ylim((0,1))
plt.show()
In [5]:
def plot1(gdf):
gdf.plot()
plt.close()
%timeit plot1(gdf)
In [6]:
def plot2(gdf):
xy = gdf['geometry'].map(lambda point: point.xy)
x, y = zip(*xy)
fig, ax = plt.subplots()
ax.scatter(x=x, y=y)
plt.close()
%timeit plot2(gdf)
In [7]:
# take the first 1,000 points and turn them into polygons
gdf_polygons = gpd.GeoDataFrame(gdf.head(1000).copy())
gdf_polygons['geometry'] = gdf_polygons['geometry'].buffer(0.1)
gdf_polygons.head()
Out[7]:
In [8]:
# this is painfully slow
gdf_polygons.plot()
plt.show()
In [9]:
# instead, extract each polygon as a descartes patch, and add to a matplotlib patch collection...
# note, this code assumes all geometries are Polygons - if you have MultiPolygons, handle separately
patches = [PolygonPatch(geometry) for geometry in gdf_polygons['geometry']]
pc = PatchCollection(patches, facecolor='#3399cc', linewidth=1, alpha=0.1)
fig, ax = plt.subplots(figsize=(5,5))
ax.add_collection(pc)
# ...then set the figure bounds to the polygons' bounds
left, bottom, right, top = gdf_polygons.total_bounds
ax.set_xlim((left,right))
ax.set_ylim((bottom,top))
plt.show()
In [10]:
def plot_polygons1(gdf_polygons):
gdf_polygons.plot()
plt.close()
%timeit plot_polygons1(gdf_polygons)
In [11]:
def plot_polygons2(gdf_polygons):
patches = [PolygonPatch(geometry) for geometry in gdf_polygons['geometry']]
pc = PatchCollection(patches, facecolor='#3399cc', linewidth=0.2, alpha=0.3)
fig, ax = plt.subplots(figsize=(5,5))
ax.add_collection(pc)
plt.close()
%timeit plot_polygons2(gdf_polygons)
The first technique plots 1,000 polygons in about 2 seconds, the latter takes about 330 milliseconds.
In [ ]: