Source code for dhd.plot

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt
import matplotlib


[docs]class Plot: """ Class to define a visual interface representing the city and its constituent geometries. Parameters ---------- streets: DataFrame, optional Dataframe of the streets network with a 'geometry' column. Default is None. buildings: DataFrame, optional Dataframe of all the city buildings with a 'geometry' column. Default is None. sources: DataFrame, optional Dataframe of the heating source(s) with a 'geometry' column. Default is None. barriers: DataFrame, optional Dataframe of the natural barriers with a 'geometry' column. Default is None. figsize: tuple Size of the figure framework. Default is *figsize* = (9,6). """ def __init__( self, streets=None, buildings=None, sources=None, barriers=None, figsize=(9, 6) ): self.streets = self.init_streets(streets) self.buildings = self.init_buildings(buildings) self.sources = self.init_sources(sources) self.barriers = self.init_barriers(barriers) self.fig, self.ax = plt.subplots(figsize=figsize) self.plot()
[docs] def init_streets(self, streets): """ Initilization of the streets geodataframe if *streets* is not None. Parameters ---------- streets: DataFrame Dataframe of the streets network with a 'geometry' column. Returns ------- GeoDataFrame Geodataframe of the streets network. """ if streets is None: return None else: return gpd.GeoDataFrame(streets)
[docs] def init_buildings(self, buildings): """ Initilization of the buildings geodataframe if *buildings* is not None. Parameters ---------- buildings: DataFrame Dataframe of the buildings with a 'geometry' column. Returns ------- GeoDataFrame Geodataframe of the buildings. """ if buildings is None: return None else: return gpd.GeoDataFrame(buildings)
[docs] def init_sources(self, sources): """ Initilization of the sources geodataframe if *sources* is not None. Parameters ---------- sources: DataFrame Dataframe of the sources with a 'geometry' column. Returns ------- GeoDataFrame Geodataframe of the sources. """ if sources is None: return None else: return gpd.GeoDataFrame(sources)
[docs] def init_barriers(self, barriers): """ Initilization of the barriers geodataframe if *barriers* is not None. Parameters ---------- barriers: DataFrame Dataframe of the barriers with a 'geometry' column. Returns ------- GeoDataFrame Geodataframe of the barriers. """ if barriers is None: return None else: return gpd.GeoDataFrame(barriers)
[docs] def reset_sources(self, sources): """ Reset the class attribute *sources*. Parameters ---------- sources: DataFrame Dataframe of the sources with a 'geometry' column. """ self.sources = gpd.GeoDataFrame(sources)
[docs] def reset_barriers(self, barriers): """ Reset the class attribute *barriers*. Parameters ---------- barriers: DataFrame Dataframe of the barriers with a 'geometry' column. """ self.barriers = gpd.GeoDataFrame(barriers)
[docs] def get_main_handles(self): """ List the handles of the background geometries of the city for the interface legends. Returns ------- list List of legend handles. """ handles = ( matplotlib.patches.Patch( color=plt.cm.tab10(5), label="buildings", alpha=0.8 ), matplotlib.lines.Line2D( [], [], color="gray", linewidth=1, label="streets", alpha=0.8 ), matplotlib.lines.Line2D( [], [], color=plt.cm.tab10(3), linewidth=1, Linestyle="--", alpha=0.8, label="natural barriers", ), matplotlib.lines.Line2D( [], [], color="black", marker="X", Linestyle="None", label="source(s)", alpha=0.8, ), ) return handles
[docs] def plot(self, loc="lower right"): """ Plot the background geometries of the city which are provided. """ if self.buildings is not None: self.buildings.plot(ax=self.ax, color=plt.cm.tab10(5), alpha=0.8) if self.streets is not None: self.streets.plot(ax=self.ax, linewidth=1, color="gray", alpha=0.8) if self.sources is not None: self.sources.plot( ax=self.ax, color="black", marker="X", markersize=30, alpha=0.8 ) if self.barriers is not None: self.barriers.plot( ax=self.ax, color=plt.cm.tab10(3), Linestyle="--", linewidth=1, alpha=0.8, ) self.ax.axis("off") legend = plt.legend(handles=self.get_main_handles(), loc=loc) self.ax.add_artist(legend) plt.tight_layout()
[docs] def clear(self): """ Clear all the objects on the interface. """ self.ax.clear()
[docs] def reset(self, loc="lower right"): """ Reset the interface with only the background geometries. """ self.clear() self.plot(loc=loc)
[docs] def get_handles(self, colors, labels, type): """ Obtain the legend handles for the list of colors and labels. Parameters ---------- colors: list List of colors. labels: list List of labels. type: string Type of legend handle. It may be 'pach', 'line' or 'point.' Returns ------- list List of legend handles. """ if type == "patch": handles = [ matplotlib.patches.Patch(color=color, label=label) for color, label in zip(colors, labels) ] elif type == "line": handles = [ matplotlib.lines.Line2D([], [], color=color, label=label) for color, label in zip(colors, labels) ] elif type == "point": handles = [ matplotlib.lines.Line2D( [], [], color=color, label=label, marker="o", markersize=5, Linestyle="None", ) for color, label in zip(colors, labels) ] else: text = "type must either be 'patch', 'point' or 'line'." raise TypeError(text) return handles
[docs] def add_geodataframe(self, gdf, kwargs={'color':'C1'}, centroid=False): """ Add the geometries of the geodataframe *gdf* to the interface. Parameters ---------- gdf: GeoDataFrame Geodataframe of the objects to represent visually. kwargs: dict, optional Arguments of the geopandas plot function. Default is {'color':'C1'}. centroid: bool If True only the centroid of the geometries is represented. """ if centroid is True: gdf = gdf["geometry"].centroid gdf.plot(ax=self.ax, **kwargs)
[docs] def add_legend(self, colors, labels, type, loc="best"): """ Add a legend to the interface. Parameters ---------- colors: list List of colors. labels: list List of labels. type: string Type of legend handle. It may be 'pach', 'line' or 'point'. loc: tuple, optional Location of the legend box. Default is *loc* = (0,1). """ handles = self.get_handles(colors, labels, type) legend = plt.legend(handles=handles, loc=loc) self.ax.add_artist(legend)