Geopandas Polygon in Matplotlib-Patches Polygonkonvertierung


8

Leider ist das Plotten von Geopandas extrem langsam und erfordert viele Ressourcen. Daher möchte ich stattdessen matplotlib zum Plotten verwenden.

Wenn ich das Shapefile mit reinem Fiona öffne und lese, kann ich die Polygone problemlos als Matplotlib-Patches extrahieren. Jetzt möchte ich den Geopandas-Datenrahmen als Ausgangspunkt verwenden, um meine Matplotlib-Polygone abzurufen.

Ich benutze derzeit so etwas wie:

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

Zum Zeichnen von Polygonen mit Matplotlib:

from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection

Antworten:


7

Dafür gibt es ein Python-Modul: Descartes (siehe Plot-Shapefile mit matplotlib zum Beispiel)

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

Der Typ der Geometrie ist ein formschönes Polygon:

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

Jetzt können Sie mit Descartes ein formschönes Polygon direkt zeichnen

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()

Geben Sie hier die Bildbeschreibung ein


3

Nach der einfachen und verständlichen Antwort habe ich mir einen einfachen Weg ausgedacht, um einen ganzen Shp mit Matplotlib zu zeichnen. Ich bin der Meinung, Geopandas sollten nur ihre Plotfunktion aktualisieren, da diese einfach, aber viel schneller ist, einschließlich der vollen Flexibilität von matplotlib - Hinzufügen von Legenden, Titeln usw.

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()

Und zum Plotten:

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()

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.