Path: blob/main/tools/contributed/sumopy/plugins/prt/results_mpl.py
169689 views
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo1# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.2# SUMOPy module3# Copyright (C) 2012-2021 University of Bologna - DICAM4# This program and the accompanying materials are made available under the5# terms of the Eclipse Public License 2.0 which is available at6# https://www.eclipse.org/legal/epl-2.0/7# This Source Code may also be made available under the following Secondary8# Licenses when the conditions for such availability set forth in the Eclipse9# Public License 2.0 are satisfied: GNU General Public License, version 210# or later which is available at11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1314# @file results_mpl.py15# @author Joerg Schweizer16# @date 20121718import os19import numpy as np20from collections import OrderedDict21import matplotlib as mpl22from matplotlib.patches import Arrow, Circle, Wedge, Polygon, FancyArrow23from matplotlib.collections import PatchCollection24import matplotlib.colors as colors25import matplotlib.cm as cmx26import matplotlib.pyplot as plt27import matplotlib.image as image2829import agilepy.lib_base.classman as cm30import agilepy.lib_base.arrayman as am31from agilepy.lib_base.geometry import *32from agilepy.lib_base.processes import Process3334COLORS = ['#1f77b4', '#aec7e8', '#ff7f0e', '#ffbb78', '#2ca02c',35'#98df8a', '#d62728', '#ff9896', '#9467bd', '#c5b0d5',36'#8c564b', '#c49c94', '#e377c2', '#f7b6d2', '#7f7f7f',37'#c7c7c7', '#bcbd22', '#dbdb8d', '#17becf', '#9edae5']383940class StopresultsPlotter(Process):41def __init__(self, results, name='Plot PRT stop results with Matplotlib',42info="Creates plots of PRT stop results using matplotlib",43logger=None, **kwargs):4445self._init_common('stopresultsplotter', parent=results, name=name,46info=info, logger=logger)4748print 'StopresultsPlotter.__init__', results, self.parent, len(self.get_stopresults())49attrsman = self.get_attrsman()5051stops = self.get_stopresults().get_prtstops()52choices_stop = {}53for id_stop in stops.get_ids():54choices_stop[str(id_stop)] = id_stop5556self.id_stop_plot = attrsman.add(cm.AttrConf('id_stop_plot', kwargs.get('id_stop_plot', stops.get_ids()[0]),57groupnames=['options'],58choices=choices_stop,59name='ID stop plot',60info='Plot results of PRT stop with this ID.',61))6263self.is_title = attrsman.add(cm.AttrConf('is_title', kwargs.get('is_title', False),64groupnames=['options'],65name='Show title',66info='Show title of diagrams.',67))6869self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont', 32),70groupnames=['options'],71name='Title fontsize',72info='Title fontsize.',73))7475self.size_labelfont = attrsman.add(cm.AttrConf('size_labelfont', kwargs.get('size_labelfont', 24),76groupnames=['options'],77name='Label fontsize',78info='Label fontsize.',79))8081self.width_line = attrsman.add(cm.AttrConf('width_line', kwargs.get('width_line', 2),82groupnames=['options'],83perm='wr',84name='Line width',85info='Width of plotted lines.',86))8788self.color_line = attrsman.add(cm.AttrConf('color_line', kwargs.get('color_line', np.array([0, 0, 1, 1], dtype=np.float32)),89groupnames=['options'],90perm='wr',91metatype='color',92name='Line color',93info='Color of line in various diagrams.',94))9596self.printformat = attrsman.add(cm.AttrConf('printformat', kwargs.get('printformat', '%.1f'),97choices=OrderedDict([98('Show no values', ''),99('x', '%.d'),100('x.x', '%.1f'),101('x.xx', '%.2f'),102('x.xxx', '%.3f'),103('x.xxxx', '%.4f'),104]),105groupnames=['options'],106name='Label formatting',107info='Print formatting of value label in graphical representation.',108))109110self.color_label = attrsman.add(cm.AttrConf('color_label', kwargs.get('color_label', np.array([0, 0, 0, 1], dtype=np.float32)),111groupnames=['options'],112perm='wr',113metatype='color',114name='Label color',115info='Color of value label in graphical representation.',116))117118self.is_grid = attrsman.add(cm.AttrConf('is_grid', kwargs.get('is_grid', True),119groupnames=['options'],120name='Show grid?',121info='If True, shows a grid on the graphical representation.',122))123self.color_background = attrsman.add(cm.AttrConf('color_background', kwargs.get('color_background', np.array([1, 1, 1, 1], dtype=np.float32)),124groupnames=['options'],125perm='wr',126metatype='color',127name='Background color',128info='Background color of schematic network in the background.',129))130131def get_stopresults(self):132return self.parent.prtstopresults133134def show(self):135stopresults = self.get_stopresults()136print 'show', stopresults137# print ' dir(vehicleman)',dir(vehicleman)138139print ' len(stopresults)', len(stopresults)140if len(stopresults) > 0:141i_fig = 0142plt.close("all")143144#i_fig +=1;fig = plt.figure(i_fig)145# self.plot_waiting_person(fig)146147i_fig += 1148fig = plt.figure(i_fig)149self.plot_waiting_person_number(fig)150151#i_fig +=1;fig = plt.figure(i_fig)152# self.plot_waiting_person_time(fig)153154i_fig += 1155fig = plt.figure(i_fig)156self.plot_waiting_person_number_stop(fig)157158i_fig += 1159fig = plt.figure(i_fig)160self.plot_flow_stop(fig)161162#i_fig +=1;fig = plt.figure(i_fig)163# self.plot_flows_compare(fig)164165#i_fig +=1;fig = plt.figure(i_fig)166# self.plot_flows_compare_stop(fig)167168plt.show()169170def plot_flow_stop(self, fig):171print 'plot_flow_stop'172id_stop = self.id_stop_plot173stopresults = self.get_stopresults()174ax = fig.add_subplot(111)175176n_stop, n_steps = stopresults.get_dimensions()177t_step = stopresults.time_step.get_value()178179time = np.arange(n_steps, dtype=np.float32)*t_step180i = 0181182flow_veh_av = np.mean(stopresults.inflows_veh[id_stop])*3600183flow_pers_av = np.mean(stopresults.inflows_person[id_stop])*3600184185ax.plot(time, stopresults.inflows_veh[id_stop]*3600,186label='Effective vehicle',187color='b',188linestyle='--', linewidth=self.width_line,189marker='s', markersize=4*self.width_line,190)191192ax.plot(time, stopresults.inflows_veh_sched[id_stop]*3600,193label='Scheduled vehicle',194color='c',195linestyle=':', linewidth=self.width_line,196marker='^', markersize=4*self.width_line,197)198199ax.plot(time, stopresults.inflows_person[id_stop]*3600,200label='Effective pers.',201color='g',202linestyle='-', linewidth=self.width_line,203marker='o', markersize=4*self.width_line,204)205206ax.plot([time[0], time[-1]], [flow_veh_av, flow_veh_av],207label='Average vehicle',208color='fuchsia',209linestyle='-', linewidth=2*self.width_line,210)211212ax.plot([time[0], time[-1]], [flow_pers_av, flow_pers_av],213label='Average person',214color='darkorange',215linestyle='-', linewidth=2*self.width_line,216)217218ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)219ax.grid(self.is_grid)220if self.is_title:221ax.set_title('Vehicle and person in-flows over time at PRT stop ID=%d' %222id_stop, fontsize=self.size_titlefont)223ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)224ax.set_ylabel('In-flows [1/h]', fontsize=self.size_labelfont)225ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))226ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))227228def plot_waiting_person_time(self, fig):229print 'plot_waiting_person_time'230stopresults = self.get_stopresults()231ax = fig.add_subplot(111)232233n_stop, n_steps = stopresults.get_dimensions()234t_step = stopresults.time_step.get_value()235#inds_stop = np.arange(n_stop, dtype = np.int32)236time = np.arange(n_steps, dtype=np.float32)*t_step237# works:ax.plot(time.reshape(n_steps,1),numbers_person_wait.reshape(n_steps,-1))238i = 0239for id_stop in stopresults.ids_stop.get_value():240ax.plot(time, 1.0/60.0*stopresults.waittimes_tot[id_stop],241COLORS[i], linewidth=self.width_line,242label='PRT Stop ID=%d' % id_stop)243i += 1244245if self.is_title:246ax.set_title('Number of waiting persons over time', fontsize=self.size_titlefont)247248ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)249ax.grid(self.is_grid)250ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)251ax.set_ylabel('Waiting times of passengers [min]', fontsize=self.size_labelfont)252ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))253ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))254255def plot_waiting_person_number_stop(self, fig):256print 'plot_waiting_person_number_stop'257stopresults = self.get_stopresults()258#ax1 = fig.add_subplot(211)259#ax2 = fig.add_subplot(212)260ax = fig.add_subplot(111)261262n_stop, n_steps = stopresults.get_dimensions()263t_step = stopresults.time_step.get_value()264#inds_stop = np.arange(n_stop, dtype = np.int32)265time = np.arange(n_steps, dtype=np.float32)*t_step266# works:ax.plot(time.reshape(n_steps,1),numbers_person_wait.reshape(n_steps,-1))267id_stop = self.id_stop_plot268ax.plot(time, stopresults.numbers_person_wait[id_stop],269'g', linewidth=self.width_line,270label='PRT Stop ID=%d' % id_stop)271272ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)273ax.grid(self.is_grid)274ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)275ax.set_ylabel('Number of waiting passengers', fontsize=self.size_labelfont)276ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))277ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))278279def plot_waiting_person_number(self, fig):280print 'plot_waiting_person_number'281stopresults = self.get_stopresults()282#ax1 = fig.add_subplot(211)283#ax2 = fig.add_subplot(212)284ax = fig.add_subplot(111)285286n_stop, n_steps = stopresults.get_dimensions()287t_step = stopresults.time_step.get_value()288#inds_stop = np.arange(n_stop, dtype = np.int32)289time = np.arange(n_steps, dtype=np.float32)*t_step290# works:ax.plot(time.reshape(n_steps,1),numbers_person_wait.reshape(n_steps,-1))291i = 0292for id_stop in stopresults.ids_stop.get_value():293print ' id_stop', id_stop294ax.plot(time, stopresults.numbers_person_wait[id_stop],295COLORS[i], linewidth=self.width_line,296label='PRT Stop ID=%d' % id_stop)297i += 1298299ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)300ax.grid(self.is_grid)301ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)302ax.set_ylabel('Number of waiting passengers', fontsize=self.size_labelfont)303ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))304ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))305306def plot_flows_compare(self, fig):307print 'plot_flows_compare'308stopresults = self.get_stopresults()309#time_update_flows = self.parent.vehicleman.time_update_flows.get_value()310time_update_flows = 10311ax = fig.add_subplot(111)312313n_stop, n_steps = stopresults.get_dimensions()314t_step = stopresults.time_step.get_value()315316time = np.arange(n_steps, dtype=np.float32)*t_step317i = 0318flowmatrix = np.zeros((10, 10), dtype=np.int32)319for id_stop in stopresults.ids_stop.get_value():320print ' id_stop', id_stop321# print ' sched',stopresults.inflows_veh_sched[id_stop]322# print ' eff ',stopresults.inflows_veh[id_stop]323flowmatrix[np.array(time_update_flows*stopresults.inflows_veh_sched[id_stop], dtype=np.int32),324np.array(time_update_flows*stopresults.inflows_veh[id_stop], dtype=np.int32)] += 1325# ax.plot(stopresults.inflows_veh_sched[id_stop]*3600,stopresults.inflows_veh[id_stop]*3600,326# COLORS[i],linewidth =self.width_line,327# label = 'PRT Stop ID=%d (effective)'%id_stop)328329i += 1330print 'flowmatrix', flowmatrix331# ax.matshow(flowmatrix)332333cax = ax.matshow(flowmatrix, cmap=cmx.get_cmap('PuBu'))334cbar = fig.colorbar(cax)335#ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)336ax.grid(self.is_grid)337ax.set_xlabel('Scheduled arrivals per interval', fontsize=self.size_labelfont)338ax.set_ylabel('Effective arrivals per interval', fontsize=self.size_labelfont)339ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))340ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))341342def plot_flows_compare_stop(self, fig):343print 'plot_flows_compare_stop'344stopresults = self.get_stopresults()345id_stop = self.id_stop_plot346#time_update_flows = self.parent.vehicleman.time_update_flows.get_value()347time_update_flows = 10348ax = fig.add_subplot(111)349350n_stop, n_steps = stopresults.get_dimensions()351t_step = stopresults.time_step.get_value()352353i = 0354flows_sched = stopresults.inflows_veh_sched[id_stop]355flows_eff = stopresults.inflows_veh[id_stop]356357x = flows_sched # -np.mean(flows_sched)358y = flows_eff # -np.mean(flows_eff)359flowcorr = np.correlate(x, y, 'full')/np.sqrt(np.sum(x*x)*np.sum(y*y))360361time = np.arange(-n_steps+1, n_steps, dtype=np.float32)*t_step362363print ' len(flowcorr),n_steps', len(flowcorr), len(time), n_steps364365ax.plot(time, flowcorr,366COLORS[i], linewidth=self.width_line,367label='PRT Stop ID=%d' % id_stop)368369ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)370ax.grid(self.is_grid)371ax.set_xlabel('Time delay [s]', fontsize=self.size_labelfont)372ax.set_ylabel('Cross-Correlation', fontsize=self.size_labelfont)373ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))374ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))375376def plot_flows(self, fig):377print 'plot_flows'378stopresults = self.get_stopresults()379ax = fig.add_subplot(111)380381n_stop, n_steps = stopresults.get_dimensions()382t_step = stopresults.time_step.get_value()383384time = np.arange(n_steps, dtype=np.float32)*t_step385i = 0386for id_stop in stopresults.ids_stop.get_value():387ax.plot(time, stopresults.inflows_veh[id_stop]*3600,388COLORS[i], linewidth=self.width_line,389label='PRT Stop ID=%d (effective)' % id_stop)390391ax.plot(time, stopresults.inflows_veh_sched[id_stop]*3600,392COLORS[i], linestyle='--', linewidth=self.width_line,393label='PRT Stop ID=%d (scheduled)' % id_stop)394395ax.plot(time, stopresults.inflows_person[id_stop]*3600,396COLORS[i], linestyle=':', linewidth=self.width_line,397label='PRT Stop ID=%d (person)' % id_stop)398399i += 1400401ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)402ax.grid(self.is_grid)403ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)404ax.set_ylabel('In-flows [1/h]', fontsize=self.size_labelfont)405ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))406ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))407408#('inflows_veh', {'name':'Vehicle in-flows', 'unit':'1/s', 'dtype':np.float32, 'info':'Vehicle flow into the stop over time.'}),409# ('inflows_veh_sched', {'name':'Sched. vehicle in-flows', 'unit':'1/s', 'dtype':np.float32, 'info':'Scheduled vehicle flow into the stop over time.'}),410# ('inflows_person', {'name':'Person in-flows', 'unit':'1/s', 'dtype':np.float32, 'info':'Person flow into the stop over time.'}),411412def plot_waiting_person(self, fig):413print 'plot_waiting_person'414stopresults = self.get_stopresults()415ax1 = fig.add_subplot(211)416ax2 = fig.add_subplot(212)417#ax = fig.add_subplot(111)418419n_stop, n_steps = stopresults.get_dimensions()420t_step = stopresults.time_step.get_value()421#inds_stop = np.arange(n_stop, dtype = np.int32)422time = np.arange(n_steps, dtype=np.float32)*t_step423# works:ax.plot(time.reshape(n_steps,1),numbers_person_wait.reshape(n_steps,-1))424i = 0425for id_stop in stopresults.ids_stop.get_value():426ax1.plot(time, stopresults.numbers_person_wait[id_stop],427COLORS[i], linewidth=self.width_line,428label='PRT Stop ID=%d' % id_stop)429ax2.plot(time, 1.0/60.0*stopresults.waittimes_tot[id_stop],430COLORS[i], linewidth=self.width_line,431label='PRT Stop ID=%d' % id_stop)432i += 1433434ax1.legend(loc='best', shadow=True, fontsize=14)435ax1.grid(self.is_grid)436ax1.set_xlabel('Time [s]', fontsize=14)437ax1.set_ylabel('Number of waiting passengers', fontsize=14)438ax1.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))439ax1.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))440441ax2.legend(loc='best', shadow=True, fontsize=14)442ax2.grid(self.is_grid)443ax2.set_xlabel('Time [s]', fontsize=14)444ax2.set_ylabel('Waiting times of passengers [min]', fontsize=14)445ax2.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))446ax2.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))447448def do(self):449# print 'do',self.edgeattrname450self.show()451return True452453def get_scenario(self):454return self._scenario455456457