Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/plugins/mapmatching/results_mpl.py
169689 views
1
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
2
# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
3
# SUMOPy module
4
# Copyright (C) 2012-2021 University of Bologna - DICAM
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file results_mpl.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
from numpy.linalg import inv
20
import os
21
##import math
22
import numpy as np
23
from collections import OrderedDict
24
import matplotlib.pyplot as plt
25
from agilepy.lib_base.geometry import *
26
from matplotlib.path import Path
27
import matplotlib.patches as patche
28
from coremodules.demand.origin_to_destination import OdIntervals
29
from agilepy.lib_base.misc import get_inversemap
30
from coremodules.misc.matplottools import *
31
from coremodules.network import network
32
import agilepy.lib_base.classman as cm
33
import agilepy.lib_base.arrayman as am
34
from agilepy.lib_base.geometry import *
35
from agilepy.lib_base.processes import Process
36
from mapmatching import COLOR_MATCHED_ROUTE, COLOR_SHORTEST_ROUTE, COLOR_FASTEST_ROUTE
37
import time
38
try:
39
from scipy import interpolate
40
is_scipy = True
41
except:
42
is_scipy = False
43
44
45
def is_sublist(l, s):
46
sub_set = False
47
if s == []:
48
sub_set = True
49
elif s == l:
50
sub_set = True
51
elif len(s) > len(l):
52
sub_set = False
53
54
else:
55
for i in range(len(l)):
56
if l[i] == s[0]:
57
n = 1
58
while (n < len(s)) and (l[i+n] == s[n]):
59
n += 1
60
61
if n == len(s):
62
sub_set = True
63
64
return sub_set
65
66
67
def kf_update(X, P, Y, H, R):
68
IM = dot(H, X)
69
IS = R + dot(H, dot(P, H.T))
70
K = dot(P, dot(H.T, inv(IS)))
71
X = X + dot(K, (Y-IM))
72
P = P - dot(K, dot(IS, K.T))
73
LH = gauss_pdf(Y, IM, IS)
74
return (X, P, K, IM, IS, LH)
75
76
77
def gauss_pdf(X, M, S):
78
if M.shape()[1] == 1:
79
DX = X - tile(M, X.shape()[1])
80
E = 0.5 * sum(DX * (dot(inv(S), DX)), axis=0)
81
E = E + 0.5 * M.shape()[0] * log(2 * pi) + 0.5 * log(det(S))
82
P = exp(-E)
83
elif X.shape()[1] == 1:
84
DX = tile(X, M.shape()[1]) - M
85
E = 0.5 * sum(DX * (dot(inv(S), DX)), axis=0)
86
E = E + 0.5 * M.shape()[0] * log(2 * pi) + 0.5 * log(det(S))
87
P = exp(-E)
88
else:
89
DX = X-M
90
E = 0.5 * dot(DX.T, dot(inv(S), DX))
91
E = E + 0.5 * M.shape()[0] * log(2 * pi) + 0.5 * log(det(S))
92
P = exp(-E)
93
return (P[0], E[0])
94
95
96
SELECTPOINTS = {'FromOrigin': 1,
97
'ToDestination': 2,
98
'FromOriginToDestination': 3,
99
'All': 4,
100
}
101
PLOTTYPE = {'Isochrone': 1,
102
'Heatmap': 2,
103
}
104
POINTSTYPE = {'OnlyOriginPoints': 1,
105
'OnlyDestinationPoints': 2,
106
'OnlyOriginAndDestinationPoints': 3,
107
'All': 4,
108
}
109
110
111
class PointresultPlotter(PlotoptionsMixin, Process):
112
def __init__(self, results, name='Plot point results with Matplotlib',
113
info="Creates plots of different point results using matplotlib",
114
logger=None, **kwargs):
115
116
self._init_common('pointresultplotter', parent=results, name=name,
117
info=info, logger=logger)
118
119
# print 'Resultplotter.__init__',results,self.parent
120
attrsman = self.get_attrsman()
121
mapmatching = self.parent.parent
122
scenario = mapmatching.get_scenario()
123
self.zones = scenario.landuse.zones
124
125
self.select_points = attrsman.add(cm.AttrConf('select_points', kwargs.get('select_points', SELECTPOINTS['FromOrigin']),
126
groupnames=['options'],
127
choices=SELECTPOINTS,
128
name='Select points',
129
info='Select trip as indicated',
130
))
131
self.plot_type = attrsman.add(cm.AttrConf('plot_type', kwargs.get('plot_type', PLOTTYPE['Heatmap']),
132
groupnames=['options'],
133
choices=PLOTTYPE,
134
name='Plot type',
135
info='Choice the type of plot',
136
))
137
self.points_type = attrsman.add(cm.AttrConf('points_type', kwargs.get('points_type', POINTSTYPE['All']),
138
groupnames=['options'],
139
choices=POINTSTYPE,
140
name='Points type',
141
info='Plot only trip points of the indicated type',
142
))
143
144
# self.is_plot_isochrone_generated = attrsman.add(cm.AttrConf( 'is_plot_isochrone_generated', kwargs.get('is_plot_isochrone_generated', True),
145
## groupnames = ['options'],
146
## name = 'Plot isochrone map from the origin zone',
147
## info = 'Plot isochrone map on edge-network for trips starting from the origin zone.',
148
# ))
149
# self.is_plot_isochrone_attracted = attrsman.add(cm.AttrConf( 'is_plot_isochrone_attracted', kwargs.get('is_plot_isochrone_attracted', True),
150
## groupnames = ['options'],
151
## name = 'Plot isochrone map to the destination zone',
152
## info = 'Plot isochrone map on edge-network for trips ending to the origin zone.',
153
# ))
154
self.is_isochrone = attrsman.add(cm.AttrConf('is_isochrone', kwargs.get('is_isochrone', False),
155
groupnames=['options'],
156
name='Plot isochrones in the map',
157
info='Plot isochrones lines in the map.',
158
))
159
self.max_time = attrsman.add(cm.AttrConf('max_time', kwargs.get('max_time', 40),
160
groupnames=['options'],
161
perm='wr',
162
name='Max time',
163
info='Max time to be considered for the isochrone plot.',
164
))
165
self.min_n_values = attrsman.add(cm.AttrConf('min_n_values', kwargs.get('min_n_values', 2),
166
groupnames=['options'],
167
perm='wr',
168
name='Minumun number of values',
169
info='Minumun number of values to assign a time to each edge.',
170
))
171
# self.is_plot_points_gen_heatmap = attrsman.add(cm.AttrConf( 'is_plot_points_gen_heatmap', kwargs.get('is_plot_points_gen_heatmap', False),
172
## groupnames = ['options'],
173
## name = 'Plot generated trip points from the origin zone',
174
## info = 'Plot a density heatmap of generated trip points from a zone.',
175
# ))
176
# self.is_plot_points_attr_heatmap = attrsman.add(cm.AttrConf( 'is_plot_points_attr_heatmap', kwargs.get('is_plot_points_attr_heatmap', False),
177
## groupnames = ['options'],
178
## name = 'Plot attracted trip points from the destination zone',
179
## info = 'Plot a density heatmap of attracted trip points from a zone.',
180
# ))
181
# self.is_plot_points_od_heatmap = attrsman.add(cm.AttrConf( 'is_plot_points_od_heatmap', kwargs.get('is_plot_points_od_heatmap', False),
182
## groupnames = ['options'],
183
## name = 'Plot od trip points heatmap',
184
## info = 'Plot a density heatmap of trip points from the origin zone to the destination zone.',
185
# ))
186
# self.is_plot_points_heatmap = attrsman.add(cm.AttrConf( 'is_plot_points_heatmap', kwargs.get('is_plot_points_heatmap', False),
187
## groupnames = ['options'],
188
## name = 'Plot density points heatmap',
189
## info = 'Plot density heatmap of the selected GPS points.',
190
# ))
191
192
self.origin_zone_name = attrsman.add(cm.AttrConf('origin_zone_name', kwargs.get('origin_zone_name', self.zones.ids_sumo[0]),
193
groupnames=['options'],
194
choices=self.zones.ids_sumo,
195
name='Origin zone name',
196
info='Generating zone name.',
197
))
198
199
self.dest_zone_name = attrsman.add(cm.AttrConf('dest_zone_name', kwargs.get('dest_zone_name', self.zones.ids_sumo[0]),
200
groupnames=['options'],
201
choices=self.zones.ids_sumo,
202
name='Destination zone name',
203
info='Attracting zone name.',
204
))
205
206
self.bins = attrsman.add(cm.AttrConf('bins', kwargs.get('bins', 500),
207
groupnames=['options'],
208
perm='wr',
209
name='Bins',
210
info='Bins for the heatmap of points.',
211
))
212
213
self.vmin = attrsman.add(cm.AttrConf('vmin', kwargs.get('vmin', 0),
214
groupnames=['options'],
215
perm='wr',
216
name='Min value',
217
info='Min value of points in a bin for the heatmap of points.',
218
))
219
220
self.is_net = attrsman.add(cm.AttrConf('is_net', kwargs.get('is_net', False),
221
groupnames=['options'],
222
name='Show net',
223
info='Show the network in the heatmap of points.',
224
))
225
226
self.titletext = attrsman.add(cm.AttrConf('titletext', kwargs.get('titletext', ''),
227
groupnames=['options'],
228
name='Title text',
229
info='Title text. Empty text means no title.',
230
))
231
self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont', 32),
232
groupnames=['options'],
233
name='Title fontsize',
234
info='Title fontsize.',
235
))
236
237
self.add_plotoptions(**kwargs)
238
239
self.add_save_options(**kwargs)
240
241
def show(self):
242
# init
243
self.init_figures()
244
fig = self.create_figure()
245
results = self.parent
246
ax = fig.add_subplot(111)
247
mapmatching = self.parent.parent
248
scenario = mapmatching.get_scenario()
249
points = scenario.demand.mapmatching.points
250
trips = scenario.demand.mapmatching.trips
251
zones = scenario.landuse.zones
252
net = scenario.net
253
ids_edge = net.edges.get_ids()
254
ids_trip = trips.get_ids()
255
zone_shape_origin = zones.shapes[zones.ids_sumo.get_id_from_index(self.origin_zone_name)]
256
zone_shape_dest = zones.shapes[zones.ids_sumo.get_id_from_index(self.dest_zone_name)]
257
258
# Plot net
259
if self.is_net:
260
print 'plot net'
261
plot_net(ax, net, color_edge="gray", width_edge=2, color_node=None,
262
alpha=0.5)
263
# Plot zones
264
if self.select_points == 1 or self.select_points == 3:
265
# plot origin zone
266
plot_zone(ax, zone_shape_origin, color_zone="coral",
267
color_outline='black', width_line=2,
268
alpha=0.4, zorder=+201)
269
if self.select_points == 2 or self.select_points == 3:
270
# plot destination zone
271
plot_zone(ax, zone_shape_dest, color_zone="coral",
272
color_outline='black', width_line=2,
273
alpha=0.4, zorder=+201)
274
# deselect points
275
points.are_selected[points.get_ids()] = False
276
# Take into account only selected traces with at least two point
277
ids_trip = ids_trip[(trips.are_selected[ids_trip] == True) & (trips.ids_points[ids_trip] != int)]
278
ids_points = trips.ids_points[ids_trip]
279
280
# select points
281
ids_final_point = np.zeros((len(ids_trip)), dtype=np.int32)
282
ids_initial_point = np.zeros((len(ids_trip)), dtype=np.int32)
283
for id_trip, ids_point, i in zip(trips.get_ids(), ids_points, range(len(ids_trip))):
284
ids_final_point[i] = ids_point[-1]
285
ids_initial_point[i] = ids_point[0]
286
if self.select_points == 1:
287
points.are_selected[ids_point] = is_point_in_polygon(
288
points.coords[ids_initial_point[i]], zone_shape_origin)
289
if self.select_points == 2:
290
points.are_selected[ids_point] = is_point_in_polygon(points.coords[ids_final_point[i]], zone_shape_dest)
291
if self.select_points == 3:
292
points.are_selected[ids_point] = is_point_in_polygon(
293
points.coords[ids_initial_point[i]], zone_shape_origin)*is_point_in_polygon(points.coords[ids_final_point[i]], zone_shape_dest)
294
if self.select_points == 4:
295
points.are_selected[ids_point] = True
296
297
# consider only selected points
298
if self.points_type == 1:
299
ids_point = ids_initial_point[(points.are_selected[ids_initial_point] == True)]
300
if self.points_type == 2:
301
ids_point = ids_final_point[(points.are_selected[ids_final_point] == True)]
302
if self.points_type == 3:
303
ids_initial_point = ids_initial_point[(points.are_selected[ids_initial_point] == True)]
304
ids_initial_point.tolist()
305
ids_final_point = ids_final_point[(points.are_selected[ids_final_point] == True)]
306
# ids_final_point.tolist()
307
ids_point = ids_initial_point.tolist()
308
ids_point.extend(ids_final_point)
309
print ids_initial_point, ids_final_point, ids_points
310
if self.points_type == 4:
311
ids_point = points.get_ids(points.are_selected.get_value() == True)
312
coords = points.coords[ids_point]
313
314
if self.plot_type == 1:
315
# Match time points with edges and call isochrone plot, if selected
316
min_n_values = self.min_n_values
317
times_edge = np.zeros(np.max(ids_edge))
318
values = np.zeros(np.max(ids_edge))
319
valuess = []
320
for i in range(np.max(ids_edge)-1):
321
valuess.append([])
322
count = np.zeros(np.max(ids_edge))
323
# if self.is_isochrone:
324
## times_point = np.zeros(np.max(ids_point)+1)
325
for coord, id_point in zip(coords, ids_point):
326
coord = np.array([coord[0], coord[1]])
327
id_closest_edge = net.edges.get_closest_edge(coord)
328
print 'point', id_point
329
if id_closest_edge > 0:
330
if self.select_points == 1:
331
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
332
if self.select_points == 2:
333
time = -(points.timestamps[id_point] -
334
points.timestamps[trips.ids_points[points.ids_trip[id_point]][-1]])/60.0
335
if self.select_points == 3:
336
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
337
if self.select_points == 4:
338
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
339
340
if 0 < time < self.max_time:
341
count[id_closest_edge-1] += 1
342
times_edge[id_closest_edge-1] += time
343
if count[id_closest_edge-1] > min_n_values:
344
values[id_closest_edge-1] = times_edge[id_closest_edge-1]/count[id_closest_edge-1]
345
346
# For the isochrone plot
347
# if self.is_isochrone:
348
## times_point[id_point] = time
349
print 'number of points:', np.sum(count)
350
351
# Plot result on map
352
print 'plot results on map'
353
if self.select_points == 1:
354
title = 'Isochrone from the origin zone'
355
if self.select_points == 2:
356
title = 'Isochrone to the destination zone'
357
if self.select_points == 3:
358
title = 'Isochrone from the origin to the destination zone'
359
if self.select_points == 4:
360
title = 'Isochrone for all trips'
361
362
self.plot_results_on_map(ax, ids_edge=ids_edge,
363
values=values[ids_edge-1],
364
title=title,
365
valuelabel='Minutes',
366
)
367
368
if self.is_save:
369
if self.select_points == 1:
370
self.save_fig('routeana_isochrone_fromO')
371
if self.select_points == 2:
372
self.save_fig('routeana_isochrone_toD')
373
if self.select_points == 3:
374
self.save_fig('routeana_isochrone_FromOtoD')
375
if self.select_points == 4:
376
self.save_fig('routeana_isochrone')
377
378
if self.plot_type == 2:
379
380
# Plot heatmap
381
x_points = coords[:, 0]
382
y_points = coords[:, 1]
383
xedges = np.linspace(0., 14000., num=self.bins)
384
yedges = np.linspace(0., 11000., num=self.bins)
385
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
386
H, xedges, yedges = np.histogram2d(x_points, y_points, bins=(xedges, yedges))
387
X, Y = np.meshgrid(xedges, yedges)
388
if self.titletext != '':
389
ax.set_title(self.titletext, fontsize=self.size_titlefont)
390
else:
391
if self.select_points == 1:
392
ax.set_title('Density heatmap of trip points from the origin zone', fontsize=self.size_titlefont)
393
if self.select_points == 2:
394
ax.set_title('Density heatmap of trip points to the destination zone', fontsize=self.size_titlefont)
395
if self.select_points == 3:
396
ax.set_title('Density heatmap of trip points from the origin zone to the destination zone',
397
fontsize=self.size_titlefont)
398
if self.select_points == 4:
399
ax.set_title('Density heatmap of all trip points', fontsize=self.size_titlefont)
400
401
plt.imshow(list(zip(*reversed(list(zip(*reversed(list(zip(*reversed(H))))))))),
402
vmin=self.vmin, cmap='Reds', extent=extent, interpolation='bicubic', alpha=0.9)
403
plt.colorbar()
404
if self.is_save:
405
if self.select_points == 1:
406
self.save_fig('routeana_heatmappoints_fromO')
407
if self.select_points == 2:
408
self.save_fig('routeana_heatmappoints_toD')
409
if self.select_points == 3:
410
self.save_fig('routeana_heatmappoints_FromOtoD')
411
if self.select_points == 4:
412
self.save_fig('routeana_heatmappoints')
413
414
# print isochrone
415
if self.is_isochrone:
416
times_point = np.zeros(np.max(ids_point)+1)
417
for id_point in ids_point:
418
if self.select_points == 1:
419
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
420
if self.select_points == 2:
421
time = -(points.timestamps[id_point] -
422
points.timestamps[trips.ids_points[points.ids_trip[id_point]][-1]])/60.0
423
if self.select_points == 3:
424
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
425
if self.select_points == 4:
426
time = (points.timestamps[id_point] - trips.timestamps[points.ids_trip[id_point]])/60.0
427
428
times_point[id_point] = time
429
self.plot_isochrone(ax, ids_point, zone_shape_origin, times_point)
430
431
if not self.is_save:
432
show_plot()
433
434
def plot_isochrone(self, ax, ids_point, zone_shape, times_point):
435
436
mapmatching = self.parent.parent
437
scenario = mapmatching.get_scenario()
438
points = scenario.demand.mapmatching.points
439
zone_g = np.array([np.mean(np.array(zone_shape)[:, 0]), np.mean(np.array(zone_shape)[:, 1])])
440
coords = points.coords[ids_point]
441
coords = coords[:][:, :2]
442
isochrone = []
443
for coord, id_point, time_point in zip(coords, ids_point, times_point[ids_point]):
444
if zone_g[0] < coord[0] and zone_g[1] < coord[1]:
445
angle = np.arctan((coord[0]-zone_g[0])/(coord[1]-zone_g[1]))
446
if zone_g[0] < coord[0] and zone_g[1] > coord[1]:
447
angle = np.arctan((zone_g[1]-coord[1])/(coord[0]-zone_g[0])) + np.pi/2
448
if zone_g[0] > coord[0] and zone_g[1] > coord[1]:
449
angle = np.arctan((zone_g[0]-coord[0])/(zone_g[1]-coord[1])) + np.pi
450
if zone_g[0] > coord[0] and zone_g[1] < coord[1]:
451
angle = np.arctan((coord[1]-zone_g[1])/(zone_g[0]-coord[0])) + np.pi*3/2
452
dist = np.sqrt(np.sum((coord-zone_g)**2))
453
isochrone.append([angle, id_point, time_point, dist])
454
isochrone = np.asarray(isochrone)
455
isochrone = isochrone[isochrone[:, 0].argsort()]
456
isochrone = isochrone[(isochrone[:, 2] > 0)]
457
458
n_bins = 200.0
459
## max_perc_var = 20.
460
isochrone_times = [5., 10., 15., 20., 25., 30., 35., 40.]
461
isochrone_shapes = [[]]*len(isochrone_times)
462
for bin in range(int(n_bins)):
463
for i in range(len(isochrone_times)):
464
iso_points = isochrone[(bin*2.0*np.pi/n_bins <= isochrone[:, 0]) & (isochrone[:, 0] < (bin+1)
465
* 2.0*np.pi/n_bins) & (0 < isochrone[:, 2]) & (isochrone_times[i] > isochrone[:, 2])]
466
if len(iso_points) > 10:
467
if len(isochrone_shapes[i]) == 0:
468
isochrone_shapes[i] = [[(points.coords[iso_points[np.argmax(iso_points[:, 3]), 1]][0]),
469
(points.coords[iso_points[np.argmax(iso_points[:, 3]), 1]][1])]]
470
else:
471
isochrone_shapes[i].append([(points.coords[iso_points[np.argmax(iso_points[:, 3]), 1]][0]),
472
(points.coords[iso_points[np.argmax(iso_points[:, 3]), 1]][1])])
473
print isochrone_shapes
474
for isochrone_shape in isochrone_shapes:
475
verts = np.array(isochrone_shape)[:, :2].tolist()
476
verts.append([0, 0])
477
codes = [Path.MOVETO]
478
for i in range(len(verts)-2):
479
codes.append(Path.LINETO)
480
codes.append(Path.CLOSEPOLY)
481
path = Path(verts, codes)
482
facecolor = 'none'
483
patch = patche.PathPatch(path, facecolor=facecolor, edgecolor='r', lw=5, alpha=0.8)
484
ax.add_patch(patch)
485
486
for isochrone_shape in isochrone_shapes:
487
488
if len(isochrone_shape) > 4:
489
zone_shape = isochrone_shape
490
print zone_shape
491
for zone_shape_coords, i in zip(isochrone_shape, range(len(isochrone_shape))):
492
print i, len(isochrone_shape)
493
if i == 0:
494
zone_shape[i] = ((np.array(isochrone_shape[i])+np.array(isochrone_shape[i+1])+np.array(
495
isochrone_shape[-1])+np.array(isochrone_shape[i+2])+np.array(isochrone_shape[-2]))/5.).tolist()
496
elif i == (len(isochrone_shape)-1):
497
zone_shape[i] = ((np.array(isochrone_shape[i])+np.array(isochrone_shape[0])+np.array(
498
isochrone_shape[i-1])+np.array(isochrone_shape[i-2])+np.array(isochrone_shape[1]))/5.).tolist()
499
elif i == 1:
500
zone_shape[i] = ((np.array(isochrone_shape[i])+np.array(isochrone_shape[i+1])+np.array(
501
isochrone_shape[i-1])+np.array(isochrone_shape[i+2])+np.array(isochrone_shape[-1]))/5.).tolist()
502
elif i == (len(isochrone_shape)-2):
503
zone_shape[i] = ((np.array(isochrone_shape[i])+np.array(isochrone_shape[i+1])+np.array(
504
isochrone_shape[i-1])+np.array(isochrone_shape[i-2])+np.array(isochrone_shape[0]))/5.).tolist()
505
else:
506
zone_shape[i] = ((np.array(isochrone_shape[i])+np.array(isochrone_shape[i+1])+np.array(
507
isochrone_shape[i-1])+np.array(isochrone_shape[i+2])+np.array(isochrone_shape[i-2]))/5.).tolist()
508
509
verts = np.array(zone_shape)[:, :2].tolist()
510
verts.append([0, 0])
511
codes = [Path.MOVETO]
512
for i in range(len(verts)-2):
513
codes.append(Path.LINETO)
514
codes.append(Path.CLOSEPOLY)
515
path = Path(verts, codes)
516
facecolor = 'none'
517
patch = patche.PathPatch(path, facecolor=facecolor, edgecolor='b', lw=5, alpha=0.8)
518
ax.add_patch(patch)
519
520
return True
521
522
def get_scenario(self):
523
return self.parent.get_scenario()
524
525
526
class NoderesultPlotter(PlotoptionsMixin, Process):
527
def __init__(self, results, name='Node results plotter',
528
info="Plots nodes related results of GPS trips using matplotlib",
529
logger=None, **kwargs):
530
531
self._init_common('noderesultplotter', parent=results, name=name,
532
info=info, logger=logger)
533
534
# print 'Resultplotter.__init__',results,self.parent
535
attrsman = self.get_attrsman()
536
537
self.plotthemefuncs = OrderedDict([
538
('times wait', self.plot_times_wait),
539
])
540
self.plottheme = attrsman.add(cm.AttrConf('plottheme', kwargs.get('plottheme', 'times wait'),
541
groupnames=['options'],
542
choices=self.plotthemefuncs.keys(),
543
name='Plot theme',
544
info='Theme or edge attribute to be plottet.',
545
))
546
547
self.n_min_matched = attrsman.add(cm.AttrConf('n_min_matched', 3,
548
groupnames=['options'],
549
name='Minum number of matched for speed analysis',
550
info='Only nodes contained in almost this number of matched routes\
551
will be considered for plotting the dynamic\
552
characteristics of edges (speeds and times).',
553
))
554
self.add_plotoptions(**kwargs)
555
self.add_save_options(**kwargs)
556
557
attrsman.delete('plottype')
558
attrsman.delete('resultwidth')
559
attrsman.delete('length_arrowhead')
560
attrsman.delete('is_widthvalue')
561
562
def plot_all_themes(self):
563
for plottheme in self.plotthemefuncs.keys():
564
self.plottheme = plottheme
565
self.show()
566
##
567
# self.is_grid = attrsman.add(cm.AttrConf( 'is_grid', kwargs.get('is_grid', True),
568
## groupnames = ['options'],
569
## name = 'Show grid?',
570
## info = 'If True, shows a grid on the graphical representation.',
571
# ))
572
##
573
# self.titletext = attrsman.add(cm.AttrConf( 'titletext', kwargs.get('titletext', ''),
574
## groupnames = ['options'],
575
## name = 'Title text',
576
## info = 'Title text. Empty text means no title.',
577
# ))
578
##
579
# self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont',32),
580
## groupnames = ['options'],
581
## name = 'Title fontsize',
582
## info = 'Title fontsize.',
583
# ))
584
##
585
# self.size_labelfont = attrsman.add(cm.AttrConf('size_labelfont', kwargs.get('size_labelfont',24),
586
## groupnames = ['options'],
587
## name = 'Label fontsize',
588
## info = 'Label fontsize.',
589
# ))
590
##
591
# self.width_line = attrsman.add(cm.AttrConf( 'width_line', kwargs.get('width_line', 1.0),
592
## groupnames = ['options'],
593
## name = 'Line width',
594
## info = 'Line width of plot.',
595
# ))
596
self.add_save_options()
597
598
def get_noderesults(self):
599
return self.parent.nodesresults
600
601
def show(self):
602
print 'NoderesultPlotter.show', self.plottheme
603
# if self.axis is None:
604
#axis = init_plot()
605
self.init_figures()
606
fig = self.create_figure()
607
axis = fig.add_subplot(111)
608
self.plotthemefuncs[self.plottheme](axis)
609
610
print ' self.is_save', self.is_save
611
if not self.is_save:
612
print ' show_plot'
613
show_plot()
614
else:
615
figname = 'nodeplot_'+self.plottheme
616
# print ' savefig',figname
617
618
# self.save_fig('edgeplot_'+self.plottheme)
619
620
rootfilepath = self.get_scenario().get_rootfilepath()
621
622
fig.savefig("%s_%s.%s" % (rootfilepath, figname, self.figformat),
623
format=self.figformat,
624
dpi=self.resolution,
625
# orientation='landscape',
626
orientation='portrait',
627
transparent=True)
628
plt.close(fig)
629
630
def plot_times_wait(self, ax):
631
print 'show noderesults', len(self.parent.nodesresults)
632
# if self.axis is None:
633
634
nodesresults = self.parent.nodesresults
635
636
if len(nodesresults) == 0:
637
return False
638
639
mapmatching = self.parent.parent
640
trips = mapmatching.trips
641
#points = mapmatching.points
642
routes = trips.get_routes()
643
scenario = mapmatching.get_scenario()
644
edges = scenario.net.edges
645
nodes = scenario.net.nodes
646
ids_noderes = nodesresults.select_ids(
647
nodesresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
648
nodetypes = nodes.types[nodesresults.ids_node[ids_noderes]]
649
times_wait = nodesresults.times_wait[ids_noderes]
650
nodetypeset = set(nodetypes)
651
652
## map_type_to_typename = get_inversemap(nodes.types.choices)
653
## map_typename_to_times_wait = {}
654
# for thistype in nodetypeset:
655
## map_typename_to_times_wait[map_type_to_typename[thistype]] = np.mean(times_wait[nodetypes == thistype])
656
657
# self.init_figures()
658
## fig = self.create_figure()
659
## ax = fig.add_subplot(111)
660
self.plot_node_results_on_map(ax, ids_noderes,
661
# edgesresults.differences_dist_tot_shortest[ids_result]/edgesresults.numbers_tot_shortest[ids_result],
662
times_wait,
663
title='Average waiting time at intersections',
664
valuelabel='Average waiting time [s]',
665
is_node_results=True,)
666
667
668
# colors = np.array(COLORS,dtype = np.object)
669
## inds_plot = np.arange(len(map_typename_to_times_wait), dtype = np.int32)
670
## bar_width = 0.45
671
## opacity = 0.5
672
# error_config = {'ecolor': '0.3'}
673
# print ' colors',get_colors(inds_plot)
674
# rects = ax.barh( inds_plot,
675
# map_typename_to_times_wait.values(),
676
# align='center',
677
# alpha=opacity,
678
# height=bar_width,
679
# color=get_colors(inds_plot),
680
# yerr=std_women, error_kw=error_config,
681
## linewidth = self.width_line,
682
# facecolor=colors[inds][inds_nz],
683
# )
684
##
685
##
686
## ax.set_yticks( inds_plot + bar_width / 2)
687
# ax.set_yticklabels(map_typename_to_times_wait.keys())
688
# ax.legend()
689
##
690
# ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)
691
# ax.grid(self.is_grid)
692
# if self.titletext != '':
693
## ax.set_title(self.titletext, fontsize=self.size_titlefont)
694
## ax.set_xlabel('Average wait times [s]', fontsize=self.size_labelfont)
695
## ax.set_ylabel('Intersection type', fontsize=self.size_labelfont)
696
## ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
697
## ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
698
# fig.tight_layout()
699
# if self.is_save:
700
# self.save_fig('virtualpop_strategy_share_current')
701
##
702
##
703
##
704
# plt.show()
705
# show_plot()
706
707
def get_scenario(self):
708
return self.parent.get_scenario()
709
710
711
class SpeedprofilePlotter(PlotoptionsMixin, Process):
712
def __init__(self, results, name='Speedprofile plotter with Matplotlib',
713
info="Plots the speed profile of a selected GPS trip using matplotlib",
714
logger=None, **kwargs):
715
716
self._init_common('speedprofileplotter', parent=results, name=name,
717
info=info, logger=logger)
718
719
# print 'Resultplotter.__init__',results,self.parent
720
attrsman = self.get_attrsman()
721
722
self.id_trip = attrsman.add(cm.AttrConf('id_trip', kwargs.get('id_trip', -1),
723
groupnames=['options'],
724
name='Trip ID',
725
info='ID of GPS trip to be plotted.',
726
))
727
728
self.is_plot_similar_trips = attrsman.add(cm.AttrConf('is_plot_similar_trips', kwargs.get('is_plot_similar_trips', True),
729
groupnames=['options'],
730
name='Plot similar trips',
731
info='If True, plot all trips which contain the same route as the given trip.',
732
))
733
734
self.method_interp = attrsman.add(cm.AttrConf('method_interp', kwargs.get('method_interp', 'slinear'),
735
groupnames=['options'],
736
choices=['linear', 'nearest', 'zero',
737
'slinear', 'quadratic', 'cubic'],
738
name='Interpolation method',
739
info='GPS point interpolation method.',
740
))
741
742
self.color_point = attrsman.add(cm.AttrConf('color_point', kwargs.get('color_point', np.array([0.0, 0.4, 0.6, 0.6], np.float32)),
743
groupnames=['options'],
744
perm='wr',
745
metatype='color',
746
name='Point color',
747
info='Color of GPS-points.',
748
))
749
750
self.size_point = attrsman.add(cm.AttrConf('size_point', kwargs.get('size_point', 10.0),
751
groupnames=['options'],
752
name='Point size',
753
info='Point size of GPS points.',
754
))
755
756
self.is_pointlabel = attrsman.add(cm.AttrConf('is_pointlabel', kwargs.get('is_pointlabel', True),
757
groupnames=['options'],
758
name='Label points?',
759
info='If True, shows point ID nex to each point.',
760
))
761
762
self.is_waitslabel = attrsman.add(cm.AttrConf('is_waitslabel', kwargs.get('is_waitslabel', True),
763
groupnames=['options'],
764
name='Show wait times?',
765
info='If True, shows wait times for each edge.',
766
))
767
768
self.is_waitslabel_junction = attrsman.add(cm.AttrConf('is_waitslabel_junction', kwargs.get('is_waitslabel_junction', True),
769
groupnames=['options'],
770
name='Show wait times at junctions?',
771
info='If True, shows wait times at junctions for each edge entering a junction.',
772
))
773
774
self.is_waitslabel_tls = attrsman.add(cm.AttrConf('is_waitslabel_tls', kwargs.get('is_waitslabel_tls', True),
775
groupnames=['options'],
776
name='Show wait times at TLS?',
777
info='If True, shows wait times at traffic light systems (TLS) for each edge entering a traffic light.',
778
))
779
780
self.color_line = attrsman.add(cm.AttrConf('color_line', kwargs.get('color_line', np.array([1.0, 0.6, 0.0, 1.0], np.float32)),
781
groupnames=['options'],
782
perm='wr',
783
metatype='color',
784
name='Line color',
785
info='Color of plotted line in diagram.',
786
))
787
788
self.width_line = attrsman.add(cm.AttrConf('width_line', kwargs.get('width_line', 3.0),
789
groupnames=['options'],
790
name='Line width',
791
info='Line width of plot.',
792
))
793
794
self.alpha_line = attrsman.add(cm.AttrConf('alpha_line', kwargs.get('alpha_line', 0.8),
795
groupnames=['options'],
796
name='Line transp.',
797
info='Line transparency of plot.',
798
))
799
800
self.is_grid = attrsman.add(cm.AttrConf('is_grid', kwargs.get('is_grid', True),
801
groupnames=['options'],
802
name='Show grid?',
803
info='If True, shows a grid on the graphical representation.',
804
))
805
806
self.titletext = attrsman.add(cm.AttrConf('titletext', kwargs.get('titletext', ''),
807
groupnames=['options'],
808
name='Title text',
809
info='Title text. Empty text means no title.',
810
))
811
812
self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont', 32),
813
groupnames=['options'],
814
name='Title fontsize',
815
info='Title fontsize.',
816
))
817
818
self.size_labelfont = attrsman.add(cm.AttrConf('size_labelfont', kwargs.get('size_labelfont', 24),
819
groupnames=['options'],
820
name='Label fontsize',
821
info='Label fontsize.',
822
))
823
self.add_save_options()
824
825
def plot_speed_over_time(self, ax, id_trip, id_route, edges, i_min=None, i_max=None,
826
is_pointlabel=True, alpha=1.0):
827
print 'plot_speed_over_time', id_trip, type(id_trip), self.parent.parent
828
829
#mapmatching = self.parent.parent
830
#trips = mapmatching.trips
831
832
routeresults = self.get_routeresults()
833
834
#id_route = trips.ids_route_matched[id_trip]
835
id_routeres = routeresults.ids_route.get_id_from_index(id_route)
836
837
mapmatching = self.parent.parent
838
trips = mapmatching.trips
839
ids_point = routeresults.ids_valid_point_speedana[id_routeres]
840
841
# tripresults.pointsposition[id_routeres],\
842
# tripresults.pointsspeed[id_routeres],
843
# tripresults.pointstime[id_routeres],
844
# ids_pointedges,
845
846
if i_min is None:
847
#ids_pointedge = routeresults.ids_pointedges[id_routeres]
848
#pointspositions = routeresults.pointspositions[id_routeres]
849
speeds = routeresults.speedana_point_speeds[id_routeres]
850
times = routeresults.speedana_point_times[id_routeres]
851
else:
852
#ids_pointedge = routeresults.ids_pointedges[id_routeres][i_min:i_max]
853
#pointspositions = routeresults.pointspositions[id_routeres][i_min:i_max]
854
speeds = routeresults.speedana_point_speeds[id_routeres][i_min:i_max]
855
times = routeresults.speedana_point_times[id_routeres][i_min:i_max]
856
# print ' id_route,id_routeres',id_route,id_routeres
857
# print ' ids_pointedge',ids_pointedge
858
n_point = len(times)
859
860
x = np.array(times, dtype=np.float32)
861
y = np.array(speeds, dtype=np.float32)*3.6 # in km/h
862
#ax = init_plot()
863
# print ' x',x
864
# print ' y',y
865
#ax.plot(locations, speeds, color = self.color_line[:2], lw = self.width_line ,alpha=0.9 ,zorder = 0)
866
867
alpha = min(alpha, self.alpha_line)
868
869
if is_scipy & (not (self.method_interp == 'linear')):
870
871
print 'use scipy to interpolate'
872
#tck = interpolate.splrep(x, y, s=0)
873
#xnew = np.linspace(np.min(x), np.max(x), 200)
874
#ynew = interpolate.splev(xnew, tck, der=0)
875
# if 1:
876
f_inter = interpolate.interp1d(x, y, kind=self.method_interp)
877
xnew = np.linspace(np.min(x), np.max(x), 200)
878
ynew = f_inter(xnew)
879
880
ax.plot(xnew, ynew, color=self.color_line, lw=self.width_line, alpha=alpha)
881
ax.plot(x, y, 'o', markersize=self.size_point, color=self.color_point, alpha=alpha)
882
else:
883
ax.plot(x, y, 'o-', markersize=self.size_point, color=self.color_line,
884
lw=self.width_line, markerfacecolor=self.color_point, alpha=alpha)
885
886
# label points
887
if self.is_pointlabel & is_pointlabel:
888
for id_point, xi, yi in zip(ids_point, x, y):
889
890
ax.text(xi+2, yi, ' %s ' % (str(id_point)),
891
verticalalignment='top',
892
horizontalalignment='left',
893
#rotation = 'vertical',
894
fontsize=int(0.8*self.size_labelfont)) # baseline
895
896
def plot_speed_over_way(self, ax, id_trip, id_route, edges, i_min=None, i_max=None,
897
is_pointlabel=True, alpha=1.0):
898
print 'plot_speed_over_way', id_trip, type(id_trip), self.parent.parent
899
900
#mapmatching = self.parent.parent
901
#trips = mapmatching.trips
902
903
routeresults = self.get_routeresults()
904
905
#id_route = trips.ids_route_matched[id_trip]
906
id_routeres = routeresults.ids_route.get_id_from_index(id_route)
907
908
mapmatching = self.parent.parent
909
trips = mapmatching.trips
910
ids_point = routeresults.ids_valid_point_speedana[id_routeres]
911
912
# tripresults.pointsposition[id_routeres],\
913
# tripresults.pointsspeed[id_routeres],
914
# tripresults.pointstime[id_routeres],
915
# ids_pointedges,
916
917
if i_min is None:
918
ids_pointedge = routeresults.ids_pointedges[id_routeres]
919
pointspositions = routeresults.speedana_point_pos[id_routeres]
920
speeds = routeresults.speedana_point_speeds[id_routeres]
921
times = routeresults.speedana_point_times[id_routeres]
922
else:
923
ids_pointedge = routeresults.ids_pointedges[id_routeres][i_min:i_max]
924
pointspositions = routeresults.speedana_point_pos[id_routeres][i_min:i_max]
925
speeds = routeresults.speedana_point_speeds[id_routeres][i_min:i_max]
926
times = routeresults.speedana_point_times[id_routeres][i_min:i_max]
927
# print ' id_route,id_routeres',id_route,id_routeres
928
# print ' ids_pointedge',ids_pointedge
929
n_point = len(ids_pointedge)
930
931
alpha = min(alpha, self.alpha_line)
932
x = pointspositions
933
y = np.array(speeds, dtype=np.float32)*3.6 # in km/h
934
935
#ax = init_plot()
936
print ' ids_point', routeresults.ids_valid_point_speedana[id_routeres]
937
print ' position', pointspositions
938
print ' x', x
939
print ' y', y
940
#ax.plot(locations, speeds, color = self.color_line[:2], lw = self.width_line ,alpha=0.9 ,zorder = 0)
941
942
if is_scipy & (not (self.method_interp == 'linear')):
943
#tck = interpolate.splrep(x, y, s=0)
944
#xnew = np.linspace(np.min(x), np.max(x), 200)
945
#ynew = interpolate.splev(xnew, tck, der=0)
946
# if 1:
947
f_inter = interpolate.interp1d(x, y, kind=self.method_interp)
948
xnew = np.linspace(np.min(x), np.max(x), 200)
949
ynew = f_inter(xnew)
950
951
ax.plot(xnew, ynew, color=self.color_line, lw=self.width_line, alpha=alpha)
952
ax.plot(x, y, 'o', markersize=self.size_point, color=self.color_point, alpha=alpha)
953
else:
954
ax.plot(x, y, 'o-', markersize=self.size_point, color=self.color_line,
955
lw=self.width_line, markerfacecolor=self.color_point, alpha=alpha)
956
if self.is_pointlabel & is_pointlabel:
957
# label points
958
for id_point, xi, yi in zip(ids_point, x, y):
959
960
ax.text(xi+2, yi, ' %s ' % (str(id_point)),
961
verticalalignment='top',
962
horizontalalignment='left',
963
#rotation = 'vertical',
964
fontsize=int(0.8*self.size_labelfont)) # baseline
965
966
def show(self):
967
print 'show', self.id_trip, type(self.id_trip), self.parent.parent
968
# if self.axis is None:
969
970
if self.id_trip >= 0:
971
id_trip = self.id_trip
972
mapmatching = self.parent.parent
973
trips = mapmatching.trips
974
#points = mapmatching.points
975
routes = trips.get_routes()
976
scenario = mapmatching.get_scenario()
977
edges = scenario.net.edges
978
nodes = scenario.net.nodes
979
980
routeresults = self.get_routeresults()
981
982
if id_trip in trips:
983
id_route = trips.ids_route_matched[id_trip]
984
else:
985
return False
986
987
route = routes.ids_edges[id_route]
988
989
if routeresults.ids_route.has_index(id_route):
990
id_routeres = routeresults.ids_route.get_id_from_index(id_route)
991
else:
992
return False
993
994
edgesresults = self.parent.edgesresults
995
connectionsresults = self.parent.connectionsresults
996
997
# tripresults.pointsposition[id_routeres],\
998
# tripresults.pointsspeed[id_routeres],
999
# tripresults.pointstime[id_routeres],
1000
# ids_pointedges,
1001
self.init_figures()
1002
fig = self.create_figure()
1003
ax = fig.add_subplot(111)
1004
1005
fig2 = self.create_figure()
1006
ax2 = fig2.add_subplot(111)
1007
1008
self.plot_speed_over_way(ax, id_trip, id_route, edges)
1009
self.plot_speed_over_time(ax2, id_trip, id_route, edges)
1010
1011
# get_color()
1012
# is_sublist
1013
#id_route = trips.ids_route_matched[id_trip]
1014
#route = routes.ids_edge[id_route]
1015
ids_pointedge = routeresults.ids_pointedges[id_routeres]
1016
if self.is_plot_similar_trips:
1017
#id_routeres = routeresults.ids_route.get_ids_from_indices(ids_route)
1018
1019
id_pointedge_first = ids_pointedge[0]
1020
id_pointedge_last = ids_pointedge[-1]
1021
1022
ids_routeres_speed = routeresults.get_ids()
1023
ids_route_speed = routeresults.ids_route[ids_routeres_speed]
1024
# print ' route',route
1025
for id_trip_speed, id_route_speed, route_speed, ids_pointedge_speed in zip(
1026
routes.ids_trip[ids_route_speed],
1027
ids_route_speed, routes.ids_edges[ids_route_speed],
1028
routeresults.ids_pointedges[ids_routeres_speed]):
1029
# print ' ids_pointedge_speed',ids_pointedge_speed
1030
# print ' route[0],is_inlist',route[0],ids_pointedge_speed.count(route[0]),type(ids_pointedge_speed)
1031
# print ' route_speed',route_speed
1032
1033
# is_sublist(route,route_speed):# | is_sublist(route_speed,route):
1034
if is_sublist(route_speed, route):
1035
i = ids_pointedge_speed.index(id_pointedge_first)
1036
j = ids_pointedge_speed.index(id_pointedge_last)
1037
n_pointedge = len(ids_pointedge_speed)
1038
while (ids_pointedge_speed[j] == id_pointedge_last) & (j < n_pointedge-1):
1039
j += 1
1040
self.plot_speed_over_way(ax, id_trip_speed, id_route_speed, edges,
1041
i, j, is_pointlabel=False, alpha=0.5)
1042
self.plot_speed_over_time(ax2, id_trip_speed, id_route_speed, edges,
1043
i, j, is_pointlabel=False, alpha=0.5)
1044
1045
# plot edge info to speed over time
1046
1047
colors = [(0.2, 0.2, 0.2, 0.7), (0.8, 0.8, 0.8, 0.7)]
1048
ymin, ymax = ax.get_ylim()
1049
x = 0
1050
x_last = routeresults.speedana_point_pos[id_routeres][0]
1051
t_last = 0
1052
i = 0
1053
## id_arc_last = routeresults.ids_arc_point[id_routeres][0]
1054
id_arc_last = 0
1055
i_point = 0
1056
pointstime = routeresults.speedana_point_times[id_routeres]
1057
print ' len(ids_pointedge)', len(ids_pointedge)
1058
print ' len(pointstime)', len(pointstime)
1059
1060
# if len(pointstime)>1:
1061
# t_last = pointstime[1]
1062
# else:
1063
#t_last_edge = pointstime[0]
1064
#t_last = pointstime[0]
1065
# print ' ids_pointedge\n',ids_pointedge
1066
# print ' pointstime\n',pointstime
1067
# print ' pointsspeeds\n',routeresults.pointsspeeds[id_routeres]
1068
1069
linestyle = '--'
1070
1071
for id_arc_point, is_connection_point, t, v, pos in zip(
1072
routeresults.ids_arc_point[id_routeres],
1073
routeresults.is_connection_point[id_routeres],
1074
pointstime,
1075
routeresults.speedana_point_speeds[id_routeres],
1076
routeresults.speedana_point_pos[id_routeres],
1077
):
1078
1079
print ' id_arc_point', id_arc_point, 'is_connection_point', is_connection_point, 'id_arc_last', id_arc_last, id_arc_point != id_arc_last, 'pos=%.2fm, t=%.2fs, v=%.2fkm/h' % (pos, t, v*3.6),
1080
color = 'k'
1081
if (id_arc_point != id_arc_last):
1082
1083
t_last = t # memorize t where edge ids changed
1084
if not is_connection_point:
1085
# edges have changed
1086
# if id_edge != -1:
1087
# x += edges.lengths[id_edge] # add length of old id_edge
1088
1089
ax2.text(t_last+2, ymax, ' ID Edge = %s ' % (str(id_arc_point)),
1090
verticalalignment='top',
1091
horizontalalignment='left',
1092
rotation='vertical',
1093
fontsize=int(0.8*self.size_labelfont)) # baseline
1094
1095
# put wait times, if any available
1096
if edgesresults.ids_edge.has_index(id_arc_point):
1097
id_edgeres = edgesresults.ids_edge.get_id_from_index(id_arc_point)
1098
time_wait = edgesresults.times_wait[id_edgeres]
1099
time_wait_junc = edgesresults.times_wait_junc[id_edgeres]
1100
time_wait_tls = edgesresults.times_wait_tls[id_edgeres]
1101
label = r' '
1102
# is_waitslabel,is_waitslabel_junction,is_waitslabel_tls
1103
if self.is_waitslabel & (time_wait > 0):
1104
label += ' $T_W=%ds$' % time_wait
1105
1106
if self.is_waitslabel_junction & (time_wait_junc > 0):
1107
label += ' $T_J=%ds$' % time_wait_junc
1108
1109
if self.is_waitslabel_tls & (time_wait_tls > 0):
1110
label += ' $T_{\mathrm{TL}}=%ds$' % time_wait_tls
1111
1112
ax2.text(t_last+2, ymin, label,
1113
verticalalignment='bottom',
1114
horizontalalignment='left',
1115
rotation='vertical',
1116
color=color,
1117
fontsize=int(0.8*self.size_labelfont))
1118
1119
ax2.plot([t_last, t_last], [ymin, ymax], color=color, linestyle=linestyle)
1120
t_last = t # memorize t where edge ids changed
1121
1122
else:
1123
# edges have changed
1124
# if id_edge != -1:
1125
# x += edges.lengths[id_edge] # add length of old id_edge
1126
1127
ax2.text(t_last+2, ymax, ' ID Connection = %s ' % (str(id_arc_point)),
1128
verticalalignment='top',
1129
horizontalalignment='left',
1130
rotation='vertical',
1131
fontsize=int(0.8*self.size_labelfont)) # baseline
1132
1133
# put wait times, if any available
1134
if connectionsresults.ids_connection.has_index(id_arc_point):
1135
id_connectionres = connectionsresults.ids_connection.get_id_from_index(id_arc_point)
1136
time_wait = connectionsresults.times_wait[id_connectionres]
1137
## time_wait_junc = connectionsresults.times_wait_junc[id_edgeres]
1138
time_wait_tls = connectionsresults.times_wait_tls[id_connectionres]
1139
label = r' '
1140
# is_waitslabel,is_waitslabel_junction,is_waitslabel_tls
1141
if self.is_waitslabel & (time_wait > 0):
1142
label += ' $T_W=%ds$' % time_wait
1143
1144
##
1145
# if self.is_waitslabel_junction & (time_wait_junc>0):
1146
## label += ' $T_J=%ds$'%time_wait_junc
1147
##
1148
1149
if self.is_waitslabel_tls & (time_wait_tls > 0):
1150
label += ' $T_{\mathrm{TL}}=%ds$' % time_wait_tls
1151
1152
ax2.text(t_last+2, ymin, label,
1153
verticalalignment='bottom',
1154
horizontalalignment='left',
1155
rotation='vertical',
1156
color=color,
1157
fontsize=int(0.8*self.size_labelfont))
1158
1159
ax2.plot([t_last, t_last], [ymin, ymax], color=color, linestyle=linestyle)
1160
1161
id_arc_last = id_arc_point # memorize edge of last point
1162
1163
i_point += 1
1164
1165
#ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)
1166
ax2.grid(self.is_grid)
1167
if self.titletext != '':
1168
ax2.set_title(self.titletext, fontsize=self.size_titlefont)
1169
1170
ax2.set_xlabel('Time [s]', fontsize=self.size_labelfont)
1171
ax2.set_ylabel('Speed [km/h]', fontsize=self.size_labelfont)
1172
ax2.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
1173
ax2.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
1174
1175
# plot edge info to speed over way graph
1176
# this will put correct edge borders and labels
1177
linestyle = '--'
1178
color = 'k'
1179
cumulative_dists = routeresults.cumulative_dists[id_routeres]
1180
cumulative_dists = np.delete(cumulative_dists, -1)
1181
cumulative_dists = np.insert(cumulative_dists, 0, 0.).tolist()
1182
ids_arc = routeresults.ids_arc[id_routeres]
1183
are_connections = routeresults.is_connection[id_routeres]
1184
print cumulative_dists, ids_arc
1185
1186
for cumulative_dist, id_arc, is_connection in zip(cumulative_dists, ids_arc, are_connections):
1187
1188
#ax.plot([x,x+length],[ymin,ymin],color = colors[i%2],lw = 3*self.width_line)
1189
1190
# ax.text( dist, ymax, ' ID= %s '%(str(id_arc)),
1191
## verticalalignment = 'top',
1192
## horizontalalignment = 'left',
1193
## rotation = 'vertical',
1194
# fontsize = int(0.8*self.size_labelfont))#baseline
1195
1196
if not is_connection:
1197
if edgesresults.ids_edge.has_index(id_arc):
1198
id_edgeres = edgesresults.ids_edge.get_id_from_index(id_arc)
1199
time_wait = edgesresults.times_wait[id_edgeres]
1200
time_wait_junc = edgesresults.times_wait_junc[id_edgeres]
1201
time_wait_tls = edgesresults.times_wait_tls[id_edgeres]
1202
label = r' '
1203
1204
if self.is_waitslabel & (time_wait > 0):
1205
label += ' $T_W=%ds$' % time_wait
1206
1207
if self.is_waitslabel_junction & (time_wait_junc > 0):
1208
label += ' $T_J=%ds$' % time_wait_junc
1209
1210
if self.is_waitslabel_tls & (time_wait_tls > 0):
1211
label += ' $T_{\mathrm{TL}}=%ds$' % time_wait_tls
1212
1213
print ' id_edge', id_arc, 'pos=%df' % cumulative_dist, 'time_wait', time_wait, 'time_wait_junc', time_wait_junc, 'time_wait_tls', time_wait_tls
1214
1215
ax.text(cumulative_dist, ymin, label,
1216
verticalalignment='bottom',
1217
horizontalalignment='left',
1218
rotation='vertical',
1219
color=color,
1220
fontsize=int(0.8*self.size_labelfont))
1221
else:
1222
print 'the edge', id_arc, 'is not in the edgeresult database'
1223
else:
1224
if connectionsresults.ids_connection.has_index(id_arc):
1225
id_connectionres = connectionsresults.ids_connection.get_id_from_index(id_arc)
1226
time_wait = connectionsresults.times_wait[id_connectionres]
1227
## time_wait_junc = connectionsresults.times_wait_junc[id_connectionres]
1228
time_wait_tls = connectionsresults.times_wait_tls[id_connectionres]
1229
label = r' '
1230
1231
if self.is_waitslabel & (time_wait > 0):
1232
label += ' $T_W=%ds$' % time_wait
1233
1234
# if self.is_waitslabel_junction & (time_wait_junc>0):
1235
## label += ' $T_J=%ds$'%time_wait_junc
1236
1237
if self.is_waitslabel_tls & (time_wait_tls > 0):
1238
label += ' $T_{\mathrm{TL}}=%ds$' % time_wait_tls
1239
1240
print ' id_connection', id_arc, 'pos=%df' % x, 'time_wait', time_wait, 'time_wait_junc', time_wait_junc, 'time_wait_tls', time_wait_tls
1241
1242
ax.text(cumulative_dist, ymin, label,
1243
verticalalignment='bottom',
1244
horizontalalignment='left',
1245
rotation='vertical',
1246
color=color,
1247
fontsize=int(0.8*self.size_labelfont))
1248
else:
1249
print 'the connection', id_arc, 'is not in the connectionresult database'
1250
1251
ax.plot([cumulative_dist, cumulative_dist], [ymin, ymax], color=color, linestyle=linestyle)
1252
1253
if not is_connection:
1254
ax.text(cumulative_dist, ymax, ' ID Edge= %s ' % (str(id_arc)),
1255
verticalalignment='top',
1256
horizontalalignment='left',
1257
rotation='vertical',
1258
fontsize=int(0.8*self.size_labelfont)) # baseline
1259
else:
1260
ax.text(cumulative_dist, ymax, ' ID Connection= %s ' % (str(id_arc)),
1261
verticalalignment='top',
1262
horizontalalignment='left',
1263
rotation='vertical',
1264
fontsize=int(0.8*self.size_labelfont)) # baseline
1265
## x += edges.lengths[id_edge]
1266
1267
#ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)
1268
ax.grid(self.is_grid)
1269
if self.titletext != '':
1270
ax.set_title(self.titletext, fontsize=self.size_titlefont)
1271
1272
ax.set_xlabel('Distance [m]', fontsize=self.size_labelfont)
1273
ax.set_ylabel('Speed [km/h]', fontsize=self.size_labelfont)
1274
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
1275
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
1276
1277
# if self.is_save:
1278
# self.save_fig('routeana_speedprofile')
1279
1280
plt.show()
1281
# show_plot()
1282
1283
def get_routeresults(self):
1284
return self.parent.routesresults_matched
1285
1286
def get_scenario(self):
1287
return self.parent.get_scenario()
1288
1289
1290
class EdgeresultPlotter(PlotoptionsMixin, Process):
1291
def __init__(self, results, name='Plot edge results with Matplotlib',
1292
info="Creates plots of different edge results using matplotlib",
1293
logger=None, **kwargs):
1294
1295
self._init_common('routeresultplotter', parent=results, name=name,
1296
info=info, logger=logger)
1297
1298
# print 'Resultplotter.__init__',results,self.parent
1299
attrsman = self.get_attrsman()
1300
1301
self.plotthemefuncs = OrderedDict([
1302
('average slopes', self.plot_average_slopes),
1303
('positive climbs', self.plot_positive_climbs),
1304
('negative climbs', self.plot_negative_climbs),
1305
('average speeds', self.plot_speeds_average),
1306
('inmove speeds', self.plot_speeds_inmotion),
1307
('times wait', self.plot_times_wait),
1308
('times wait_tls', self.plot_times_wait_tls),
1309
('number matched_routes', self.plot_numbers_tot_matched),
1310
('number shortest', self.plot_numbers_tot_shortest),
1311
('total deviation', self.plot_differences_dist_tot_shortest),
1312
('relative deviation', self.plot_differences_dist_rel_shortest),
1313
('usage probabilities by matched routes', self.plot_probabilities_tot_matched),
1314
('estimated flows from matched routes', self.plot_flows_est_matched_routes),
1315
])
1316
self.plottheme = attrsman.add(cm.AttrConf('plottheme', kwargs.get('plottheme', 'average speeds'),
1317
groupnames=['options'],
1318
choices=self.plotthemefuncs.keys(),
1319
name='Plot theme',
1320
info='Theme or edge attribute to be plottet.',
1321
))
1322
self.n_min_matched = attrsman.add(cm.AttrConf('n_min_matched', 3,
1323
groupnames=['options'],
1324
name='Minum number of matched for speed analysis',
1325
info='Only edge contained in almost this number of matched routes\
1326
will be considered for plotting the dynamic\
1327
characteristics of edges (speeds and times).',
1328
))
1329
1330
self.add_plotoptions(**kwargs)
1331
self.add_save_options(**kwargs)
1332
1333
def plot_all_themes(self):
1334
for plottheme in self.plotthemefuncs.keys():
1335
self.plottheme = plottheme
1336
self.show()
1337
1338
def show(self):
1339
print 'EdgeresultPlotter.show', self.plottheme
1340
# if self.axis is None:
1341
#axis = init_plot()
1342
self.init_figures()
1343
fig = self.create_figure()
1344
axis = fig.add_subplot(111)
1345
self.plotthemefuncs[self.plottheme](axis)
1346
1347
print ' self.is_save', self.is_save
1348
if not self.is_save:
1349
print ' show_plot'
1350
show_plot()
1351
else:
1352
figname = 'edgeplot_'+self.plottheme
1353
# print ' savefig',figname
1354
1355
# self.save_fig('edgeplot_'+self.plottheme)
1356
1357
rootfilepath = self.get_scenario().get_rootfilepath()
1358
1359
fig.savefig("%s_%s.%s" % (rootfilepath, figname, self.figformat),
1360
format=self.figformat,
1361
dpi=self.resolution,
1362
# orientation='landscape',
1363
orientation='portrait',
1364
transparent=True)
1365
plt.close(fig)
1366
1367
def get_edgeresults(self):
1368
return self.parent.edgesresults # must have attribute 'ids_edge'
1369
1370
def plot_average_slopes(self, ax):
1371
1372
edges = self.parent.parent.parent.parent.net.edges
1373
ids_edge = edges.get_ids()
1374
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1375
average_slopes = edges.average_slopes
1376
print ids_edge, average_slopes[ids_edge]
1377
self.plot_results_on_map(ax,
1378
values=average_slopes[ids_edge],
1379
ids_edge=ids_edge,
1380
title='Average edge slopes',
1381
valuelabel='Slope',
1382
)
1383
1384
def plot_positive_climbs(self, ax):
1385
1386
edges = self.parent.parent.parent.parent.net.edges
1387
ids_edge = edges.get_ids()
1388
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1389
positive_climbs = edges.positive_climbs
1390
print ids_edge, positive_climbs[ids_edge]
1391
self.plot_results_on_map(ax,
1392
values=positive_climbs[ids_edge],
1393
ids_edge=ids_edge,
1394
title='Average edge slopes',
1395
valuelabel='Slope',
1396
)
1397
1398
def plot_negative_climbs(self, ax):
1399
1400
edges = self.parent.parent.parent.parent.net.edges
1401
ids_edge = edges.get_ids()
1402
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1403
negative_climbs = edges.negative_climbs
1404
print ids_edge, negative_climbs[ids_edge]
1405
self.plot_results_on_map(ax,
1406
values=negative_climbs[ids_edge],
1407
ids_edge=ids_edge,
1408
title='Average edge slopes',
1409
valuelabel='Slope',
1410
)
1411
1412
def plot_differences_dist_rel_shortest(self, ax):
1413
edgesresults = self.get_edgeresults()
1414
ids_result = edgesresults.select_ids(edgesresults.differences_dist_rel_shortest.get_value() > 0)
1415
1416
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1417
1418
self.plot_results_on_map(ax, ids_result,
1419
# edgesresults.differences_dist_tot_shortest[ids_result]/edgesresults.numbers_tot_shortest[ids_result],
1420
edgesresults.differences_dist_rel_shortest[ids_result],
1421
title='Deviation generated per trip',
1422
valuelabel='Generated deviation per trip [m]',
1423
)
1424
1425
def plot_differences_dist_tot_shortest(self, ax):
1426
edgesresults = self.get_edgeresults()
1427
ids_result = edgesresults.get_ids()
1428
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1429
#deviation_tot = edgesresults.differences_dist_tot_shortest
1430
self.plot_results_on_map(ax, ids_result,
1431
edgesresults.differences_dist_tot_shortest[ids_result]/1000,
1432
# deviation_tot[ids_result]/1000,
1433
title='Total deviation generated per edge',
1434
valuelabel='Generated total deviation [km]',
1435
)
1436
1437
def plot_numbers_tot_shortest(self, ax):
1438
edgesresults = self.get_edgeresults()
1439
ids_result = edgesresults.get_ids()
1440
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1441
numbers_tot_shortest = edgesresults.numbers_tot_shortest
1442
self.plot_results_on_map(ax, ids_result,
1443
numbers_tot_shortest[ids_result],
1444
title='Edge usage from shortest routes',
1445
valuelabel='Usage in number of persons',
1446
)
1447
1448
def plot_numbers_tot_matched(self, ax):
1449
edgesresults = self.get_edgeresults()
1450
ids_result = edgesresults.get_ids()
1451
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1452
numbers_tot_matched = edgesresults.numbers_tot_matched
1453
self.plot_results_on_map(ax, ids_result,
1454
numbers_tot_matched[ids_result],
1455
title='Edge usage from matched routes',
1456
valuelabel='Usage in number of persons',
1457
)
1458
1459
def plot_speeds_average(self, ax):
1460
edgesresults = self.parent.edgesresults
1461
1462
print 'plot_speeds_average'
1463
1464
#ids_result = edgesresults.get_ids()
1465
ids_result = edgesresults.select_ids(
1466
edgesresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1467
1468
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1469
speeds_average = self.parent.edgesresults.speed_average
1470
# print ' speeds_average',speeds_average[ids_result]
1471
# print ' ids_result',ids_result
1472
1473
self.plot_results_on_map(ax, ids_result,
1474
speeds_average[ids_result]*3.6,
1475
title='Average edge speeds',
1476
valuelabel='Average edge speeds [km/h]',
1477
)
1478
1479
def plot_speeds_inmotion(self, ax):
1480
edgesresults = self.parent.edgesresults
1481
#ids_result = edgesresults.get_ids()
1482
ids_result = edgesresults.select_ids(
1483
edgesresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1484
1485
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1486
speeds = self.parent.edgesresults.speed_average_in_motion
1487
1488
# print ' speeds_average',speeds[ids_result]
1489
# print ' ids_result',ids_result
1490
1491
self.plot_results_on_map(ax, ids_result,
1492
speeds[ids_result]*3.6,
1493
title='Average edge speeds in motion',
1494
valuelabel='Average edge speeds in motion [km/h]',
1495
)
1496
1497
def plot_times_wait(self, ax):
1498
edgesresults = self.parent.edgesresults
1499
#ids_result = edgesresults.get_ids()
1500
ids_result = edgesresults.select_ids(
1501
edgesresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1502
1503
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1504
times = edgesresults.times_wait
1505
self.plot_results_on_map(ax, ids_result,
1506
times[ids_result],
1507
title='Average wait times',
1508
valuelabel='Average wait times [s]',
1509
)
1510
1511
def plot_times_wait_tls(self, ax):
1512
#ids_result = self.parent.edgesresults.get_ids()
1513
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1514
edgesresults = self.parent.edgesresults
1515
ids_result = edgesresults.select_ids(
1516
edgesresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1517
times = edgesresults.times_wait_tls
1518
self.plot_results_on_map(ax, ids_result,
1519
times[ids_result],
1520
title='Average wait times at Traffic Lights',
1521
valuelabel='Average wait times at TLS [s]',
1522
)
1523
1524
def plot_probabilities_tot_matched(self, ax):
1525
ids_result = self.parent.edgesresults.get_ids()
1526
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1527
self.plot_results_on_map(ax, ids_result,
1528
self.parent.edgesresults.probabilities_tot_matched[ids_result],
1529
title='Probabilities',
1530
valuelabel=r'Enter probabilities [\%]',
1531
)
1532
1533
def plot_flows_est_matched_routes(self, ax):
1534
ids_result = self.parent.edgesresults.get_ids()
1535
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1536
self.plot_results_on_map(ax, ids_result,
1537
self.parent.edgesresults.flows_est[ids_result],
1538
title='Flows',
1539
valuelabel=r'Estimated flows [1/h]',
1540
)
1541
1542
def do(self):
1543
# print 'do',self.edgeattrname
1544
self.show()
1545
return True
1546
1547
1548
class ConnectionresultPlotter(PlotoptionsMixin, Process):
1549
def __init__(self, results, name='Plot connection results with Matplotlib',
1550
info="Creates plots of different connection results using matplotlib",
1551
logger=None, **kwargs):
1552
1553
self._init_common('routeresultplotter', parent=results, name=name,
1554
info=info, logger=logger)
1555
1556
# print 'Resultplotter.__init__',results,self.parent
1557
attrsman = self.get_attrsman()
1558
1559
self.plotthemefuncs = OrderedDict([
1560
('times wait', self.plot_times_wait),
1561
('times wait_tls', self.plot_times_wait_tls),
1562
])
1563
self.plottheme = attrsman.add(cm.AttrConf('plottheme', kwargs.get('plottheme', 'times wait'),
1564
groupnames=['options'],
1565
choices=self.plotthemefuncs.keys(),
1566
name='Plot theme',
1567
info='Theme or edge attribute to be plottet.',
1568
))
1569
1570
self.n_min_matched = attrsman.add(cm.AttrConf('n_min_matched', 3,
1571
groupnames=['options'],
1572
name='Minum number of matched for speed analysis',
1573
info='Only connectors contained in almost this number of matched routes\
1574
will be considered for plotting the dynamic\
1575
characteristics of edges (speeds and times).'))
1576
1577
self.add_plotoptions(**kwargs)
1578
self.add_save_options(**kwargs)
1579
1580
def plot_all_themes(self):
1581
for plottheme in self.plotthemefuncs.keys():
1582
self.plottheme = plottheme
1583
self.show()
1584
1585
def show(self):
1586
print 'connectionresultPlotter.show', self.plottheme
1587
# if self.axis is None:
1588
#axis = init_plot()
1589
self.init_figures()
1590
fig = self.create_figure()
1591
axis = fig.add_subplot(111)
1592
self.plotthemefuncs[self.plottheme](axis)
1593
1594
print ' self.is_save', self.is_save
1595
if not self.is_save:
1596
print ' show_plot'
1597
show_plot()
1598
else:
1599
figname = 'connectionplot_'+self.plottheme
1600
# print ' savefig',figname
1601
1602
# self.save_fig('edgeplot_'+self.plottheme)
1603
1604
rootfilepath = self.get_scenario().get_rootfilepath()
1605
1606
fig.savefig("%s_%s.%s" % (rootfilepath, figname, self.figformat),
1607
format=self.figformat,
1608
dpi=self.resolution,
1609
# orientation='landscape',
1610
orientation='portrait',
1611
transparent=True)
1612
plt.close(fig)
1613
1614
def get_connectionresults(self):
1615
return self.parent.connectionsresults
1616
1617
def plot_times_wait(self, ax):
1618
1619
connectionsresults = self.parent.connectionsresults
1620
#ids_result = edgesresults.get_ids()
1621
1622
ids_result = connectionsresults.select_ids(
1623
connectionsresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1624
#resultattrconf = getattr(self.parent.edgesresults, self.edgeattrname)
1625
times = connectionsresults.times_wait
1626
# print 'TIMES VALUES', times[ids_result]
1627
self.plot_results_on_map(ax,
1628
values=times[ids_result],
1629
title='Average wait times at connectors',
1630
valuelabel='Average wait times [s]',
1631
is_connection_results=True,
1632
ids_connectionres=ids_result)
1633
1634
def plot_times_wait_tls(self, ax):
1635
1636
connectionsresults = self.parent.connectionsresults
1637
ids_result = connectionsresults.select_ids(
1638
connectionsresults.numbers_matched_for_speed_analysis.get_value() > self.n_min_matched)
1639
times = connectionsresults.times_wait_tls
1640
# print 'TIMES VALUES', times[ids_result]
1641
self.plot_results_on_map(ax,
1642
values=times[ids_result],
1643
title='Average wait times at tls connectors',
1644
valuelabel='Average wait times [s]',
1645
is_connection_results=True,
1646
ids_connectionres=ids_result)
1647
1648
def do(self):
1649
# print 'do',self.edgeattrname
1650
self.show()
1651
return True
1652
1653
1654
class AlternativeRoutesPlotter(PlotoptionsMixin, Process):
1655
def __init__(self, results, name='Plot edge of alternative routes with Matplotlib',
1656
info="Creates plots of different edge results using matplotlib",
1657
logger=None, **kwargs):
1658
1659
self._init_common('routeresultplotter', parent=results, name=name,
1660
info=info, logger=logger)
1661
1662
# print 'Resultplotter.__init__',results,self.parent
1663
attrsman = self.get_attrsman()
1664
1665
self.color_chosen = attrsman.add(cm.AttrConf('color_chosen', kwargs.get('color_chosen', np.array([0.9, 0.2, 0.2, 0.99], dtype=np.float32)),
1666
groupnames=['options'],
1667
perm='wr',
1668
metatype='color',
1669
name='Color Alt. chosen',
1670
info='Color of chosen alternative.',
1671
))
1672
1673
self.color2 = attrsman.add(cm.AttrConf('color2', kwargs.get('color2', np.array([0.2, 0.9, 0.2, 0.99], dtype=np.float32)),
1674
groupnames=['options'],
1675
perm='wr',
1676
metatype='color',
1677
name='Color Alt. 2',
1678
info='Color of second alternative.',
1679
))
1680
1681
kwargs_fixed = {'plottype': 'polygons',
1682
'is_widthvalue': True,
1683
'is_colorvalue': False, # colors assigned explicitely
1684
'is_value_range': True,
1685
'value_range_min': 0,
1686
'value_range_max': 2,
1687
'color_fill': np.array([0.9, 0.2, 0.2, 0.99], dtype=np.float32),
1688
'printformat': '',
1689
}
1690
kwargs.update(kwargs_fixed)
1691
1692
self.add_plotoptions(**kwargs)
1693
self.add_save_options(**kwargs)
1694
1695
# configure fixed options as privat (non visible for gui)
1696
attrsman = self.get_attrsman()
1697
for attrname in kwargs_fixed.keys():
1698
attrconf = attrsman.get_config(attrname)
1699
attrconf.add_groupnames(['_private'])
1700
1701
def show(self):
1702
print 'AlternativeRoutesPlotter.show'
1703
# if self.axis is None:
1704
#axis = init_plot()
1705
title = 'Route alternatives'
1706
valuelabel = ''
1707
self.init_figures()
1708
fig = self.create_figure()
1709
axis = fig.add_subplot(111)
1710
1711
altroutesresults = self.parent.altroutesresults
1712
ids_res = altroutesresults.get_ids()
1713
net = self.parent.get_scenario().net
1714
edges = net.edges
1715
1716
axis.set_axis_bgcolor(self.color_background)
1717
if self.is_show_network:
1718
plot_net(axis, net, color_edge=self.color_network, width_edge=2,
1719
color_node=self.color_nodes, alpha=self.alpha_net)
1720
1721
if self.is_show_facilities:
1722
facilities = self.parent.get_scenario().landuse.facilities
1723
plot_facilities(axis, facilities, color_building=self.color_facilities,
1724
color_outline=self.color_borders,
1725
width_line=2, alpha=self.alpha_facilities,
1726
)
1727
if self.is_show_maps:
1728
plot_maps(axis, self.parent.get_scenario().landuse.maps, alpha=self.alpha_maps)
1729
1730
# if self.is_value_range:
1731
# value_range = (self.value_range_min, self.value_range_max)
1732
# else:
1733
value_range = (0, 2)
1734
1735
for id_trip, id_choice, chosen, ids_edge_all in zip(
1736
altroutesresults.ids_trip[ids_res],
1737
altroutesresults.ids_alt[ids_res],
1738
altroutesresults.choices[ids_res],
1739
altroutesresults.ids_edges[ids_res]):
1740
# print ' id_trip',id_trip,'ids_edge',ids_edge_all
1741
if ids_edge_all is not None:
1742
if id_choice == 1:
1743
ids_edge = ids_edge_all
1744
1745
else:
1746
ids_edge = ids_edge_all[1:-1]
1747
1748
if chosen:
1749
color = self.color_chosen # use predefined color sor selected
1750
elif id_choice == 2:
1751
color = self.color2
1752
else:
1753
color = get_color(id_choice)
1754
1755
plot_edgevalues_lines(axis,
1756
ids_edge=ids_edge,
1757
values=np.ones(len(ids_edge), dtype=np.float32)*(int(chosen)+1),
1758
edges=net.edges,
1759
width_max=self.resultwidth,
1760
alpha=self.alpha_results,
1761
printformat=self.printformat,
1762
color_outline=self.color_outline,
1763
color_fill=color,
1764
color_label=self.color_label,
1765
is_antialiased=True,
1766
is_fill=self.is_colorvalue,
1767
is_widthvalue=self.is_widthvalue,
1768
length_arrowhead=self.length_arrowhead,
1769
fontsize=self.size_labelfont,
1770
valuelabel=False,
1771
value_range=value_range,
1772
is_colorbar=False,
1773
)
1774
else:
1775
print 'WARNING in AlternativeRoutesPlotter.show ids_edge=', ids_edge_all, 'of id_trip', id_trip
1776
1777
if self.is_show_title:
1778
axis.set_title(title, fontsize=self.size_titlefont)
1779
1780
axis.axis('equal')
1781
# ax.legend(loc='best',shadow=True)
1782
1783
axis.grid(self.is_grid)
1784
axis.set_xlabel('West-East [m]', fontsize=self.size_labelfont)
1785
axis.set_ylabel('South-North [m]', fontsize=self.size_labelfont)
1786
axis.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
1787
axis.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
1788
1789
## save or show
1790
print ' self.is_save', self.is_save
1791
if not self.is_save:
1792
print ' show_plot'
1793
show_plot()
1794
else:
1795
self.save_fig('altroutesplot')
1796
plt.close(fig)
1797
1798
1799
class RouteresultPlotter(PlotoptionsMixin, Process):
1800
def __init__(self, results, name='Plot route results with Matplotlib',
1801
info="Creates plots of different route results using matplotlib",
1802
logger=None, **kwargs):
1803
1804
self._init_common('routeresultplotter', parent=results, name=name,
1805
info=info, logger=logger)
1806
1807
print 'Resultplotter.__init__', results, self.parent
1808
attrsman = self.get_attrsman()
1809
1810
mapmatching = self.parent.parent
1811
scenario = mapmatching.get_scenario()
1812
self.zones = scenario.landuse.zones
1813
self.is_plot_bike_availability_ffbss_zone = attrsman.add(cm.AttrConf('is_plot_bike_availability_ffbss_zone', kwargs.get('is_plot_bike_availability_ffbss_zone', True),
1814
groupnames=['options'],
1815
name='Plot bike relative availability for FFBSS in a zone',
1816
info='Plot the variation of the bike availability in a day for a zone. Either 24 or 96 bins are recommended',
1817
))
1818
1819
if len(self.zones) > 0:
1820
1821
self.zone_ffbss = attrsman.add(cm.AttrConf('zone_ffbss', kwargs.get('zone_ffbss', self.zones.ids_sumo[1]),
1822
groupnames=['options'],
1823
choices=self.zones.ids_sumo,
1824
name='Zone for the FFBSS availability analysis',
1825
info='Select the zone for the FFBSS availability analysis.',
1826
))
1827
1828
self.is_analyze_bike_availability_ffbss_zones = attrsman.add(cm.AttrConf('is_analyze_bike_availability_ffbss_zones', kwargs.get('is_analyze_bike_availability_ffbss_zones', True),
1829
groupnames=['options'],
1830
name='Analize bike relative availability for FFBSS in all zones',
1831
info='Plot the absolute and relative (for zones with almost n_bins trips) variation of the bike availability in a day for all zones. Either 24 or 96 bins are recommended',
1832
))
1833
1834
self.is_plot_bike_availability_ffbss = attrsman.add(cm.AttrConf('is_plot_bike_availability_ffbss', kwargs.get('is_plot_bike_availability_ffbss', False),
1835
groupnames=['options'],
1836
name='Plot bike usage distribution',
1837
info='Plot the number of bikes that are doing a trip simultaneously in the day period. It require an high number of bins',
1838
))
1839
1840
self.is_plot_deptimedistrib = attrsman.add(cm.AttrConf('is_plot_deptimedistrib', kwargs.get('is_plot_deptimedistrib', False),
1841
groupnames=['options'],
1842
name='Plot departure time distribution',
1843
info='Plot cumulative distribution on trip departure time of matched route.',
1844
))
1845
1846
# comprison matched shortest
1847
self.is_plot_lengthdistrib = attrsman.add(cm.AttrConf('is_plot_lengthdistrib', kwargs.get('is_plot_lengthdistrib', True),
1848
groupnames=['options'],
1849
name='Plot length distribution',
1850
info='Plot cumulative distribution on length of matched route and shortest route.',
1851
))
1852
1853
self.is_plot_lengthprob = attrsman.add(cm.AttrConf('is_plot_lengthprob', kwargs.get('is_plot_lengthprob', False),
1854
groupnames=['options'],
1855
name='Plot length probabilities',
1856
info='Plot probabilities length of matched route and shortest route.',
1857
))
1858
1859
self.is_plot_lengthdistrib_by_class = attrsman.add(cm.AttrConf('is_plot_lengthdistrib_by_class', kwargs.get('is_plot_lengthdistrib_by_class', False),
1860
groupnames=['options'],
1861
name='Plot class length distribution',
1862
info='Plot mean values of length of matched route and shortest route for different trip length classes.',
1863
))
1864
1865
self.distance_class = attrsman.add(cm.AttrConf('distance_class', kwargs.get('distance_class', 2000),
1866
groupnames=['options'],
1867
name='Class distance',
1868
info='Distance to generate trip length classes.',
1869
))
1870
1871
self.is_plot_lengthratio = attrsman.add(cm.AttrConf('is_plot_lengthratio', kwargs.get('is_plot_lengthratio', False),
1872
groupnames=['options'],
1873
name='Plot length ratio',
1874
info='Plot cumulative distribution on length ratio between shortest route and matched route.',
1875
))
1876
1877
self.is_plot_lengthoverlap = attrsman.add(cm.AttrConf('is_plot_lengthoverlap', kwargs.get('is_plot_lengthoverlap', False),
1878
groupnames=['options'],
1879
name='Plot overlap with shortest',
1880
info='Plot cumulative distribution on the realtive length overlap between shortest route and matched route.',
1881
))
1882
1883
self.is_plot_lengthoverlap_fastest = attrsman.add(cm.AttrConf('is_plot_lengthoverlap_fastest', kwargs.get('is_plot_lengthoverlap_fastest', False),
1884
groupnames=['options'],
1885
name='Plot overlap with fastest',
1886
info='Plot cumulative distribution on on the realtive length between fastest route and matched route.',
1887
))
1888
1889
self.is_plot_mixshare = attrsman.add(cm.AttrConf('is_plot_mixshare', kwargs.get('is_plot_mixshare', False),
1890
groupnames=['options'],
1891
name='Plot mixed share',
1892
info='Plot cumulative distribution of share of mixed access roads of shortest route and matched route.',
1893
))
1894
1895
self.is_plot_exclusiveshare = attrsman.add(cm.AttrConf('is_plot_exclusiveshare', kwargs.get('is_plot_exclusiveshare', False),
1896
groupnames=['options'],
1897
name='Plot exclusive share',
1898
info='Plot cumulative distribution of share of exclusive access roads of shortest route and matched route.',
1899
))
1900
1901
self.is_plot_lowpriorityshare = attrsman.add(cm.AttrConf('is_plot_lowpriorityshare', kwargs.get('is_plot_lowpriorityshare', False),
1902
groupnames=['options'],
1903
name='Plot low priority share',
1904
info='Plot cumulative distribution of share of low priority roads of shortest route and matched route.',
1905
))
1906
1907
self.is_plot_nodesdensity = attrsman.add(cm.AttrConf('is_plot_nodesdensity', kwargs.get('is_plot_nodesdensity', False),
1908
groupnames=['options'],
1909
name='Plot node ratio',
1910
info='Plot cumulative distribution of node ratio between shortest route and matched route.',
1911
))
1912
1913
self.is_plot_tldensity = attrsman.add(cm.AttrConf('is_plot_tldensity', kwargs.get('is_plot_tldensity', False),
1914
groupnames=['options'],
1915
name='Plot TL ratio',
1916
info='Plot cumulative distribution of traffic light ratio between shortest route and matched route.',
1917
))
1918
self.is_prioritychangedensity = attrsman.add(cm.AttrConf('is_prioritychangedensity', kwargs.get('is_prioritychangedensity', False),
1919
groupnames=['options'],
1920
name='Plot prio. change dens.',
1921
info='Plot cumulative distribution of priority change denities between shortest route and matched route.',
1922
))
1923
1924
# comprison non-overlapping matched and shortest
1925
self.is_plot_lengthratio_nonoverlap = attrsman.add(cm.AttrConf('is_plot_lengthratio_nonoverlap', kwargs.get('is_plot_lengthratio_nonoverlap', False),
1926
groupnames=['options'],
1927
name='Plot length ratio non-overlap',
1928
info='Plot cumulative distribution on length ratio between non-overlapping parts of shortest route and matched route.',
1929
))
1930
1931
self.is_plot_mixshare_nonoverlap = attrsman.add(cm.AttrConf('is_plot_mixshare_nonoverlap', kwargs.get('is_plot_mixshare_nonoverlap', False),
1932
groupnames=['options'],
1933
name='Plot mixed share non-overlap',
1934
info='Plot cumulative distribution of share of mixed access roads of non-overlapping parts of shortest route and matched route.',
1935
))
1936
1937
self.is_plot_exclusiveshare_nonoverlap = attrsman.add(cm.AttrConf('is_plot_exclusiveshare_nonoverlap', kwargs.get('is_plot_exclusiveshare_nonoverlap', False),
1938
groupnames=['options'],
1939
name='Plot exclusive share non-overlap',
1940
info='Plot cumulative distribution of share of exclusive access roads of non-overlapping parts of shortest route and matched route.',
1941
))
1942
1943
self.is_plot_lowpriorityshare_nonoverlap = attrsman.add(cm.AttrConf('is_plot_lowpriorityshare_nonoverlap', kwargs.get('is_plot_lowpriorityshare_nonoverlap', False),
1944
groupnames=['options'],
1945
name='Plot low priority share non-overlap',
1946
info='Plot cumulative distribution of share of low priority roads of non-overlapping parts of shortest route and matched route.',
1947
))
1948
1949
self.is_plot_nodesdensity_nonoverlap = attrsman.add(cm.AttrConf('is_plot_nodesdensity_nonoverlap', kwargs.get('is_plot_nodesdensity_nonoverlap', False),
1950
groupnames=['options'],
1951
name='Plot node ratio non-overlap',
1952
info='Plot cumulative distribution of node ratio between non-overlapping parts of shortest route and matched route.',
1953
))
1954
1955
self.is_plot_tldensity_nonoverlap = attrsman.add(cm.AttrConf('is_plot_tldensity_nonoverlap', kwargs.get('is_plot_tldensity_nonoverlap', False),
1956
groupnames=['options'],
1957
name='Plot TL ratio non-overlap',
1958
info='Plot cumulative distribution of traffic light ratio between non-overlapping parts of shortest route and matched route.',
1959
))
1960
1961
self.is_prioritychangedensity_nonoverlap = attrsman.add(cm.AttrConf('is_prioritychangedensity_nonoverlap', kwargs.get('is_prioritychangedensity_nonoverlap', False),
1962
groupnames=['options'],
1963
name='Plot prio. change dens. non-overlap',
1964
info='Plot cumulative distribution of priority change denities between non-overlapping parts of shortest route and matched route.',
1965
))
1966
1967
# other
1968
self.n_bins = attrsman.add(cm.AttrConf('n_bins', kwargs.get('n_bins', 10),
1969
groupnames=['options'],
1970
name='Bin number',
1971
info='Number of bins for histograms.',
1972
))
1973
1974
# self.add_plotoptions(**kwargs)
1975
self.is_title = attrsman.add(cm.AttrConf('is_title', kwargs.get('is_title', False),
1976
groupnames=['options'],
1977
name='Show title',
1978
info='Show title of diagrams.',
1979
))
1980
1981
self.title = attrsman.add(cm.AttrConf('title', kwargs.get('title', ''),
1982
groupnames=['options'],
1983
name='Title',
1984
info='Title text, if blank then default values are used. Only in combination with show title option.',
1985
))
1986
1987
self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont', 32),
1988
groupnames=['options'],
1989
name='Title fontsize',
1990
info='Title fontsize.',
1991
))
1992
1993
self.size_labelfont = attrsman.add(cm.AttrConf('size_labelfont', kwargs.get('size_labelfont', 24),
1994
groupnames=['options'],
1995
name='Label fontsize',
1996
info='Label fontsize.',
1997
))
1998
1999
self.width_line = attrsman.add(cm.AttrConf('width_line', kwargs.get('width_line', 2),
2000
groupnames=['options'],
2001
perm='wr',
2002
name='Line width',
2003
info='Width of plotted lines.',
2004
))
2005
2006
self.color_line = attrsman.add(cm.AttrConf('color_line', kwargs.get('color_line', np.array([0, 0, 0, 1], dtype=np.float32)),
2007
groupnames=['options'],
2008
perm='wr',
2009
metatype='color',
2010
name='Line color',
2011
info='Color of line in various diagrams.',
2012
))
2013
2014
# COLOR_MATCHED_ROUTE,COLOR_SHORTEST_ROUTE,COLOR_FASTEST_ROUTE
2015
self.color_matched = attrsman.add(cm.AttrConf('color_matched', kwargs.get('color_matched', COLOR_MATCHED_ROUTE.copy()),
2016
groupnames=['options'],
2017
perm='wr',
2018
metatype='color',
2019
name='Color matched data',
2020
info='Color of matched data in various diagrams.',
2021
))
2022
2023
self.color_shortest = attrsman.add(cm.AttrConf('color_shortest', kwargs.get('color_shortest', COLOR_SHORTEST_ROUTE.copy()),
2024
groupnames=['options'],
2025
perm='wr',
2026
metatype='color',
2027
name='Color shortest route data',
2028
info='Color of shortest route data in various diagrams.',
2029
))
2030
2031
self.color_fastest = attrsman.add(cm.AttrConf('color_fastest', kwargs.get('color_fastest', COLOR_FASTEST_ROUTE.copy()),
2032
groupnames=['options'],
2033
perm='wr',
2034
metatype='color',
2035
name='Color fastest route data',
2036
info='Color of fastest route data in various diagrams.',
2037
))
2038
2039
self.printformat = attrsman.add(cm.AttrConf('printformat', kwargs.get('printformat', '%.1f'),
2040
choices=OrderedDict([
2041
('Show no values', ''),
2042
('x', '%.d'),
2043
('x.x', '%.1f'),
2044
('x.xx', '%.2f'),
2045
('x.xxx', '%.3f'),
2046
('x.xxxx', '%.4f'),
2047
]),
2048
groupnames=['options'],
2049
name='Label formatting',
2050
info='Print formatting of value label in graphical representation.',
2051
))
2052
2053
self.color_label = attrsman.add(cm.AttrConf('color_label', kwargs.get('color_label', np.array([0, 0, 0, 1], dtype=np.float32)),
2054
groupnames=['options'],
2055
perm='wr',
2056
metatype='color',
2057
name='Label color',
2058
info='Color of value label in graphical representation.',
2059
))
2060
2061
self.is_grid = attrsman.add(cm.AttrConf('is_grid', kwargs.get('is_grid', True),
2062
groupnames=['options'],
2063
name='Show grid?',
2064
info='If True, shows a grid on the graphical representation.',
2065
))
2066
self.color_background = attrsman.add(cm.AttrConf('color_background', kwargs.get('color_background', np.array([1, 1, 1, 1], dtype=np.float32)),
2067
groupnames=['options'],
2068
perm='wr',
2069
metatype='color',
2070
name='Background color',
2071
info='Background color of schematic network in the background.',
2072
))
2073
2074
self.add_save_options(**kwargs)
2075
2076
def show(self):
2077
# print 'show',self.edgeattrname
2078
# if self.axis is None:
2079
self.init_figures()
2080
plt.rc('lines', linewidth=self.width_line)
2081
# plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b', 'y']) +
2082
# cycler('linestyle', ['-', '--', ':', '-.'])))
2083
if self.is_plot_lengthratio:
2084
self.plot_lengthratio()
2085
2086
if self.is_plot_lengthoverlap:
2087
self.plot_lengthoverlap()
2088
2089
if self.is_plot_lengthoverlap_fastest:
2090
self.plot_lengthoverlap_fastest()
2091
2092
if self.is_plot_lengthdistrib:
2093
self.plot_lengthdistrib()
2094
2095
if self.is_plot_lengthprob:
2096
self.plot_lengthprob()
2097
2098
if self.is_plot_lengthdistrib_by_class:
2099
self.plot_lengthdistrib_by_class()
2100
2101
# --
2102
if self.is_plot_lengthdistrib:
2103
self.plot_lengthdistrib()
2104
2105
if self.is_plot_mixshare:
2106
self.plot_mixshare()
2107
2108
if self.is_plot_exclusiveshare:
2109
self.plot_exclusiveshare()
2110
2111
if self.is_plot_lowpriorityshare:
2112
self.plot_lowpriorityshare()
2113
2114
if self.is_plot_nodesdensity:
2115
self.plot_nodesdensity()
2116
2117
if self.is_plot_tldensity:
2118
self.plot_tldensity()
2119
2120
if self.is_prioritychangedensity:
2121
self.plot_prioritychangedensity()
2122
2123
# non overlapping
2124
if self.is_plot_lengthratio_nonoverlap:
2125
self.plot_lengthratio_nonoverlap()
2126
2127
if self.is_plot_mixshare_nonoverlap:
2128
self.plot_mixshare_nonoverlap()
2129
2130
if self.is_plot_exclusiveshare_nonoverlap:
2131
self.plot_exclusiveshare_nonoverlap()
2132
2133
if self.is_plot_lowpriorityshare_nonoverlap:
2134
self.plot_lowpriorityshare_nonoverlap()
2135
2136
if self.is_plot_nodesdensity_nonoverlap:
2137
self.plot_nodesdensity_nonoverlap()
2138
2139
if self.is_plot_tldensity_nonoverlap:
2140
self.plot_tldensity_nonoverlap()
2141
2142
if self.is_prioritychangedensity_nonoverlap:
2143
self.plot_prioritychangedensity_nonoverlap()
2144
2145
if self.is_plot_deptimedistrib:
2146
self.plot_deptimedistrib()
2147
2148
if self.is_plot_bike_availability_ffbss:
2149
self.plot_bike_availability_ffbss()
2150
2151
if self.is_plot_bike_availability_ffbss_zone:
2152
self.plot_bike_availability_ffbss_zone()
2153
2154
if self.is_analyze_bike_availability_ffbss_zones:
2155
self.analyze_bike_availability_ffbss_zones()
2156
2157
if not self.is_save:
2158
show_plot()
2159
2160
def plot_bike_availability_ffbss(self):
2161
print 'plot_bike_availability_ffbss'
2162
# Print the number of bikes simultaneously used every 24h/n_bins hours by selecting traces of a particular day
2163
fig = self.create_figure()
2164
mapmatching = self.parent.parent
2165
trips = mapmatching.trips
2166
ids_trip = trips.get_ids()[(trips.are_selected[trips.get_ids()] == True)]
2167
dep_arr_times = np.zeros((len(ids_trip), 2))
2168
for i, id_trip in zip(range(len(ids_trip)), ids_trip):
2169
t = time.localtime(trips.timestamps[id_trip])
2170
dep_arr_times[i, 0] = t.tm_hour + t.tm_min/60.0 + t.tm_sec/3600.0
2171
dep_arr_times[i, 1] = dep_arr_times[i, 0] + trips.durations_gps[id_trip]/3600.0
2172
self.n_bins
2173
## dep_arr_times = np.sort(dep_arr_times.sort, axis = 0)
2174
print dep_arr_times[:1000]
2175
ax = fig.add_subplot(111)
2176
x_min = min(dep_arr_times[:, 0])
2177
x_max = max(dep_arr_times[:, 0])
2178
bins = np.linspace(x_min, x_max, self.n_bins)
2179
bike_usage = np.zeros(self.n_bins)
2180
2181
for id_trip, dep_arr_time in zip(ids_trip, dep_arr_times):
2182
for bin, i in zip(bins, range(self.n_bins)):
2183
if dep_arr_time[0] < bin and dep_arr_time[1] > bin:
2184
bike_usage[i-1] += 1
2185
print bike_usage
2186
bincenters = plt.plot(bins, bike_usage, color=self.color_matched,
2187
label='Bike usage distribution of GPS Mobike traces')
2188
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2189
ax.grid(self.is_grid)
2190
if self.is_title:
2191
ax.set_title('Bike usage distribution of GPS Mobike traces', fontsize=self.size_titlefont)
2192
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2193
ax.set_ylabel('Bike usage', fontsize=self.size_labelfont)
2194
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2195
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2196
if self.is_save:
2197
self.save_fig('bike_usage')
2198
2199
def plot_bike_availability_ffbss_zone(self):
2200
print 'plot_bike_availability_ffbss_zone'
2201
# Plot the difference between attracted and generated trips froma zone in a day every 24h/n_bins hours
2202
fig = self.create_figure()
2203
mapmatching = self.parent.parent
2204
trips = mapmatching.trips
2205
points = mapmatching.points
2206
ids_trip = trips.get_ids()
2207
ids_trip = ids_trip[(trips.are_selected[ids_trip] == True) & (trips.ids_points[ids_trip] != int)]
2208
ids_points = trips.ids_points[ids_trip]
2209
zone = self.zone_ffbss
2210
scenario = mapmatching.get_scenario()
2211
zones = scenario.landuse.zones
2212
zone_shape = zones.shapes[zones.ids_sumo.get_id_from_index(self.zone_ffbss)]
2213
n_bins = self.n_bins
2214
generated_trips = np.zeros((n_bins))
2215
attracted_trips = np.zeros((n_bins))
2216
2217
for id_trip, ids_point in zip(ids_trip, ids_points):
2218
id_initial_point = ids_point[0]
2219
id_final_point = ids_point[-1]
2220
print id_trip
2221
starting_time = np.int(points.timestamps[id_initial_point] % 86400/86400.*np.float(n_bins))
2222
arriving_time = np.int(points.timestamps[id_final_point] % 86400/86400.*np.float(n_bins))
2223
2224
if is_point_in_polygon(mapmatching.points.coords[id_initial_point], zone_shape):
2225
generated_trips[starting_time] += 1
2226
2227
if is_point_in_polygon(mapmatching.points.coords[id_final_point], zone_shape):
2228
attracted_trips[arriving_time] += 1
2229
2230
availability = np.cumsum(attracted_trips) - np.cumsum(generated_trips)
2231
bins = np.linspace(0, 24, num=n_bins)
2232
np.savetxt('generated_trips_%s.txt' % (zone), generated_trips)
2233
np.savetxt('attracted_trips_%s.txt' % (zone), attracted_trips)
2234
2235
ax = fig.add_subplot(131)
2236
bincenters = plt.plot(bins, availability, color=self.color_matched,
2237
label='Bikes availability')
2238
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2239
ax.grid(self.is_grid)
2240
if self.is_title:
2241
ax.set_title('Bikes relativeavailability during time', fontsize=self.size_titlefont)
2242
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2243
ax.set_ylabel('Bike Relative Availability', fontsize=self.size_labelfont)
2244
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2245
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2246
2247
ax = fig.add_subplot(132)
2248
bincenters = plt.plot(bins, generated_trips, color=self.color_matched,
2249
label='Generated bikes')
2250
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2251
ax.grid(self.is_grid)
2252
if self.is_title:
2253
ax.set_title('Generated bikes during time', fontsize=self.size_titlefont)
2254
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2255
ax.set_ylabel('Generated bikes', fontsize=self.size_labelfont)
2256
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2257
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2258
2259
ax = fig.add_subplot(133)
2260
bincenters = plt.plot(bins, attracted_trips, color=self.color_matched,
2261
label='Attracted bikes')
2262
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2263
ax.grid(self.is_grid)
2264
if self.is_title:
2265
ax.set_title('Attracted bikes during time', fontsize=self.size_titlefont)
2266
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2267
ax.set_ylabel('Attracted bikes', fontsize=self.size_labelfont)
2268
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2269
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2270
if self.is_save:
2271
self.save_fig('bike_availability')
2272
2273
def analyze_bike_availability_ffbss_zones(self):
2274
print 'analyze_bike_availability_ffbss_zones'
2275
# Save a .txt file with generated trips and attracted trips every 24h/n_bins hours for each zone with selected trips
2276
fig = self.create_figure()
2277
mapmatching = self.parent.parent
2278
trips = mapmatching.trips
2279
points = mapmatching.points
2280
ids_trip = trips.get_ids()
2281
ids_trip = ids_trip[(trips.are_selected[ids_trip] == True) & (trips.ids_points[ids_trip] != int)]
2282
ids_points = trips.ids_points[ids_trip]
2283
zone = self.zone_ffbss
2284
scenario = mapmatching.get_scenario()
2285
zones = scenario.landuse.zones
2286
n_zone = len(zones.get_ids())
2287
n_bins = self.n_bins
2288
generated_trips = np.zeros((n_zone, n_bins))
2289
attracted_trips = np.zeros((n_zone, n_bins))
2290
for id_trip, ids_point in zip(ids_trip, ids_points):
2291
id_initial_point = ids_point[0]
2292
id_final_point = ids_point[-1]
2293
print id_trip
2294
starting_time = np.int(points.timestamps[id_initial_point] % 86400/86400.*np.float(n_bins))
2295
arriving_time = np.int(points.timestamps[id_final_point] % 86400/86400.*np.float(n_bins))
2296
i = 0
2297
for zone in zones.get_ids():
2298
zone_shape = zones.shapes[zone]
2299
if is_point_in_polygon(mapmatching.points.coords[id_initial_point], zone_shape):
2300
generated_trips[i, starting_time] += 1
2301
break
2302
i += 1
2303
i = 0
2304
for zone in zones.get_ids():
2305
zone_shape = zones.shapes[zone]
2306
if is_point_in_polygon(mapmatching.points.coords[id_final_point], zone_shape):
2307
attracted_trips[i, arriving_time] += 1
2308
break
2309
i += 1
2310
np.savetxt('generated_trips.txt', generated_trips)
2311
np.savetxt('attracted_trips.txt', attracted_trips)
2312
2313
availability = attracted_trips - generated_trips
2314
for row in range(len(availability[:, 0])):
2315
availability[row, :] = np.cumsum(availability[row, :])
2316
2317
bins = np.linspace(0, 24, num=n_bins)
2318
np.savetxt('generated_trips_%s.txt' % (zone), generated_trips)
2319
np.savetxt('attracted_trips_%s.txt' % (zone), attracted_trips)
2320
2321
ax = fig.add_subplot(231)
2322
for row in range(len(availability[:, 0])):
2323
bincenters = plt.plot(bins, availability[row, :], color=self.color_matched)
2324
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2325
ax.grid(self.is_grid)
2326
if self.is_title:
2327
ax.set_title('Bikes relativeavailability during time', fontsize=self.size_titlefont)
2328
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2329
ax.set_ylabel('Bike Relative Availability', fontsize=self.size_labelfont)
2330
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2331
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2332
2333
ax = fig.add_subplot(232)
2334
for row in range(len(generated_trips[:, 0])):
2335
bincenters = plt.plot(bins, generated_trips[row, :], color=self.color_matched)
2336
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2337
ax.grid(self.is_grid)
2338
if self.is_title:
2339
ax.set_title('Generated bikes during time', fontsize=self.size_titlefont)
2340
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2341
ax.set_ylabel('Generated bikes', fontsize=self.size_labelfont)
2342
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2343
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2344
2345
ax = fig.add_subplot(233)
2346
for row in range(len(attracted_trips[:, 0])):
2347
bincenters = plt.plot(bins, attracted_trips[row, :], color=self.color_matched)
2348
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2349
ax.grid(self.is_grid)
2350
if self.is_title:
2351
ax.set_title('Attracted bikes during time', fontsize=self.size_titlefont)
2352
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2353
ax.set_ylabel('Attracted bikes', fontsize=self.size_labelfont)
2354
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2355
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2356
if self.is_save:
2357
self.save_fig('bike_availability')
2358
2359
# plot relative values
2360
availability2 = np.zeros((len(availability[:, 0]), len(availability[0, :])))
2361
generated_trips2 = np.zeros((len(availability[:, 0]), len(availability[0, :])))
2362
attracted_trips2 = np.zeros((len(availability[:, 0]), len(availability[0, :])))
2363
2364
for row in range(len(availability[:, 0])):
2365
availability2[row, :] = availability[row, :]/np.sum(np.absolute(availability[row, :]))
2366
generated_trips2[row, :] = generated_trips[row, :]/np.sum(generated_trips[row, :])
2367
attracted_trips2[row, :] = attracted_trips[row, :]/np.sum(attracted_trips[row, :])
2368
2369
ax = fig.add_subplot(234)
2370
for row in range(len(availability[:, 0])):
2371
if np.sum(generated_trips[row, :]) > n_bins and np.sum(attracted_trips[row, :]) > n_bins:
2372
bincenters = plt.plot(bins, availability2[row, :], color=self.color_matched)
2373
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2374
ax.grid(self.is_grid)
2375
if self.is_title:
2376
ax.set_title('Bikes relativeavailability during time', fontsize=self.size_titlefont)
2377
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2378
ax.set_ylabel('Bike Relative Availability', fontsize=self.size_labelfont)
2379
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2380
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2381
2382
ax = fig.add_subplot(235)
2383
for row in range(len(generated_trips[:, 0])):
2384
if np.sum(generated_trips[row, :]) > n_bins and np.sum(attracted_trips[row, :]) > n_bins:
2385
bincenters = plt.plot(bins, generated_trips2[row, :], color=self.color_matched)
2386
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2387
ax.grid(self.is_grid)
2388
if self.is_title:
2389
ax.set_title('Generated bikes during time', fontsize=self.size_titlefont)
2390
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2391
ax.set_ylabel('Generated bikes', fontsize=self.size_labelfont)
2392
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2393
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2394
2395
ax = fig.add_subplot(236)
2396
for row in range(len(attracted_trips[:, 0])):
2397
if np.sum(generated_trips[row, :]) > n_bins and np.sum(attracted_trips[row, :]) > n_bins:
2398
bincenters = plt.plot(bins, attracted_trips2[row, :], color=self.color_matched)
2399
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2400
ax.grid(self.is_grid)
2401
if self.is_title:
2402
ax.set_title('Attracted bikes during time', fontsize=self.size_titlefont)
2403
ax.set_xlabel('time [h]', fontsize=self.size_labelfont)
2404
ax.set_ylabel('Attracted bikes', fontsize=self.size_labelfont)
2405
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2406
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2407
if self.is_save:
2408
self.save_fig('bike_availability')
2409
2410
def plot_deptimedistrib(self):
2411
print 'plot_deptimedistrib'
2412
fig = self.create_figure()
2413
mapmatching = self.parent.parent
2414
trips = mapmatching.trips
2415
ids_trip = trips.get_ids()
2416
hour_departure = np.zeros(len(ids_trip))
2417
for i, id_trip in zip(range(len(ids_trip)), ids_trip):
2418
t = time.localtime(trips.timestamps[id_trip])
2419
hour_departure[i] = t.tm_hour + t.tm_min/60.0 + t.tm_sec/3600.0
2420
# print hour_departure[:1000]
2421
2422
ax = fig.add_subplot(111)
2423
x_min = min(hour_departure)
2424
x_max = max(hour_departure)
2425
if self.n_bins < 0:
2426
bins = np.arange(x_min, x_max + 1, 1)
2427
2428
else:
2429
n_bins = self.n_bins
2430
bins = np.linspace(x_min, x_max, n_bins)
2431
2432
# print ' bins',bins
2433
bincenters = plt.hist(hour_departure, bins=bins, color=self.color_line,
2434
density=True,
2435
histtype='stepfilled',
2436
label='Departure time (hour) distribution')
2437
2438
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2439
ax.grid(self.is_grid)
2440
if self.is_title:
2441
if self.title == "":
2442
title = 'Departure time distribution of GPS traces'
2443
else:
2444
title = self.title
2445
ax.set_title(title, fontsize=self.size_titlefont)
2446
ax.set_xlabel('Departure time [h]', fontsize=self.size_labelfont)
2447
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2448
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2449
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2450
if self.is_save:
2451
self.save_fig('plot_deptimedistrib')
2452
2453
def plot_tldensity(self):
2454
print 'plot_tldensity'
2455
fig = self.create_figure()
2456
results = self.parent
2457
routesresults_shortest = results.routesresults_shortest
2458
routesresults_matched = results.routesresults_matched
2459
edgesresults = results.edgesresults
2460
2461
ax = fig.add_subplot(111)
2462
ids_valid = routesresults_matched.select_ids(np.logical_and(
2463
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2464
2465
dists_match = routesresults_matched.distances[ids_valid]
2466
dists_shortest = routesresults_shortest.distances[ids_valid]
2467
2468
matched = routesresults_matched.numbers_nodes_tls[ids_valid]/dists_match*1000
2469
shortest = routesresults_shortest.numbers_nodes_tls[ids_valid]/dists_shortest*1000
2470
2471
x_min = min(np.min(matched), np.min(shortest))
2472
x_max = 10.0 # max(np.max(matched),np.max(shortest))
2473
bins = np.linspace(x_min, x_max, self.n_bins)
2474
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2475
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
2476
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2477
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
2478
2479
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2480
ax.grid(self.is_grid)
2481
if self.is_title:
2482
ax.set_title('Node densities of matched and shortest route', fontsize=self.size_titlefont)
2483
ax.set_xlabel('Traffic light density [1/km]', fontsize=self.size_labelfont)
2484
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2485
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2486
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2487
if self.is_save:
2488
self.save_fig('routeana_tldensity')
2489
2490
def plot_nodesdensity(self):
2491
print 'plot_nodesdensity'
2492
fig = self.create_figure()
2493
results = self.parent
2494
2495
routesresults_shortest = results.routesresults_shortest
2496
routesresults_matched = results.routesresults_matched
2497
edgesresults = results.edgesresults
2498
2499
ax = fig.add_subplot(111)
2500
ids_valid = routesresults_matched.select_ids(np.logical_and(
2501
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2502
2503
dists_match = routesresults_matched.distances[ids_valid]
2504
dists_shortest = routesresults_shortest.distances[ids_valid]
2505
2506
matched = routesresults_matched.numbers_nodes[ids_valid]/dists_match*1000
2507
shortest = routesresults_shortest.numbers_nodes[ids_valid]/dists_shortest*1000
2508
2509
x_min = min(np.min(matched), np.min(shortest))
2510
x_max = max(np.max(matched), np.max(shortest))
2511
bins = np.linspace(x_min, x_max, self.n_bins)
2512
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2513
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
2514
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2515
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
2516
2517
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2518
ax.grid(self.is_grid)
2519
if self.is_title:
2520
ax.set_title('Node densities of matched and shortest route', fontsize=self.size_titlefont)
2521
ax.set_xlabel('Node density [1/km]', fontsize=self.size_labelfont)
2522
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2523
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2524
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2525
if self.is_save:
2526
self.save_fig('routeana_nodesdensity')
2527
2528
def plot_prioritychangedensity(self):
2529
print 'plot_prioritychangedensity'
2530
fig = self.create_figure()
2531
results = self.parent
2532
routesresults_shortest = results.routesresults_shortest
2533
routesresults_matched = results.routesresults_matched
2534
edgesresults = results.edgesresults
2535
2536
ax = fig.add_subplot(111)
2537
ids_valid = routesresults_matched.select_ids(np.logical_and(
2538
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2539
2540
dists_match = routesresults_matched.distances[ids_valid]
2541
dists_shortest = routesresults_shortest.distances[ids_valid]
2542
2543
matched = routesresults_matched.numbers_prioritychange[ids_valid]/dists_match*1000
2544
shortest = routesresults_shortest.numbers_prioritychange[ids_valid]/dists_shortest*1000
2545
2546
x_min = min(np.min(matched), np.min(shortest))
2547
x_max = max(np.max(matched), np.max(shortest))
2548
bins = np.linspace(x_min, x_max, self.n_bins)
2549
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2550
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
2551
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2552
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
2553
2554
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2555
ax.grid(self.is_grid)
2556
if self.is_title:
2557
ax.set_title('Priority change dens. of matched and shortest route', fontsize=self.size_titlefont)
2558
ax.set_xlabel('Priority change density [1/km]', fontsize=self.size_labelfont)
2559
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2560
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2561
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2562
if self.is_save:
2563
self.save_fig('routeana_nodesdensity')
2564
2565
def plot_lowpriorityshare(self):
2566
print 'plot_lowpriorityshare'
2567
fig = self.create_figure()
2568
results = self.parent
2569
routesresults_shortest = results.routesresults_shortest
2570
routesresults_matched = results.routesresults_matched
2571
edgesresults = results.edgesresults
2572
2573
ax = fig.add_subplot(111)
2574
ids_valid = routesresults_matched.select_ids(np.logical_and(
2575
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2576
2577
dists_match = routesresults_matched.distances[ids_valid]
2578
dists_shortest = routesresults_shortest.distances[ids_valid]
2579
2580
matched = routesresults_matched.lengths_low_priority[ids_valid]/dists_match*100
2581
shortest = routesresults_shortest.lengths_low_priority[ids_valid]/dists_shortest*100
2582
2583
x_min = min(np.min(matched), np.min(shortest))
2584
x_max = 15.0 # max(np.max(matched),np.max(shortest))
2585
bins = np.linspace(x_min, x_max, self.n_bins)
2586
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2587
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
2588
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2589
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
2590
2591
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2592
ax.grid(self.is_grid)
2593
if self.is_title:
2594
ax.set_title('Share of low priority roads of matched and shortest route', fontsize=self.size_titlefont)
2595
ax.set_xlabel('Low priority road share [%]', fontsize=self.size_labelfont)
2596
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2597
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2598
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2599
if self.is_save:
2600
self.save_fig('routeana_lowpriorityshare')
2601
2602
def plot_exclusiveshare(self):
2603
print 'plot_exclusiveshare'
2604
fig = self.create_figure()
2605
results = self.parent
2606
routesresults_shortest = results.routesresults_shortest
2607
routesresults_matched = results.routesresults_matched
2608
edgesresults = results.edgesresults
2609
2610
ax = fig.add_subplot(111)
2611
ids_valid = routesresults_matched.select_ids(np.logical_and(
2612
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2613
2614
dists_match = routesresults_matched.distances[ids_valid]
2615
dists_shortest = routesresults_shortest.distances[ids_valid]
2616
2617
matched = routesresults_matched.lengths_exclusive[ids_valid]/dists_match*100
2618
shortest = routesresults_shortest.lengths_exclusive[ids_valid]/dists_shortest*100
2619
2620
x_min = min(np.min(matched), np.min(shortest))
2621
x_max = max(np.max(matched), np.max(shortest))
2622
bins = np.linspace(x_min, x_max, self.n_bins)
2623
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2624
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
2625
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2626
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
2627
2628
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2629
ax.grid(self.is_grid)
2630
if self.is_title:
2631
ax.set_title('Share of exclusive access roads of matched and shortest route', fontsize=self.size_titlefont)
2632
ax.set_xlabel('Exclusive access road share [%]', fontsize=self.size_labelfont)
2633
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2634
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2635
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2636
if self.is_save:
2637
self.save_fig('routeana_exclusiveshare')
2638
2639
def plot_mixshare(self):
2640
print 'plot_mixshare'
2641
fig = self.create_figure()
2642
results = self.parent
2643
routesresults_shortest = results.routesresults_shortest
2644
routesresults_matched = results.routesresults_matched
2645
edgesresults = results.edgesresults
2646
2647
ax = fig.add_subplot(111)
2648
ids_valid = routesresults_matched.select_ids(np.logical_and(
2649
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2650
2651
dists_match = routesresults_matched.distances[ids_valid]
2652
dists_shortest = routesresults_shortest.distances[ids_valid]
2653
2654
matched = routesresults_matched.lengths_mixed[ids_valid]/dists_match*100
2655
shortest = routesresults_shortest.lengths_mixed[ids_valid]/dists_shortest*100
2656
2657
x_min = min(np.min(matched), np.min(shortest))
2658
x_max = max(np.max(matched), np.max(shortest))
2659
bins = np.linspace(x_min, x_max, self.n_bins)
2660
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
2661
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
2662
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2663
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
2664
2665
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2666
ax.grid(self.is_grid)
2667
if self.is_title:
2668
ax.set_title('Share of mixed reserved access roads of matched and shortest route',
2669
fontsize=self.size_titlefont)
2670
ax.set_xlabel('Mixed reserved access road share [%]', fontsize=self.size_labelfont)
2671
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2672
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2673
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2674
if self.is_save:
2675
self.save_fig('routeana_mixshare')
2676
2677
def plot_lengthdistrib_by_class(self):
2678
print 'plot_lengthdistrib_by_class'
2679
fig = self.create_figure()
2680
results = self.parent
2681
routesresults_shortest = results.routesresults_shortest
2682
routesresults_matched = results.routesresults_matched
2683
edgesresults = results.edgesresults
2684
2685
ax = fig.add_subplot(111)
2686
ids_valid = routesresults_matched.select_ids(np.logical_and(
2687
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2688
2689
dists_match = routesresults_matched.distances[ids_valid]
2690
dists_shortest = routesresults_shortest.distances[ids_valid]
2691
x_min = min(np.min(dists_match), np.min(dists_shortest))
2692
x_max = max(np.max(dists_match), np.max(dists_shortest))
2693
2694
dists_class = np.arange(0, int(x_max), self.distance_class)
2695
dists_class_center = (dists_class+0.5*self.distance_class)[1:]
2696
n_class = len(dists_class)-1
2697
means_match = np.zeros(n_class, dtype=np.float32)
2698
stds_match = np.zeros(n_class, dtype=np.float32)
2699
means_shortest = np.zeros(n_class, dtype=np.float32)
2700
stds_shortest = np.zeros(n_class, dtype=np.float32)
2701
xticklabels = []
2702
ratiolabels = []
2703
for dist_lower, dist_upper, i in zip(dists_class[:-1], dists_class[1:], range(n_class)):
2704
xticklabels.append('%d - %d' % (float(dist_lower)/1000, float(dist_upper)/1000))
2705
inds = np.logical_and(dists_match > dist_lower, dists_match < dist_upper)
2706
means_match[i] = np.mean(dists_match[inds])
2707
stds_match[i] = np.std(dists_match[inds])
2708
2709
#inds = np.logical_and(dists_shortest>dist_lower,dists_shortest<dist_upper)
2710
means_shortest[i] = np.mean(dists_shortest[inds])
2711
stds_shortest[i] = np.std(dists_shortest[inds])
2712
2713
ratiolabel = ''
2714
if (not np.isnan(means_shortest[i])) & (not np.isnan(means_match[i])):
2715
if means_match[i] > 0:
2716
ratiolabel = '%d%%' % (means_shortest[i]/means_match[i]*100)
2717
ratiolabels.append(ratiolabel)
2718
2719
print ' dists_class_center', dists_class_center
2720
print ' means_match', means_match
2721
print ' stds_match', stds_match
2722
print ' means_shortest', means_shortest
2723
print ' stds_shortest', stds_shortest
2724
2725
x = np.arange(n_class, dtype=np.float32) # the x locations for the groups
2726
width = 0.35 # the width of the bars
2727
2728
# ax.bar(ind + width, women_means, width, color='y', yerr=women_std)
2729
bars1 = ax.bar(x-width, means_match, width, color=self.color_matched, yerr=stds_match)
2730
bars2 = ax.bar(x+0*width, means_shortest, width, color=self.color_shortest, yerr=stds_shortest)
2731
#bars1 = ax.bar(dists_class_center+0.35*self.distance_class, means_match, 0.25*self.distance_class, color=self.color_matched, yerr=stds_match)
2732
#bars2 = ax.bar(dists_class_center-0.35*self.distance_class, means_shortest, 0.25*self.distance_class, color=self.color_shortest, yerr=stds_shortest)
2733
2734
#ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)
2735
ax.legend((bars1[0], bars2[0]), ('matched', 'shortest'),
2736
shadow=True, fontsize=self.size_labelfont, loc='best')
2737
2738
# if self.is_grid:
2739
ax.yaxis.grid(self.is_grid)
2740
2741
if self.is_title:
2742
ax.set_title('Mean length by trip length class', fontsize=self.size_titlefont)
2743
ax.set_xlabel('Length classes [km]', fontsize=self.size_labelfont)
2744
ax.set_ylabel('Mean length [m]', fontsize=self.size_labelfont)
2745
2746
ax.set_xticks(x)
2747
ax.set_xticklabels(xticklabels)
2748
# self._autolabel_bars(ax,bars1,means_match)
2749
self._autolabel_bars(ax, bars2, ratiolabels)
2750
2751
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2752
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2753
if self.is_save:
2754
self.save_fig('routeana_lengthdistrib_by_class')
2755
2756
def _autolabel_bars(self, ax, bars, labels):
2757
"""
2758
Attach a text label above each bar displaying its height
2759
"""
2760
for rect, label in zip(bars, labels):
2761
height = rect.get_height()
2762
if not np.isnan(height):
2763
ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
2764
'%s' % label,
2765
ha='center', va='bottom',
2766
fontsize=int(0.8*self.size_labelfont),
2767
)
2768
2769
def plot_lengthdistrib(self):
2770
2771
fig = self.create_figure()
2772
results = self.parent
2773
routesresults_shortest = results.routesresults_shortest
2774
routesresults_matched = results.routesresults_matched
2775
edgesresults = results.edgesresults
2776
2777
ax = fig.add_subplot(111)
2778
ids_valid = routesresults_matched.select_ids(np.logical_and(routesresults_shortest.distances.get_value() > 0,
2779
time. routesresults_matched.distances.get_value() > 0,
2780
# routesresults_matched.distances.get_value()<20000)
2781
))
2782
print 'plot_lengthdistrib', len(ids_valid)
2783
# print ' ids_valid',ids_valid
2784
if len(ids_valid) == 0:
2785
return False
2786
2787
dists_match = routesresults_matched.distances[ids_valid]
2788
dists_shortest = routesresults_shortest.distances[ids_valid]
2789
2790
x_min = min(np.min(dists_match), np.min(dists_shortest))
2791
x_max = max(np.max(dists_match), np.max(dists_shortest))
2792
bins = np.linspace(x_min, x_max, self.n_bins)
2793
bincenters = self.plot_hist(ax, dists_match, bins=bins, color=self.color_matched,
2794
label='matched:'+'$\mu = %dm$, $\sigma=%dm$' % (np.mean(dists_match), np.std(dists_match)))
2795
bincenters = self.plot_hist(ax, dists_shortest, bins=bins, color=self.color_shortest, label='shortest:' +
2796
'$\mu = %dm$, $\sigma=%dm$' % (np.mean(dists_shortest), np.std(dists_shortest)))
2797
2798
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2799
ax.grid(self.is_grid)
2800
if self.is_title:
2801
ax.set_title('Length distribution of matched and shortest route', fontsize=self.size_titlefont)
2802
ax.set_xlabel('Length [m]', fontsize=self.size_labelfont)
2803
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2804
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2805
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2806
if self.is_save:
2807
self.save_fig('routeana_lengthdistrib')
2808
return True
2809
2810
def plot_timedistrib(self):
2811
print 'plot_timedistrib'
2812
fig = self.create_figure()
2813
results = self.parent
2814
mapmatching = results.parent
2815
trips = mapmatching.trips
2816
#routesresults_fastest = results.routesresults_fastest
2817
#routesresults_matched = results.routesresults_matched
2818
edgesresults = results.edgesresults
2819
2820
ax = fig.add_subplot(111)
2821
#ids_overlength = routesresults_matched.select_ids(np.logical_and(routesresults_shortest.distances.get_value()>0, routesresults_matched.distances.get_value()>20000))
2822
# print ' len(ids_overlength)',len(ids_overlength)
2823
# print ' ids_overlength',ids_overlength
2824
2825
ids_valid = trips.select_ids(
2826
np.logical_and(trips.lengths_route_matched.get_value() > 0,
2827
trips.durations_route_fastest.get_value() > 0,
2828
# routesresults_matched.distances.get_value()<20000)
2829
))
2830
2831
if len(ids_valid) == 0:
2832
return False
2833
2834
times_fastest = trips.durations_route_fastest[ids_valid]
2835
times_match = times_fastest+trips.timelosses_route_fastest[ids_valid]
2836
2837
x_min = min(np.min(times_fastest), np.min(times_match))
2838
x_max = max(np.max(times_fastest), np.max(times_match))
2839
bins = np.linspace(x_min, x_max, self.n_bins)
2840
bincenters = self.plot_hist(ax, times_match, bins=bins, color=self.color_matched,
2841
label='matched:'+'$\mu = %dm$, $\sigma=%dm$' % (np.mean(times_match), np.std(times_match)))
2842
bincenters = self.plot_hist(ax, times_fastest, bins=bins, color=self.color_fastest, label='fastest:' +
2843
'$\mu = %dm$, $\sigma=%dm$' % (np.mean(times_fastest), np.std(times_fastest)))
2844
2845
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2846
ax.grid(self.is_grid)
2847
if self.is_title:
2848
ax.set_title('Triptime distribution of matched and fastest route', fontsize=self.size_titlefont)
2849
ax.set_xlabel('Time [s]', fontsize=self.size_labelfont)
2850
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2851
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2852
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2853
if self.is_save:
2854
self.save_fig('routeana_timedistrib')
2855
2856
return True
2857
2858
def plot_lengthprob(self):
2859
print 'plot_lengthprob'
2860
fig = self.create_figure()
2861
results = self.parent
2862
routesresults_shortest = results.routesresults_shortest
2863
routesresults_matched = results.routesresults_matched
2864
edgesresults = results.edgesresults
2865
2866
ax = fig.add_subplot(111)
2867
ids_valid = routesresults_matched.select_ids(np.logical_and(
2868
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2869
2870
dists_match = routesresults_matched.distances[ids_valid]
2871
dists_shortest = routesresults_shortest.distances[ids_valid]
2872
2873
x_min = min(np.min(dists_match), np.min(dists_shortest))
2874
x_max = max(np.max(dists_match), np.max(dists_shortest))
2875
bins = np.linspace(x_min, x_max, self.n_bins)
2876
w_bin = bins[1]-bins[0]
2877
bincenters = self.plot_hist(ax, dists_match, bins=bins,
2878
color=self.color_matched,
2879
label='matched:' +
2880
'$\mu = %dm$, $\sigma=%dm$' % (np.mean(dists_match), np.std(dists_match)),
2881
is_rel_frequ=True,
2882
is_percent=True,
2883
)
2884
bincenters = self.plot_hist(ax, dists_shortest, bins=bins,
2885
color=self.color_shortest,
2886
label='shortest:' +
2887
'$\mu = %dm$, $\sigma=%dm$' % (np.mean(dists_shortest), np.std(dists_shortest)),
2888
is_rel_frequ=True,
2889
is_percent=True,
2890
)
2891
2892
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2893
ax.grid(self.is_grid)
2894
if self.is_title:
2895
ax.set_title('Relative frequency of matched and shortest route', fontsize=self.size_titlefont)
2896
ax.set_xlabel('Length [m]', fontsize=self.size_labelfont)
2897
ax.set_ylabel('Relative frequency [%]', fontsize=self.size_labelfont)
2898
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2899
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2900
if self.is_save:
2901
self.save_fig('routeana_lengthprob')
2902
2903
def plot_lengthoverlap(self):
2904
print 'plot_lengthoverlap'
2905
fig = self.create_figure()
2906
results = self.parent
2907
routesresults_shortest = results.routesresults_shortest
2908
routesresults_matched = results.routesresults_matched
2909
edgesresults = results.edgesresults
2910
2911
ax = fig.add_subplot(111)
2912
bins = np.linspace(0.0, 1.0, self.n_bins)
2913
2914
ids_valid = routesresults_matched.select_ids(np.logical_and(
2915
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2916
values = routesresults_shortest.lengths_overlap_matched[ids_valid]/routesresults_matched.distances[ids_valid]
2917
bincenters = self.plot_hist(ax, values,
2918
bins=bins, histtype='bar',
2919
label=r'$\mu = %.2f$, $\sigma=%.2f$' % (np.mean(values), np.std(values))
2920
)
2921
2922
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2923
ax.grid(self.is_grid)
2924
if self.is_title:
2925
ax.set_title('Share of overlap between shortest path and matched path', fontsize=self.size_titlefont)
2926
ax.set_xlabel('Overlap share between shortest and matched path', fontsize=self.size_labelfont)
2927
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2928
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2929
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2930
2931
self.set_figmargins()
2932
if self.is_save:
2933
self.save_fig('routeana_lengthoverlap')
2934
2935
def plot_lengthoverlap_fastest(self):
2936
print 'plot_lengthoverlap_fastest'
2937
fig = self.create_figure()
2938
results = self.parent
2939
print 'dir(results)', dir(results)
2940
routesresults_fastest = results.routesresults_fastest
2941
routesresults_matched = results.routesresults_matched
2942
edgesresults = results.edgesresults
2943
2944
ax = fig.add_subplot(111)
2945
bins = np.linspace(0.0, 1.0, self.n_bins)
2946
2947
ids_valid = routesresults_matched.select_ids(np.logical_and(
2948
routesresults_fastest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2949
values = routesresults_fastest.lengths_overlap_matched[ids_valid]/routesresults_matched.distances[ids_valid]
2950
bincenters = self.plot_hist(ax, values,
2951
bins=bins, histtype='bar',
2952
label=r'$\mu = %.2f$, $\sigma=%.2f$' % (np.mean(values), np.std(values))
2953
)
2954
2955
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2956
ax.grid(self.is_grid)
2957
if self.is_title:
2958
ax.set_title('Share of overlap between fastest path and matched path', fontsize=self.size_titlefont)
2959
ax.set_xlabel('Overlap share between fastest and matched path', fontsize=self.size_labelfont)
2960
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2961
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2962
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2963
2964
self.set_figmargins()
2965
if self.is_save:
2966
self.save_fig('routeana_lengthoverlap_fastest')
2967
2968
def plot_lengthratio(self):
2969
print 'plot_lengthratio'
2970
fig = self.create_figure()
2971
results = self.parent
2972
routesresults_shortest = results.routesresults_shortest
2973
routesresults_matched = results.routesresults_matched
2974
edgesresults = results.edgesresults
2975
2976
ax = fig.add_subplot(111)
2977
bins = np.linspace(0.0, 1.0, self.n_bins)
2978
2979
ids_valid = routesresults_matched.select_ids(np.logical_and(
2980
routesresults_shortest.distances.get_value() > 0, routesresults_matched.distances.get_value() > 0))
2981
values = routesresults_shortest.distances[ids_valid]/routesresults_matched.distances[ids_valid]
2982
bincenters = self.plot_hist(ax, values,
2983
bins=bins, histtype='bar',
2984
label=r'$\mu = %.2f$, $\sigma=%.2f$' % (np.mean(values), np.std(values))
2985
)
2986
2987
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
2988
ax.grid(self.is_grid)
2989
if self.is_title:
2990
ax.set_title('Ratio distance shortest path over matched path', fontsize=self.size_titlefont)
2991
ax.set_xlabel('Ratio shortest path length/matched path length', fontsize=self.size_labelfont)
2992
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
2993
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
2994
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
2995
2996
self.set_figmargins()
2997
if self.is_save:
2998
self.save_fig('routeana_lengthratio')
2999
3000
3001
# -------------------------------------------------------------------------------
3002
# non-overlap
3003
3004
def plot_lengthratio_nonoverlap(self):
3005
print 'plot_lengthratio_nonoverlap'
3006
fig = self.create_figure()
3007
results = self.parent
3008
routesresults_shortest = results.routesresults_shortest
3009
routesresults_matched = results.routesresults_matched
3010
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3011
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3012
3013
edgesresults = results.edgesresults
3014
3015
ax = fig.add_subplot(111)
3016
bins = np.linspace(0.0, 1.0, self.n_bins)
3017
3018
ids_valid = routesresults_matched.select_ids(np.logical_and(
3019
routesresults_shortest_nonoverlap.distances.get_value() > 0,
3020
routesresults_matched_nonoverlap.distances.get_value() > 0)
3021
)
3022
3023
values = routesresults_shortest_nonoverlap.distances[ids_valid] / \
3024
routesresults_matched_nonoverlap.distances[ids_valid]
3025
bincenters = self.plot_hist(ax, values,
3026
bins=bins, histtype='bar',
3027
label=r'$\mu = %.2f$, $\sigma=%.2f$' % (np.mean(values), np.std(values))
3028
)
3029
3030
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3031
ax.grid(self.is_grid)
3032
if self.is_title:
3033
ax.set_title('Ratio distance of non-overlapping shortest over matched path', fontsize=self.size_titlefont)
3034
ax.set_xlabel('Ratio shortest n.o. path length/matched path length', fontsize=self.size_labelfont)
3035
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3036
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3037
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3038
3039
self.set_figmargins()
3040
if self.is_save:
3041
self.save_fig('routeana_lengthratio_nonoverlap')
3042
3043
def plot_tldensity_nonoverlap(self):
3044
print 'plot_tldensity_nonoverlap'
3045
fig = self.create_figure()
3046
results = self.parent
3047
routesresults_shortest = results.routesresults_shortest
3048
routesresults_matched = results.routesresults_matched
3049
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3050
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3051
edgesresults = results.edgesresults
3052
3053
ax = fig.add_subplot(111)
3054
ids_valid = routesresults_matched.select_ids(np.logical_and(
3055
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3056
3057
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3058
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3059
3060
matched = routesresults_matched_nonoverlap.numbers_nodes_tls[ids_valid]/dists_match*1000
3061
shortest = routesresults_shortest_nonoverlap.numbers_nodes_tls[ids_valid]/dists_shortest*1000
3062
3063
x_min = min(np.min(matched), np.min(shortest))
3064
x_max = 10.0 # max(np.max(matched),np.max(shortest))
3065
bins = np.linspace(x_min, x_max, self.n_bins)
3066
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3067
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
3068
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3069
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
3070
3071
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3072
ax.grid(self.is_grid)
3073
if self.is_title:
3074
ax.set_title('Node densities of non-overlapping matched and shortest route', fontsize=self.size_titlefont)
3075
ax.set_xlabel('Traffic light density n.o. [1/km]', fontsize=self.size_labelfont)
3076
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3077
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3078
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3079
if self.is_save:
3080
self.save_fig('routeana_tldensity_nonoverlap')
3081
3082
def plot_nodesdensity_nonoverlap(self):
3083
print 'plot_nodesdensity_nonoverlap'
3084
fig = self.create_figure()
3085
results = self.parent
3086
routesresults_shortest = results.routesresults_shortest
3087
routesresults_matched = results.routesresults_matched
3088
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3089
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3090
edgesresults = results.edgesresults
3091
3092
ax = fig.add_subplot(111)
3093
ids_valid = routesresults_matched.select_ids(np.logical_and(
3094
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3095
3096
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3097
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3098
3099
matched = routesresults_matched_nonoverlap.numbers_nodes[ids_valid]/dists_match*1000
3100
shortest = routesresults_shortest_nonoverlap.numbers_nodes[ids_valid]/dists_shortest*1000
3101
3102
x_min = min(np.min(matched), np.min(shortest))
3103
x_max = max(np.max(matched), np.max(shortest))
3104
bins = np.linspace(x_min, x_max, self.n_bins)
3105
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3106
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
3107
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3108
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
3109
3110
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3111
ax.grid(self.is_grid)
3112
if self.is_title:
3113
ax.set_title('Node densities of non-overlapping matched and shortest route', fontsize=self.size_titlefont)
3114
ax.set_xlabel('Node density n.o. [1/km]', fontsize=self.size_labelfont)
3115
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3116
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3117
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3118
if self.is_save:
3119
self.save_fig('routeana_nodesdensity_nonoverlap')
3120
3121
def plot_prioritychangedensity_nonoverlap(self):
3122
print 'plot_prioritychangedensity_nonoverlap'
3123
fig = self.create_figure()
3124
results = self.parent
3125
routesresults_shortest = results.routesresults_shortest
3126
routesresults_matched = results.routesresults_matched
3127
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3128
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3129
edgesresults = results.edgesresults
3130
3131
ax = fig.add_subplot(111)
3132
ids_valid = routesresults_matched.select_ids(np.logical_and(
3133
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3134
3135
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3136
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3137
3138
matched = routesresults_matched_nonoverlap.numbers_prioritychange[ids_valid]/dists_match*1000
3139
shortest = routesresults_shortest_nonoverlap.numbers_prioritychange[ids_valid]/dists_shortest*1000
3140
3141
x_min = min(np.min(matched), np.min(shortest))
3142
x_max = max(np.max(matched), np.max(shortest))
3143
bins = np.linspace(x_min, x_max, self.n_bins)
3144
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3145
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(matched), np.std(matched)))
3146
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3147
'$\mu = %.2f/km$, $\sigma=%.2f/km$' % (np.mean(shortest), np.std(shortest)))
3148
3149
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3150
ax.grid(self.is_grid)
3151
if self.is_title:
3152
ax.set_title('Priority change dens. of non-overlapping matched and shortest route',
3153
fontsize=self.size_titlefont)
3154
ax.set_xlabel('Priority change density n.o. [1/km]', fontsize=self.size_labelfont)
3155
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3156
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3157
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3158
if self.is_save:
3159
self.save_fig('routeana_nodesdensity_nonoverlap')
3160
3161
def plot_lowpriorityshare_nonoverlap(self):
3162
print 'plot_lowpriorityshare_nonoverlap'
3163
fig = self.create_figure()
3164
results = self.parent
3165
routesresults_shortest = results.routesresults_shortest
3166
routesresults_matched = results.routesresults_matched
3167
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3168
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3169
edgesresults = results.edgesresults
3170
3171
ax = fig.add_subplot(111)
3172
ids_valid = routesresults_matched.select_ids(np.logical_and(
3173
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3174
3175
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3176
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3177
3178
matched = routesresults_matched_nonoverlap.lengths_low_priority[ids_valid]/dists_match*100
3179
shortest = routesresults_shortest_nonoverlap.lengths_low_priority[ids_valid]/dists_shortest*100
3180
3181
x_min = min(np.min(matched), np.min(shortest))
3182
x_max = 15.0 # max(np.max(matched),np.max(shortest))
3183
bins = np.linspace(x_min, x_max, self.n_bins)
3184
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3185
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
3186
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3187
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
3188
3189
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3190
ax.grid(self.is_grid)
3191
if self.is_title:
3192
ax.set_title('Share of low priority roads of non-overlapping matched and shortest route',
3193
fontsize=self.size_titlefont)
3194
ax.set_xlabel('Low priority road share n.o. [%]', fontsize=self.size_labelfont)
3195
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3196
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3197
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3198
if self.is_save:
3199
self.save_fig('routeana_lowpriorityshare_nonoverlap')
3200
3201
def plot_exclusiveshare_nonoverlap(self):
3202
print 'plot_exclusiveshare_nonoverlap'
3203
fig = self.create_figure()
3204
results = self.parent
3205
routesresults_shortest = results.routesresults_shortest
3206
routesresults_matched = results.routesresults_matched
3207
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3208
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3209
edgesresults = results.edgesresults
3210
3211
ax = fig.add_subplot(111)
3212
ids_valid = routesresults_matched.select_ids(np.logical_and(
3213
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3214
3215
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3216
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3217
3218
matched = routesresults_matched_nonoverlap.lengths_exclusive[ids_valid]/dists_match*100
3219
shortest = routesresults_shortest_nonoverlap.lengths_exclusive[ids_valid]/dists_shortest*100
3220
3221
x_min = min(np.min(matched), np.min(shortest))
3222
x_max = max(np.max(matched), np.max(shortest))
3223
bins = np.linspace(x_min, x_max, self.n_bins)
3224
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3225
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
3226
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3227
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
3228
3229
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3230
ax.grid(self.is_grid)
3231
if self.is_title:
3232
ax.set_title('Share of exclusive access roads of non-overlapping matched and shortest route',
3233
fontsize=self.size_titlefont)
3234
ax.set_xlabel('Exclusive access road share n.o. [%]', fontsize=self.size_labelfont)
3235
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3236
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3237
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3238
if self.is_save:
3239
self.save_fig('routeana_exclusiveshare_nonoverlap')
3240
3241
def plot_mixshare_nonoverlap(self):
3242
print 'plot_mixshare_nonoverlap'
3243
fig = self.create_figure()
3244
results = self.parent
3245
routesresults_shortest = results.routesresults_shortest
3246
routesresults_matched = results.routesresults_matched
3247
routesresults_shortest_nonoverlap = results.routesresults_shortest_nonoverlap
3248
routesresults_matched_nonoverlap = results.routesresults_matched_nonoverlap
3249
edgesresults = results.edgesresults
3250
3251
ax = fig.add_subplot(111)
3252
ids_valid = routesresults_matched.select_ids(np.logical_and(
3253
routesresults_shortest_nonoverlap.distances.get_value() > 0, routesresults_matched_nonoverlap.distances.get_value() > 0))
3254
3255
dists_match = routesresults_matched_nonoverlap.distances[ids_valid]
3256
dists_shortest = routesresults_shortest_nonoverlap.distances[ids_valid]
3257
3258
matched = routesresults_matched_nonoverlap.lengths_mixed[ids_valid]/dists_match*100
3259
shortest = routesresults_shortest_nonoverlap.lengths_mixed[ids_valid]/dists_shortest*100
3260
3261
x_min = min(np.min(matched), np.min(shortest))
3262
x_max = max(np.max(matched), np.max(shortest))
3263
bins = np.linspace(x_min, x_max, self.n_bins)
3264
bincenters = self.plot_hist(ax, matched, bins=bins, color=self.color_matched, label='matched:' +
3265
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(matched), np.std(matched)))
3266
bincenters = self.plot_hist(ax, shortest, bins=bins, color=self.color_shortest, label='shortest:' +
3267
'$\mu = %.2f$%%, $\sigma=%.2f$%%' % (np.mean(shortest), np.std(shortest)))
3268
3269
ax.legend(loc='best', shadow=True, fontsize=self.size_labelfont)
3270
ax.grid(self.is_grid)
3271
if self.is_title:
3272
ax.set_title('Share of mixed reserved access roads of non-overlapping matched and shortest route',
3273
fontsize=self.size_titlefont)
3274
ax.set_xlabel('Mixed reserved access road share n.o. [%]', fontsize=self.size_labelfont)
3275
ax.set_ylabel('Probability distribution', fontsize=self.size_labelfont)
3276
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3277
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3278
if self.is_save:
3279
self.save_fig('routeana_mixshare_nonoverlap')
3280
# -------------------------------------------------------------------------------
3281
3282
def do(self):
3283
# print 'do',self.edgeattrname
3284
self.show()
3285
3286
def get_scenario(self):
3287
return self.parent.get_scenario()
3288
3289
3290
class PtFlowdigramPlotter(PlotoptionsMixin, Process):
3291
def __init__(self, results, name='PT flowdiagram',
3292
info="Plots the flow diagram of PT lines using matplotlib",
3293
logger=None, **kwargs):
3294
3295
self._init_common('ptrouteresultplotter', parent=results, name=name,
3296
info=info, logger=logger)
3297
3298
print 'PtFlowdigramPlotter.__init__', results, self.parent
3299
attrsman = self.get_attrsman()
3300
3301
self.id_line = attrsman.add(cm.AttrConf('id_line', kwargs.get('id_line', -1),
3302
groupnames=['options'],
3303
name='Line ID',
3304
info='ID of public transport line to be plotted.',
3305
))
3306
3307
self.is_add_similar = attrsman.add(cm.AttrConf('is_add_similar', kwargs.get('is_add_similar', True),
3308
groupnames=['options'],
3309
name='include similar lines',
3310
info='Add also trips on similar PT lines.',
3311
))
3312
3313
self.is_title = attrsman.add(cm.AttrConf('is_title', kwargs.get('is_title', False),
3314
groupnames=['options'],
3315
name='Show title',
3316
info='Show title of diagrams.',
3317
))
3318
3319
self.size_titlefont = attrsman.add(cm.AttrConf('size_titlefont', kwargs.get('size_titlefont', 32),
3320
groupnames=['options'],
3321
name='Title fontsize',
3322
info='Title fontsize.',
3323
))
3324
3325
self.size_labelfont = attrsman.add(cm.AttrConf('size_labelfont', kwargs.get('size_labelfont', 24),
3326
groupnames=['options'],
3327
name='Label fontsize',
3328
info='Label fontsize.',
3329
))
3330
3331
self.width_line = attrsman.add(cm.AttrConf('width_line', kwargs.get('width_line', 2),
3332
groupnames=['options'],
3333
perm='wr',
3334
name='Line width',
3335
info='Width of plotted lines.',
3336
))
3337
3338
# self.color_outline = attrsman.add(cm.AttrConf( 'color_outline', kwargs.get('color_outline', np.array([0.0,0.0,0.0,0.95], dtype=np.float32)),
3339
# groupnames = ['options'],
3340
# perm='wr',
3341
# metatype = 'color',
3342
# name = 'Outline color',
3343
# info = 'Outline color of result arrows in graphical representation. Only valid if no color-fill is chosen.',
3344
# ))
3345
3346
self.color_fill = attrsman.add(cm.AttrConf('color_fill', kwargs.get('color_fill', np.array([0.3, 0.3, 1.0, 0.95], dtype=np.float32)),
3347
groupnames=['options'],
3348
perm='wr',
3349
metatype='color',
3350
name='Fill color',
3351
info='Fill color of result arrows in graphical representation.',
3352
))
3353
3354
self.is_grid = attrsman.add(cm.AttrConf('is_grid', kwargs.get('is_grid', False),
3355
groupnames=['options'],
3356
name='Show grid?',
3357
info='If True, shows a grid on the graphical representation.',
3358
))
3359
3360
self.csvfilepath = attrsman.add(cm.AttrConf('csvfilepath', kwargs.get('csvfilepath', ''),
3361
groupnames=['options'],
3362
perm='rw',
3363
name='CSV filename',
3364
wildcards='CSV file (*.csv)|*.csv|All file (*.*)|*.*',
3365
metatype='filepaths',
3366
info="""Filename to export flow results.""",
3367
))
3368
3369
self.add_save_options(**kwargs)
3370
3371
def show(self):
3372
print 'show'
3373
# if self.axis is None:
3374
self.init_figures()
3375
plt.rc('lines', linewidth=self.width_line)
3376
fig = self.create_figure()
3377
ax = fig.add_subplot(111)
3378
3379
results = self.parent
3380
3381
ptlinesresults = results.ptlinesresults
3382
3383
# link object
3384
mapmatching = results.parent
3385
#trips = mapmatching.trips
3386
#routes = trips.get_routes()
3387
3388
scenario = mapmatching.get_scenario()
3389
ptstops = scenario.net.ptstops
3390
demand = scenario.demand
3391
ptlines = demand.ptlines
3392
ptlinks = ptlines.get_ptlinks()
3393
3394
if not self.id_line in ptlines:
3395
print 'WARNING: line with ID', self.id_line, 'not found.'
3396
return False
3397
3398
#id_line = ptlines.linenames.get_id_from_index(self.linename)
3399
if self.is_add_similar:
3400
linename = ptlines.linenames[self.id_line].split('_')[0]
3401
else:
3402
linename = ptlines.linenames[self.id_line]
3403
ids_stoptuple_line, tripnumbers_line = ptlinesresults.get_flowdiagramm(
3404
self.id_line, is_add_similar=self.is_add_similar)
3405
3406
n_stops = len(ids_stoptuple_line)
3407
ax.bar(xrange(n_stops), tripnumbers_line,
3408
width=1.0, bottom=0, align='edge',
3409
color=self.color_fill,
3410
#linecolor = self.color_outline,
3411
linewidth=self.width_line,)
3412
3413
stopnames = []
3414
for id_fromstop, id_tostop in ids_stoptuple_line:
3415
stopnames.append(ptstops.stopnames_human[id_fromstop])
3416
# print ' stopnames',stopnames
3417
ax.set_xticks(xrange(n_stops))
3418
ax.set_xticklabels(stopnames)
3419
3420
#ax.legend(loc='best',shadow=True, fontsize=self.size_labelfont)
3421
ax.grid(self.is_grid)
3422
if self.is_title:
3423
ax.set_title('Flow diagram of PT line '+linename, fontsize=self.size_titlefont)
3424
ax.set_xlabel('Stops', fontsize=self.size_labelfont)
3425
ax.set_ylabel('Number of Passengers', fontsize=self.size_labelfont)
3426
ax.tick_params(axis='x', labelsize=int(0.8*self.size_labelfont))
3427
ax.tick_params(axis='y', labelsize=int(0.8*self.size_labelfont))
3428
plt.setp(ax.get_xticklabels(), rotation=90, ha="right", rotation_mode="anchor")
3429
3430
if len(self.csvfilepath) > 0:
3431
# export to csv
3432
f = open(self.csvfilepath, 'w')
3433
f.write('Flow diagram of PT line '+linename+'\n\n')
3434
sep = ','
3435
f.write('Stopname from'+sep+'Stopname from'+sep+'Passengers\n')
3436
for ids_stoptuple, number in zip(ids_stoptuple_line, tripnumbers_line):
3437
f.write(ptstops.stopnames_human[ids_stoptuple[0]]+sep +
3438
ptstops.stopnames_human[ids_stoptuple[1]]+sep+str(number)+'\n')
3439
3440
f.close()
3441
3442
if self.is_save:
3443
self.save_fig('_ptrouteana_flowdiagram')
3444
else:
3445
show_plot()
3446
3447