def lineage_map(p, linkage_cols, data, boundary=None): bg, cause, effect = utils.random_sample_from_p(p, linkage_cols) bg_data = data.getrows(bg).space cause_data = data.getrows(cause).space effect_data = data.getrows(effect).space fig = plt.figure() ax = fig.add_subplot(111) if boundary: plot_shapely_geos(boundary, ax=ax) ax.scatter(bg_data.getdim(0), bg_data.getdim(1), c='k', marker='o', s=50, alpha=0.3) plt.plot(effect_data.getdim(0), effect_data.getdim(1), 'rd', lw=2.5) for i in range(len(cause)): x = cause_data[i, 0] y = cause_data[i, 1] dx = effect_data[i, 0] - x dy = effect_data[i, 1] - y plt.plot([x, x + dx], [y, y + dy], 'r-', lw=2.5) # try: # ax.arrow(x, y, dx, dy, ec='r', fc='none', head_width=15, width=2, length_includes_head=True) # except Exception: # pass ax.set_aspect('equal')
def plot(self, show_sample_units=True, show_prediction=True, fmax=0.9, cmap='Reds', **kwargs): from matplotlib import patches fig = plt.figure() ax = fig.add_subplot(111) ax.set_aspect('equal') if show_prediction: # create dictionary of segment colours for plotting # this requires creating a norm instance and using that to index a colourmap vmax = sorted(self.prediction_values)[int(self.n_sample_units * fmax)] cmap = cm.get_cmap(cmap) norm = mpl.colors.Normalize(vmin=0, vmax=vmax) colour_mapper = cm.ScalarMappable(norm=norm, cmap=cmap) edge_inner_col = {} for pv, edge in zip(self.prediction_values, self.sample_units): edge_inner_col[edge['fid']] = colour_mapper.to_rgba(pv) self.graph.plot_network(ax=ax, edge_width=7, edge_inner_col=edge_inner_col) else: # plot standard network edge outlines without colour self.graph.plot_network(edge_width=10, edge_inner_col='w') if show_sample_units: # alternating grey - black grid squares / crosses xsp, ysp = self.sample_points.to_cartesian().separate mins = np.array(self.sample_units).min(axis=0) maxs = np.array(self.sample_units).max(axis=0) xmin_group = np.arange(mins[0], maxs[2], 2 * self.side_length) ymin_group = np.arange(mins[1], maxs[3], 2 * self.side_length) count = 0 for gp, su, n in zip(self.grid_polys, self.sample_units, self.n_sample_point_per_unit): a = np.any(np.abs(xmin_group - su[0]) < 1e-3) ^ np.any( np.abs(ymin_group - su[1]) < 1e-3) fc = np.ones(3) * (0.5 if a else 0.8) mc = np.ones(3) * 0.5 if a else 'k' plot_shapely_geos(gp, facecolor=fc, alpha=0.4) plt.plot( xsp[count:count + n], ysp[count:count + n], 'o', color=mc, markersize=5, ) count += n # remove x and y ticks as these rarely add anything ax.set_xticks([]) ax.set_yticks([])
def plot_domain(city_domain, sub_domain, ax=None, set_axis=True): bbox = np.array(city_domain.buffer(100).bounds) if ax is None: fig = plt.figure() ax = fig.add_subplot(111) plot_shapely_geos(city_domain, ax=ax) plot_shapely_geos(sub_domain, ax=ax, facecolor='k') if set_axis: plt.axis('equal') plt.axis(np.array(bbox)[(0, 2, 1, 3),]) plt.axis('off')
def network_density_movie_slides2(vb, res, t0=None, fmax=None, line_buffer=10, colorbar=False, boundary=None, outdir='network_density_slides'): """ Create image files of network density over a series of predictions :param vb: Validation object :param res: The result of a validation run :param t0: Optional datetime.date corresponding to time zero. :param outdir: The output directory for images, which is created if necessary :param boundary: Optionally supply a Shapely object for plotting :param colorbar: TODO: needs to be implemented :return: None """ os.mkdir(outdir) fmax = fmax or 0.99 n = len(res['cutoff_t']) idx = bisect.bisect_left( np.linspace(0, 1, res['prediction_values'].size), fmax ) vmax = sorted(res['prediction_values'].flat)[idx] lines = list(vb.graph.lines_iter()) xy = vb.sample_points.to_cartesian() for i in range(n): z = vb.model.predict(res['cutoff_t'][i], None) # no spatial points needed: reuse sample points z[z > vmax] = vmax fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111) ax.set_xticks([]) ax.set_yticks([]) ax.scatter(xy.toarray(0), xy.toarray(1), c=z, edgecolor='none', cmap='Reds') plot_network_edge_lines(lines, ax=ax, line_buffer=line_buffer) if boundary is not None: plot_shapely_geos(boundary, ax=ax, set_axes=False, facecolor='none', edgecolor='k', linewidth=2.) outfile = os.path.join(outdir, '%03d.png') % (i + 1) if t0: t = t0 + datetime.timedelta(days=res['cutoff_t'][i]) title = t.strftime("%d/%m/%Y") else: title = res['cutoff_t'][i] plt.title(title, fontsize=24) plt.tight_layout(pad=1.5) plt.show() plt.axis('auto') plt.axis('equal') plt.savefig(outfile, dpi=150) plt.close(fig)
def plot_optimal_bandwidth_map(ht, hd, boundaries, ax=None, trange=None, colourbar=True): """ Plot a map showing both spatial and temporal optimal bandwidths :param ht: Dict of optimal temporal bandwidths :param hd: Dict of optimal spatial bandwidths :param boundaries: Dict of boundary polygons, indexed by same key as ht and hd :param ax: Optionally specify axes, otherwise new plot will be created :param trange: Optionally specify the time range - useful when creating multiple plots :param colourbar: If True, a colourbar is added :return: """ buff = 0.01 if ax is None: fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111) # get full domain boundary dom = ops.cascaded_union([boundaries[k] for k in ht]) xmin, ymin, xmax, ymax = dom.bounds if trange is None: trange = (np.min(ht.values()), np.max(ht.values())) sc_map = colour_mapper([], vmin=trange[0], vmax=trange[1], cmap='Reds') for k in boundaries: if k in ht: plot_shapely_geos(boundaries[k], ec='k', fc=sc_map.to_rgba(ht[k]), ax=ax) else: plot_shapely_geos(boundaries[k], ec='k', fc='none', ax=ax) if k in hd: centroid = boundaries[k].centroid circ = Circle((centroid.x, centroid.y), radius=hd[k], edgecolor='none', facecolor='b') ax.add_patch(circ) dx = xmax - xmin dy = ymax - ymin ax.set_xlim([xmin - dx * buff, xmax + dx * buff]) ax.set_ylim([ymin - dy * buff, ymax + dy * buff]) ax.set_aspect('equal') ax.set_xticks([]) ax.set_yticks([]) ax.set_frame_on(False) plt.tight_layout(0.)
def render(self, ax=None): ax = ax or plt.gca() spatial.plot_shapely_geos(self.osm.domain, ax=ax, set_axes=True, **self.style['domain']) for t, v in self.osm.elements.iteritems(): if t in self.style: this_style = self.style[t] for k, x in v.items(): if k in this_style: s = dict(this_style[k]) buffer = s.pop('buffer', None) if buffer: # buffer each entry in list of linestrings x = [a.buffer(buffer) for a in x] spatial.plot_shapely_geos(x, ax=ax, set_axes=False, **s) elif '__other' in this_style: s = this_style['__other'] spatial.plot_shapely_geos(x, ax=ax, set_axes=False, **s) ax.set_aspect('equal') ax.set_xticks([]) ax.set_yticks([]) return ax
def spatial_repeat_analysis(crime_type='burglary', domain=None, plot_osm=False, **kwargs): data, t0, cid = get_crimes_by_type(crime_type=crime_type, domain=domain, **kwargs) xy = data[:, 1:] rpt = collections.defaultdict(int) uniq = collections.defaultdict(int) for t in xy: if np.sum((np.sum(xy == t, axis=1) == 2)) > 1: rpt[tuple(t)] += 1 else: uniq[tuple(t)] += 1 # plotting domain = domain or compute_chicago_region() fig = plt.figure() ax = fig.add_subplot(111) # outline plot_shapely_geos(domain, ax=ax, fc='None') # off-grid repeat locations tt = np.array(rpt.keys()) ax.plot(tt[:, 0], tt[:, 1], 'ok') # tt = np.array(uniq.keys()) ax.plot(tt[:, 0], tt[:, 1], 'o', color='#CCCCCC', alpha=0.6) # x_max, y_max = np.max(np.array(camden.mpoly[0].coords[0]), axis=0) # x_min, y_min = np.min(np.array(camden.mpoly[0].coords[0]), axis=0) # ax.set_xlim(np.array([-150, 150]) + np.array([x_min, x_max])) # ax.set_ylim(np.array([-150, 150]) + np.array([y_min, y_max])) ax.set_aspect('equal') ax.axis('off') plt.draw() return rpt, uniq
def plot(self, show_sample_units=True, show_sample_points=False, show_prediction=True, fmax=0.9, cmap='Reds', ax=None, **kwargs): if ax is None: fig = plt.figure() ax = fig.add_subplot(111) ax.set_aspect('equal') plot_shapely_geos(self.poly, facecolor='none', edgecolor='k', ax=ax) if show_prediction: # create dictionary of segment colours for plotting # this requires creating a norm instance and using that to index a colourmap cmapper = colour_mapper(self.prediction_values, fmax=fmax, vmin=0) for pv, grid in zip(self.prediction_values, self.sample_units): sq = shapely_rectangle_from_vertices(*grid) plot_shapely_geos(sq, ax=ax, facecolor=cmapper.to_rgba(pv), edgecolor='none', alpha=kwargs.pop('alpha', 0.4)) if show_sample_units: plot_shapely_geos([ shapely_rectangle_from_vertices(*grid) for grid in self.sample_units ], ax=ax, facecolor='none') if show_sample_points: plt.scatter(*self.sample_points.separate, s=10, c='k', marker='o') # remove x and y ticks as these rarely add anything ax.set_xticks([]) ax.set_yticks([]) plt.draw()
for gy in grid_y: ax.plot([grid_xmin, grid_xmax], [gy, gy], 'k-', lw=2, alpha=0.25) for gx in grid_x: ax.plot([gx, gx], [grid_ymin, grid_ymax], 'k-', lw=2, alpha=0.25) # get highlighted grid squares pick_idx = np.argsort(grid_vals_reduced[j])[::-1][:50] pick_polys = [grid_polys_reduced[k] for k in pick_idx] # get highlighted segments net_pick_idx = np.argsort(net_vals_reduced[j])[::-1][:50] pick_segments = [net_lines_reduced[k] for k in net_pick_idx] pick_segment_mpoly = ops.cascaded_union( [t.buffer(15, 32) for t in pick_segments]) _ = plot_shapely_geos(pick_segment_mpoly, ax=ax, ec='none', fc='c') _ = plot_shapely_geos(pick_polys, ax=ax, edgecolor='b', lw=2, facecolor='none') # grid plot ax = axs[1, i] plots.plot_network_edge_lines(net_lines_reduced, ax=ax, alpha=1., colorbar=False) plot_shaded_regions(grid_polys_reduced, grid_vals_reduced[j], ax=ax,
polys_pred_rank_order = [ vb.roc.grid_polys[i] for i in res['prediction_rank'][-1] ] norm = mpl.colors.Normalize(min(pred_values), max(pred_values)) cmap = mpl.cm.jet sm = mpl.cm.ScalarMappable(norm, cmap) # Figure: surface showing prediction values by grid square fig = plt.figure() ax = fig.add_subplot(111) for (p, r) in zip(polys_pred_rank_order, sorted(pred_values, reverse=True)): # spatial.plot_geodjango_shapes(shapes=(p,), ax=ax, facecolor=sm.to_rgba(r), set_axes=False) try: spatial.plot_shapely_geos(shapes=p, ax=ax, facecolor=sm.to_rgba(r)) except Exception: pass spatial.plot_geodjango_shapes((vb.spatial_domain, ), ax=ax, facecolor='none') # Figure: surface showing true values by grid square norm = mpl.colors.Normalize(min(vb.roc.true_count), max(vb.roc.true_count)) sm = mpl.cm.ScalarMappable(norm, cmap) fig = plt.figure() ax = fig.add_subplot(111) for (p, r) in zip(vb.roc.grid_polys, vb.roc.true_count): # spatial.plot_geodjango_shapes(shapes=(p,), ax=ax, facecolor=sm.to_rgba(r), set_axes=False)
pred_t = 180. arr_fun = lambda x, y: plots.txy_to_cartesian_data_array(np.ones_like(x) * pred_t, x, y) pred_fun = lambda x, y: r.predict(arr_fun(x, y)) xx, yy, zz = spatial.plot_surface_function_on_polygon(domain, pred_fun, ax=ax, fmax=0.98, cmap=cm, dx=50) ax.axis('off') plt.tight_layout() fig.savefig('continuous_heatmap.png', dpi=300) fig.savefig('continuous_heatmap.pdf', dpi=300) # (2) top 10 % grid squares ipolys, full_extents, full_grid_square = create_spatial_grid(domain, 200) grid_values = [] for xmin, ymin, xmax, ymax in full_extents: i, j = np.where((xx >= xmin) & (xx < xmax) & (yy >= ymin) & (yy < ymax)) grid_values.append(zz[i, j].sum()) sort_idx = np.argsort(grid_values)[::-1] top_10_pct = sort_idx[:int(len(sort_idx) * 0.1)] top_10_pct_grids = [shapely_rectangle_from_vertices(*full_extents[i]) for i in top_10_pct] fig = plt.figure(figsize=(5, 6)) ax = fig.add_subplot(111) net.plot_network(ax=ax) spatial.plot_shapely_geos(domain, ax=ax) spatial.plot_shapely_geos(top_10_pct_grids, ax=ax, fc='r', ec='none', lw=1.5, alpha=0.7) ax.axis('off') plt.tight_layout() fig.savefig('top_10_pct_grids.png', dpi=300) fig.savefig('top_10_pct_grids.pdf', dpi=300)
def network_density_movie_slides2(vb, res, t0=None, fmax=None, line_buffer=10, colorbar=False, boundary=None, outdir='network_density_slides'): """ Create image files of network density over a series of predictions :param vb: Validation object :param res: The result of a validation run :param t0: Optional datetime.date corresponding to time zero. :param outdir: The output directory for images, which is created if necessary :param boundary: Optionally supply a Shapely object for plotting :param colorbar: TODO: needs to be implemented :return: None """ os.mkdir(outdir) fmax = fmax or 0.99 n = len(res['cutoff_t']) idx = bisect.bisect_left(np.linspace(0, 1, res['prediction_values'].size), fmax) vmax = sorted(res['prediction_values'].flat)[idx] lines = list(vb.graph.lines_iter()) xy = vb.sample_points.to_cartesian() for i in range(n): z = vb.model.predict( res['cutoff_t'][i], None) # no spatial points needed: reuse sample points z[z > vmax] = vmax fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111) ax.set_xticks([]) ax.set_yticks([]) ax.scatter(xy.toarray(0), xy.toarray(1), c=z, edgecolor='none', cmap='Reds') plot_network_edge_lines(lines, ax=ax, line_buffer=line_buffer) if boundary is not None: plot_shapely_geos(boundary, ax=ax, set_axes=False, facecolor='none', edgecolor='k', linewidth=2.) outfile = os.path.join(outdir, '%03d.png') % (i + 1) if t0: t = t0 + datetime.timedelta(days=res['cutoff_t'][i]) title = t.strftime("%d/%m/%Y") else: title = res['cutoff_t'][i] plt.title(title, fontsize=24) plt.tight_layout(pad=1.5) plt.show() plt.axis('auto') plt.axis('equal') plt.savefig(outfile, dpi=150) plt.close(fig)