import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20city_name%20%3D%20%22edinburgh%22%0A%20%20%20%20return%20(city_name%2C)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20geopandas%20as%20gpd%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20from%20scipy.interpolate%20import%20griddata%0A%20%20%20%20from%20shapely%20import%20vectorized%0A%20%20%20%20import%20contextily%20as%20cx%0A%20%20%20%20from%20matplotlib.colors%20import%20BoundaryNorm%0A%20%20%20%20return%20BoundaryNorm%2C%20gpd%2C%20mo%2C%20np%2C%20plt%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20h3_resolution%20%3D%2010%0A%20%20%20%20epsg_metres%20%3D%2027700%20%20%23%20a%20CRS%20that%20has%20unit%20of%20metres%3B%20use%20this%20here%20to%20avoid%20warnings%20about%20area%20calculations%0A%20%20%20%20return%20epsg_metres%2C%20h3_resolution%0A%0A%0A%40app.cell%0Adef%20_(city_name%2C%20h3_resolution)%3A%0A%20%20%20%20arrow_data_file%20%3D%20f%22%7Bcity_name%7D_min_%7Bh3_resolution%7D.arrow%22%0A%20%20%20%20return%20(arrow_data_file%2C)%0A%0A%0A%40app.cell%0Adef%20_(arrow_data_file%2C%20epsg_metres%2C%20gpd)%3A%0A%20%20%20%20heights_gdf%20%3D%20gpd.read_feather(arrow_data_file).to_crs(epsg%3Depsg_metres).copy()%0A%20%20%20%20return%20(heights_gdf%2C)%0A%0A%0A%40app.cell%0Adef%20_(BoundaryNorm%2C%20mo%2C%20np%2C%20plt)%3A%0A%20%20%20%20%40mo.cache%0A%20%20%20%20def%20make_norm(heights_gdf)%3A%0A%20%20%20%20%20%20%20%20min_height%20%3D%20heights_gdf%5B%5B%22min_height%22%5D%5D%0A%20%20%20%20%20%20%20%20percentiles%20%3D%20np.linspace(0%2C%20100%2C%2041)%0A%20%20%20%20%20%20%20%20bounds%20%3D%20np.percentile(min_height%2C%20percentiles)%0A%0A%20%20%20%20%20%20%20%20norm%20%3D%20BoundaryNorm(bounds%2C%20ncolors%3D256)%0A%0A%20%20%20%20%20%20%20%20return%20norm%0A%0A%0A%20%20%20%20def%20plot_boundary(gdf%2C%20ax)%3A%0A%20%20%20%20%20%20%20%20gdf.dissolve().boundary.plot(ax%3Dax%2C%20edgecolor%3D%22black%22%2C%20linewidth%3D0.5)%0A%0A%0A%20%20%20%20%40mo.cache%0A%20%20%20%20def%20make_header_plot(heights_gdf%2C%20height_thresholds%3D%5B%5D)%3A%0A%20%20%20%20%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(figsize%3D(8%2C%208))%0A%20%20%20%20%20%20%20%20ax.set_axis_off()%0A%0A%20%20%20%20%20%20%20%20plot_boundary(heights_gdf%2C%20ax)%0A%0A%20%20%20%20%20%20%20%20norm%20%3D%20make_norm(heights_gdf)%0A%0A%20%20%20%20%20%20%20%20heights_gdf.plot(%22min_height%22%2C%20ax%3Dax%2C%20cmap%3D%22terrain%22%2C%20norm%3Dnorm)%0A%0A%20%20%20%20%20%20%20%20ax_inset%20%3D%20ax.inset_axes(%5B0.6%2C%200.05%2C%200.3%2C%200.25%5D)%0A%20%20%20%20%20%20%20%20ax_inset.hist(heights_gdf%5B%22min_height%22%5D%2C%20bins%3D50%2C%20color%3D%22steelblue%22)%0A%20%20%20%20%20%20%20%20for%20height_threshold%20in%20height_thresholds%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax_inset.axvline(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3Dheight_threshold%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22red%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linestyle%3D%22--%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20linewidth%3D1.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3D%22Threshold%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20ax_inset.set_title(%22Distribution%22%2C%20fontsize%3D9)%0A%20%20%20%20%20%20%20%20ax_inset.set_xlabel(%22height%22%2C%20fontsize%3D8)%0A%20%20%20%20%20%20%20%20for%20spine%20in%20%5B%22left%22%2C%20%22right%22%2C%20%22top%22%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ax_inset.spines%5Bspine%5D.set_visible(False)%0A%20%20%20%20%20%20%20%20ax_inset.yaxis.set_visible(False)%0A%0A%20%20%20%20%20%20%20%20return%20plt.gca()%0A%0A%0A%20%20%20%20%40mo.cache%0A%20%20%20%20def%20make_thresholded_mini_plot(heights_gdf%2C%20height_threshold)%3A%0A%20%20%20%20%20%20%20%20fig%2C%20ax%20%3D%20plt.subplots(figsize%3D(4%2C%204))%0A%20%20%20%20%20%20%20%20ax.set_axis_off()%0A%20%20%20%20%20%20%20%20ax.set_title(f%22%3E%3D%20%7Bheight_threshold%7Dm%22%2C%20fontsize%3D9)%0A%0A%20%20%20%20%20%20%20%20plot_boundary(heights_gdf%2C%20ax)%0A%0A%20%20%20%20%20%20%20%20norm%20%3D%20make_norm(heights_gdf)%0A%0A%20%20%20%20%20%20%20%20thresholded_gdf%20%3D%20heights_gdf%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20heights_gdf%5B%22min_height%22%5D%20%3E%3D%20height_threshold%0A%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%20%20%20%20thresholded_gdf.plot(%22min_height%22%2C%20ax%3Dax%2C%20cmap%3D%22terrain%22%2C%20norm%3Dnorm)%0A%0A%20%20%20%20%20%20%20%20return%20plt.gca()%0A%20%20%20%20return%20make_header_plot%2C%20make_thresholded_mini_plot%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20def%20grid(items%2C%20cols%3D2)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Lay%20out%20items%20in%20a%20grid%20with%20the%20specified%20number%20of%20columns.%22%22%22%0A%20%20%20%20%20%20%20%20rows%20%3D%20%5Bmo.hstack(items%5Bi%20%3A%20i%20%2B%20cols%5D)%20for%20i%20in%20range(0%2C%20len(items)%2C%20cols)%5D%0A%20%20%20%20%20%20%20%20return%20mo.vstack(rows%2C%20gap%3D1)%0A%20%20%20%20return%20(grid%2C)%0A%0A%0A%40app.cell%0Adef%20_(grid%2C%20heights_gdf%2C%20make_header_plot%2C%20make_thresholded_mini_plot%2C%20mo)%3A%0A%20%20%20%20height_thresholds%20%3D%20%5B1%2C%205%2C%2010%2C%2025%2C%20100%2C%20200%2C%20300%2C%20400%5D%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20make_header_plot(heights_gdf%2C%20height_thresholds)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20align%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20grid(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20make_thresholded_mini_plot(heights_gdf%2C%20h)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20h%20in%20height_thresholds%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cols%3D4%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
85e1f01031197b6cff997fd8e6b7c424