Geopandas Polygon en patchs matplotlib Conversion de polygone

9

Malheureusement, le traçage des géopandas est extrêmement lent et prend beaucoup de ressources, donc je voudrais utiliser à la place matplotlib pour le traçage.

Lorsque j'utilise Fiona pur pour ouvrir et lire le fichier de formes, je n'ai aucun mal à extraire les polygones en tant que patchs matplotlib mais maintenant je voudrais utiliser comme point de départ le cadre de données geopandas pour obtenir mes polygones matplotlib.

J'utilise actuellement quelque chose comme:

with FI.open(df_map_elements, 'r') as layer:
    for element in layer:
        key = int(element['id'])
        if key not in dict_mapindex_mpl_polygon.keys():
            dict_mapindex_mpl_polygon[key]=[]
        for tp in element['geometry']['coordinates']:
            q = np.array(tp)
            polygon = Polygon(q) # matplotlib Polygon NOT Shapely

Pour tracer des polygones avec matplotlib:

from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
Philipp Schwarz
la source

Réponses:

8

Il y a un module Python pour ça: Descartes (regardez Plot shapefile avec matplotlib par exemple)

from geopandas import GeoDataFrame
test = GeoDataFrame.from_file('poly1.shp')
test.set_index('id', inplace=True)
test.sort()
test['geometry']
testid
0    POLYGON ((1105874.411110075 -6125459.381061088...
1    POLYGON ((1106076.359169902 -6125875.557806003...
2    POLYGON ((1106260.568548799 -6125410.258560049...
3    POLYGON ((1105747.511315724 -6125864.64169466,...
Name: geometry, dtype: object

Le type de la géométrie est un polygone galbé:

 type(test['geometry'][2])
 shapely.geometry.polygon.Polygon

Vous pouvez maintenant utiliser Descartes pour tracer directement un polygone bien fait

import matplotlib.pyplot as plt 
from descartes import PolygonPatch
BLUE = '#6699cc'
poly= test['geometry'][2]
fig = plt.figure() 
ax = fig.gca() 
ax.add_patch(PolygonPatch(poly, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2 ))
ax.axis('scaled')
plt.show()

entrez la description de l'image ici

gène
la source
3

Après la réponse simple et compréhensible, j'ai trouvé moi-même un moyen simple de tracer un shp entier avec matplotlib. Je pense que les géopandas devraient simplement mettre à jour leur fonction de traçage car celle-ci est simple mais tellement plus rapide, y compris la flexibilité totale de matplotlib - en ajoutant la légende, le titre, etc.

from descartes import PolygonPatch
import geopandas as gp
import pysal as ps
import numpy as np

# Import libraries for visualization
from matplotlib import pyplot as plt
from matplotlib.patches import Polygon as mpl_Polygon
from matplotlib.collections import PatchCollection

shapefile = 'raw_data/shapefile/yourshapefile.shp'
df_map_elements = gp.GeoDataFrame.from_file(shapefile)

df_map_elements["mpl_polygon"] = np.nan
df_map_elements['mpl_polygon'] = df_map_elements['mpl_polygon'].astype(object)
for self_index, self_row_df in df_map_elements.iterrows():
    m_polygon = self_row_df['geometry']
    poly=[]
    if m_polygon.geom_type == 'MultiPolygon':
        for pol in m_polygon:
            poly.append(PolygonPatch(pol))
    else:
        poly.append(PolygonPatch(m_polygon))
    df_map_elements.set_value(self_index, 'mpl_polygon', poly)

dict_mapindex_mpl_polygon = df_map_elements['mpl_polygon'].to_dict()

Et pour tracer:

fig, ax = plt.subplots()
for c_l ,patches in dict_mapindex_mpl_polygon.items():
    p = PatchCollection(patches,color='white',lw=.3,edgecolor='k')
    ax.add_collection(p)
ax.autoscale_view()

plt.show()

entrez la description de l'image ici

Philipp Schwarz
la source