I use the following python function to plot in matplotlib geopandas geodataframes. This works very good with geodtaframes with 10000 - 20000 elements (also polygonal geometries) but with vectors with 80000 geometries it takes about two minutes to build the raster image, that is a very, very long period. QGIS, for example, is slower than my function for 10000-20000 geometries vectors but really faster with the biggest one. I cannot understand such a slump of performance.
Best regards and thank you for any kind of help and support. Michele Zucchelli.
def Get_raster_image_from_vector(fp, cmap, single_color = False, cmap_col = None, extent = None, plot_width = 800, plot_height = 500, gdf = None, set_extent = False):
#leggi il file con geopandas, se non viene già passato il geodataframe letto
#passare già il geodataframe letto permette di ridurre i tempi complessivi
if gdf is None:
gdf = gpd_read_file(fp)
if not extent: #se non viene passata un'estensione usa quella del file
bounds = gdf.total_bounds
xmin, ymin, xmax, ymax = bounds[0], bounds[1], bounds[2], bounds[3]
extent = (xmin, xmax, ymin, ymax)
else:
xmin, xmax, ymin, ymax = extent
# Creazione del Canvas con i limiti definiti dalla bounding box
canvas = ds.Canvas(plot_width=plot_width, plot_height=plot_height,
x_range=(xmin, xmax),
y_range=(ymin, ymax))
#ottieni il tipo di geometria
geometry_type = gdf.iloc[0].geometry.geom_type
first_row_title = gdf.columns[0]
if geometry_type in ["Polygon", "MultiPolygon"]:
if not single_color:
# Colorazione basata sui valori di una colonna con una colormap
agg = canvas.polygons(gdf, geometry="geometry", agg=ds.mean(cmap_col))
img = tf.shade(agg, cmap=cmap, how="linear")
else:
gdf['id_numerico'] = np.arange(1, len(gdf) + 1)
agg = canvas.polygons(gdf, geometry="geometry", agg=ds.mean('id_numerico'))#ds.count()
img = tf.shade(agg, cmap=cmap, how="linear")
print("immagine creata")
elif geometry_type in ["LineString", "MultiLineString"]:
if not single_color:
agg = canvas.line(gdf, geometry="geometry", agg=ds.max(cmap_col), line_width=2)
img = tf.shade(agg, cmap=cmap, how="linear")
else:
agg = canvas.line(gdf, geometry="geometry", agg=ds.count(), line_width=2)
img = tf.shade(agg, cmap=cmap, how="linear")
elif geometry_type in ["Point", "MultiPoint"]:
if not single_color:
agg = canvas.points(gdf, geometry="geometry", agg=ds.max(cmap_col))
img = tf.shade(agg, cmap=cmap, how="linear")
else:
agg = canvas.points(gdf, geometry="geometry", agg=ds.count())
img = tf.shade(agg, cmap=cmap, how="linear")
else:
raise ValueError("geometry type not recognized")
# Conversione dell'immagine Datashader in un array NumPy per Matplotlib
img_pil = img.to_pil()
img_np = np.array(img_pil)
return [img_np, fp, extent, set_extent]