def plot_count_diff(self, *, ax=None, save_fig=None, **kwargs): f, ax = check_ax(ax, **kwargs) ax.set_title("Node Count over Time", **self.font_dict["title"]) ax.set_xlabel("Time [s]", **self.font_dict["xlabel"]) ax.set_ylabel("Pedestrian Count", **self.font_dict["ylabel"]) _i = pd.IndexSlice nodes = (self.map.loc[_i[:], _i["count"]].groupby( level=[self.tsc_id_idx_name, self.tsc_time_idx_name ]).sum().groupby(level="simtime").mean()) nodes_std = (self.map.loc[_i[:], _i["count"]].groupby( level=[self.tsc_id_idx_name, self.tsc_time_idx_name ]).sum().groupby(level="simtime").std()) glb = self.glb_map.groupby(level=self.tsc_time_idx_name).sum()["count"] ax.plot(nodes.index, nodes, label="Mean count") ax.fill_between( nodes.index, nodes + nodes_std, nodes - nodes_std, alpha=0.35, interpolate=True, label="Count +/- 1 std", ) ax.plot(glb.index, glb, label="Actual count") f.legend() if save_fig is not None: f.savefig(save_fig) return f, ax
def plot_area( self, time_step, node_id, value, *, ax=None, pcolormesh_dict: dict = None, fig_dict: dict = None, ax_prop: dict = None, **kwargs, ): """ Birds eyes view of density in a 2D color mesh with X/Y spanning the area under observation. Z axis (density) is shown with given color grading. Default data view: per node / per time / all cells """ df = self.update_area(time_step, node_id, value) f, ax = check_ax(ax, **fig_dict if fig_dict is not None else {}) cell = self.get_location(time_step, node_id, cell_id=False) if "title" in kwargs: ax.set_title(kwargs["title"], **self.font_dict["title"]) else: ax.set_title( f"Area plot of '{value}'. node: {node_id} time: " f"{time_step} cell [{cell[0]}, {cell[1]}]", **self.font_dict["title"], ) ax.set_aspect("equal") ax.tick_params(axis="x", labelsize=self.font_dict["tick_size"]) ax.tick_params(axis="y", labelsize=self.font_dict["tick_size"]) # if self.scenario_plotter is not None: # self.scenario_plotter.add_obstacles(ax) _d = update_dict(pcolormesh_dict, shading="flat") pcm = ax.pcolormesh(self.meta.X_flat, self.meta.Y_flat, df, **_d) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) cax.set_label("colorbar") cax.tick_params(axis="y", labelsize=self.font_dict["tick_size"]) f.colorbar(pcm, cax=cax) ax.update(ax_prop if ax_prop is not None else {}) return f, ax
def plot_delay_over_distance( self, time_step, node_id, value, remove_null=True, label=None, *, ax: plt.Axes = None, fig_dict: dict = None, ax_prop: dict = None, **kwargs, ): """ Plot delay_kind* over the distance between measurements location (cell) and the position of the map owner. Default data view: per node / per time / all cells *)delay_kind: change definition of delay using the delay_kind parameter. one of: ["delay", "measurement_age", "update_age"] """ f, ax = check_ax(ax, **fig_dict if fig_dict is not None else {}) df = self.update_delay_over_distance(time_step, node_id, value, remove_null=remove_null, line=None, **kwargs) if label is None: label = value ax.plot("owner_dist", value, data=df, label=label) ax_prop = {} if ax_prop is None else ax_prop ax_prop.setdefault( "title", f"Delay({value}) over Distance", ) ax_prop.setdefault("xlabel", "Cell distance (euklid) to owners location [m]") ax_prop.setdefault("ylabel", "Delay in [s]") ax.lines[0].set_linestyle("None") ax.lines[0].set_marker("o") self.apply_ax_props(ax, ax_prop) return f, ax
def plot_count(self, *, ax=None, **kwargs): f, ax = check_ax(ax, **kwargs) ax.set_title("Total node count over time", **self.font_dict["title"]) ax.set_xlabel("time [s]", **self.font_dict["xlabel"]) ax.set_ylabel("total node count", **self.font_dict["ylabel"]) for _id, df in self.iter_nodes_d2d(first=1): df_time = df.groupby(level=self.tsc_time_idx_name).sum() ax.plot(df_time.index, df_time["count"], label=f"{_id}") g = self.glb_map.groupby(level=self.tsc_time_idx_name).sum() ax.plot( g.index.get_level_values(self.tsc_time_idx_name), g["count"], label=f"0", ) ax.legend() return f, ax
def plot_error_over_distance( self, time_step, node_id, value, label=None, *, ax=None, fig_dict: dict = None, ax_prop: dict = None, **kwargs, ): f, ax = check_ax(ax, **fig_dict if fig_dict is not None else {}) df = self.update_error_over_distance(time_step, node_id, value, line=None, **kwargs) if label is None: label = value ax.plot("owner_dist", value, data=df, label=label) ax_prop = {} if ax_prop is None else ax_prop ax_prop.setdefault( "title", f"Error({value}) over Distance", ) ax_prop.setdefault("xlabel", "Cell distance (euklid) to owners location [m]") ax_prop.setdefault("ylabel", f"{value}") ax.lines[0].set_linestyle("None") ax.lines[0].set_marker("o") self.apply_ax_props(ax, ax_prop) return f, ax
def plot_location_map(self, time_step, *, ax=None, add_legend=True): places = self.own_cell() _i = pd.IndexSlice places = places.loc[ _i[:, time_step], :] # select only the needed timestep f, ax = check_ax(ax) ax.set_title(f"Node Placement at time {time_step}s") ax.set_aspect("equal") ax.set_xlim([0, self.meta.x_dim]) ax.set_ylim([0, self.meta.y_dim]) if self.scenario_plotter is not None: self.scenario_plotter.add_obstacles(ax) for _id, df in places.groupby(level=self.tsc_id_idx_name): # move coordinate for node :id: to center of cell. df = df + 0.5 * self.meta.cell_size ax.scatter(df["x"], df["y"], label=f"{_id}") if add_legend: ax.legend(bbox_to_anchor=(1.05, 1), loc="upper left") return f, ax