Map tree visibility statistics per district¶
Author: Willeke A’Campo
Description: This notebooks shows the results for the tree visibility analysis for the trekroner municipalities: Bodø, Bærum, Kristiansand and Oslo.
Documentation:
Map the indicators for the 3-30-300-rule¶
[ ]:
import os
import leafmap
import pandas as pd
[ ]:
# TODO move
municipality = "kristiansand"
src_crs = "EPSG:25832"
reporting_dir = r"/workspaces/urban-climate/data/08_reporting/"
input_file = os.path.join(reporting_dir,f"{municipality}_district_treeVis_stat.parquet" )
# add layers to gdf for mapping
gdf_mapping = leafmap.read_parquet(
input_file,
return_type='gdf',
src_crs= src_crs ,
dst_crs="EPSG:4326"
)
# Calculate the center of the study_area GeoDataFrame
center = gdf_mapping.geometry.unary_union.centroid
display(gdf_mapping[[
"kommunenavn","grunnkretsnummer", "grunnkretsnavn",
"n_trees", "n_bldg", "n_res_bldg",
"n_trees_near_rbldg","perc_near_rbldg","labels_near_rbldg",
"a_crown", "perc_crown", "labels_perc_crown",
"n_res_bldg_near_gs","perc_near_gs", "labels_near_gs",
"a_open_space", "a_private_space", "a_public_space"
]])
kommunenavn | grunnkretsnummer | grunnkretsnavn | n_trees | n_bldg | n_res_bldg | n_trees_near_rbldg | perc_near_rbldg | labels_near_rbldg | a_crown | perc_crown | labels_perc_crown | n_res_bldg_near_gs | perc_near_gs | labels_near_gs | a_open_space | a_private_space | a_public_space | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Kristiansand | 42040701 | Grim - Dueknipen | 298 | 204 | 87 | 88 | 30 | 25-50% | 24228.22 | 15.40 | 0-25% | 61 | 70.0 | 50-75% | 104499.24 | 32663.19 | 71273.56 |
1 | Kristiansand | 42040702 | Grimsmyra | 632 | 609 | 310 | 509 | 81 | 75-100% | 39153.62 | 15.43 | 0-25% | 286 | 92.0 | 75-100% | 161599.53 | 83491.13 | 75987.51 |
2 | Kristiansand | 42040704 | Møllevannet - Klappane | 154 | 82 | 40 | 70 | 45 | 25-50% | 9176.21 | 13.43 | 0-25% | 40 | 100.0 | 75-100% | 47883.75 | 16124.35 | 31553.15 |
3 | Kristiansand | 42040705 | Enrum - Paradis | 433 | 190 | 78 | 141 | 33 | 25-50% | 35490.59 | 32.06 | 25-50% | 77 | 99.0 | 75-100% | 58644.02 | 27538.81 | 30578.40 |
4 | Kristiansand | 42040801 | Kvadraturen Sørvest | 440 | 307 | 72 | 108 | 25 | 0-25% | 25854.21 | 5.59 | 0-25% | 0 | 0.0 | 0-25% | 205287.23 | 52343.63 | 153860.23 |
5 | Kristiansand | 42040802 | Kvadraturen Nordvest | 439 | 416 | 104 | 108 | 25 | 0-25% | 31861.02 | 9.60 | 0-25% | 0 | 0.0 | 0-25% | 194937.12 | 47966.65 | 147339.89 |
6 | Kristiansand | 42040803 | Kvadraturen Sørøst | 432 | 375 | 170 | 165 | 38 | 25-50% | 26190.16 | 4.59 | 0-25% | 13 | 8.0 | 0-25% | 190027.25 | 57009.83 | 132599.47 |
7 | Kristiansand | 42040804 | Kvadraturen Nordøst | 216 | 695 | 382 | 163 | 75 | 50-75% | 9775.37 | 3.26 | 0-25% | 54 | 14.0 | 0-25% | 145466.62 | 60967.31 | 84394.45 |
8 | Kristiansand | 42040806 | Eg | 366 | 86 | 32 | 158 | 43 | 25-50% | 23503.05 | 24.93 | 0-25% | 32 | 100.0 | 75-100% | 59291.48 | 16598.72 | 42233.00 |
9 | Kristiansand | 42040807 | Sykehuset | 1291 | 99 | 1 | 11 | 1 | 0-25% | 96850.88 | 24.05 | 0-25% | 1 | 100.0 | 75-100% | 257912.45 | 159733.95 | 97249.30 |
10 | Kristiansand | 42040901 | Galgeberg | 333 | 285 | 129 | 173 | 52 | 50-75% | 15768.14 | 6.06 | 0-25% | 129 | 100.0 | 75-100% | 118018.59 | 45730.00 | 71898.16 |
11 | Kristiansand | 42040902 | Hamreheia | 481 | 564 | 250 | 415 | 86 | 75-100% | 23997.30 | 8.18 | 0-25% | 248 | 99.0 | 75-100% | 173022.23 | 90216.37 | 81218.94 |
12 | Kristiansand | 42040903 | Kuholmen | 332 | 395 | 160 | 228 | 69 | 50-75% | 16465.98 | 5.34 | 0-25% | 160 | 100.0 | 75-100% | 188112.45 | 64551.17 | 122261.60 |
13 | Kristiansand | 42040904 | Valhalla Sør | 128 | 241 | 124 | 120 | 94 | 75-100% | 4095.61 | 4.88 | 0-25% | 114 | 92.0 | 75-100% | 62455.76 | 34136.45 | 27904.97 |
14 | Kristiansand | 42040905 | Valhalla Midt | 276 | 499 | 261 | 242 | 88 | 75-100% | 12991.49 | 7.35 | 0-25% | 82 | 31.0 | 25-50% | 124027.37 | 64567.89 | 58371.44 |
15 | Kristiansand | 42040907 | Valhalla Nord - Kongsgård | 439 | 303 | 155 | 328 | 75 | 50-75% | 25669.20 | 12.04 | 0-25% | 155 | 100.0 | 75-100% | 148043.27 | 68896.92 | 77977.48 |
16 | Kristiansand | 42040908 | Solbygg | 122 | 98 | 50 | 63 | 52 | 50-75% | 6955.10 | 6.78 | 0-25% | 50 | 100.0 | 75-100% | 73094.88 | 29007.49 | 43483.53 |
17 | Kristiansand | 42040909 | Kjempegravane | 47 | 132 | 61 | 45 | 96 | 75-100% | 2604.27 | 5.22 | 0-25% | 61 | 100.0 | 75-100% | 34834.33 | 18410.68 | 15887.13 |
18 | Kristiansand | 42040910 | Tobienborg | 381 | 302 | 148 | 164 | 43 | 25-50% | 23394.14 | 12.40 | 0-25% | 148 | 100.0 | 75-100% | 131510.67 | 50772.92 | 79382.28 |
19 | Kristiansand | 42040911 | Nedre Lund | 402 | 526 | 187 | 304 | 76 | 75-100% | 21780.21 | 6.46 | 0-25% | 177 | 95.0 | 75-100% | 205347.41 | 89383.95 | 114498.01 |
20 | Kristiansand | 42040912 | Oddemarka | 118 | 108 | 31 | 65 | 55 | 50-75% | 7577.51 | 10.27 | 0-25% | 31 | 100.0 | 75-100% | 54084.15 | 21627.48 | 32029.34 |
21 | Kristiansand | 42040913 | Flaten | 103 | 162 | 80 | 90 | 87 | 75-100% | 5368.99 | 8.09 | 0-25% | 80 | 100.0 | 75-100% | 45788.73 | 23253.30 | 22286.44 |
22 | Kristiansand | 42040915 | Gimlemoen - Jegersberg | 580 | 40 | 1 | 5 | 1 | 0-25% | 45532.23 | 21.19 | 0-25% | 1 | 100.0 | 75-100% | 145747.75 | 31836.04 | 113747.86 |
23 | Kristiansand | 42040918 | Gimlevang | 34 | 42 | 19 | 18 | 53 | 50-75% | 1886.51 | 4.09 | 0-25% | 19 | 100.0 | 75-100% | 28194.61 | 10814.88 | 17202.92 |
24 | Kristiansand | 42040919 | Gimle | 1175 | 21 | 2 | 18 | 2 | 0-25% | 89392.76 | 48.56 | 25-50% | 2 | 100.0 | 75-100% | 87002.41 | 15415.42 | 71380.45 |
25 | Kristiansand | 42040920 | Marviksletta | 48 | 6 | 0 | 0 | 0 | 0-25% | 3426.57 | 18.12 | 0-25% | 0 | NaN | no data | 12271.83 | 6491.21 | 5721.18 |
26 | Kristiansand | 42040921 | Lund Industriområde | 40 | 9 | 0 | 0 | 0 | 0-25% | 2207.87 | 8.89 | 0-25% | 0 | NaN | no data | 16471.13 | 11996.89 | 4519.13 |
27 | Kristiansand | 42041101 | Nedre Kongsgård | 1008 | 390 | 29 | 55 | 5 | 0-25% | 57912.16 | 18.42 | 0-25% | 29 | 100.0 | 75-100% | 218743.47 | 87159.60 | 130853.74 |
28 | Kristiansand | 42041102 | Kongsgard 1 - Vige | 166 | 9 | 0 | 0 | 0 | 0-25% | 11158.61 | 49.82 | 25-50% | 0 | NaN | no data | 9656.72 | 4293.83 | 5215.83 |
29 | Kristiansand | 42041103 | Bjørndalsheia | 129 | 38 | 12 | 43 | 33 | 25-50% | 8886.66 | 17.37 | 0-25% | 12 | 100.0 | 75-100% | 40086.45 | 5665.55 | 34368.30 |
30 | Kristiansand | 42041104 | Vestre Bjørndalen | 36 | 20 | 2 | 4 | 11 | 0-25% | 1164.64 | 2.24 | 0-25% | 2 | 100.0 | 75-100% | 45113.70 | 11336.80 | 33673.90 |
Rule 3 | all residents should be able to see at least 3 trees from their home.
[ ]:
m = leafmap.Map()
m.set_center(center.x, center.y, zoom=13)
m.add_basemap("CartoDB.Positron")
m.add_data(
gdf_mapping, column='perc_near_rbldg', scheme='Quantiles', cmap='Greens', legend_title='Number of Trees near Residential Buildings'
)
m
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/leafmap/common.py in ?(data, column, cmap, colors, labels, scheme, k, legend_kwds, classification_kwds)
4949 import mapclassify
4950 except ImportError:
-> 4951 raise ImportError(
4952 "mapclassify is required for this function. Install with `pip install mapclassify`."
ModuleNotFoundError: No module named 'mapclassify'
During handling of the above exception, another exception occurred:
ImportError Traceback (most recent call last)
/tmp/ipykernel_591/161069249.py in ?()
1 m = leafmap.Map()
2 m.set_center(center.x, center.y, zoom=13)
3 m.add_basemap("CartoDB.Positron")
----> 4 m.add_data(
5 gdf_mapping, column='perc_near_rbldg', scheme='Quantiles', cmap='Greens', legend_title='Number of Trees near Residential Buildings'
6 )
7 m
/usr/local/lib/python3.10/dist-packages/leafmap/leafmap.py in ?(self, data, column, colors, labels, cmap, scheme, k, add_legend, legend_title, legend_position, legend_kwds, classification_kwds, layer_name, style, hover_style, style_callback, info_mode, encoding, **kwargs)
3839 **kwargs: Additional keyword arguments to pass to the GeoJSON class, such as fields, which can be a list of column names to be included in the popup.
3840
3841 """
3842
-> 3843 gdf, legend_dict = classify(
3844 data=data,
3845 column=column,
3846 cmap=cmap,
/usr/local/lib/python3.10/dist-packages/leafmap/common.py in ?(data, column, cmap, colors, labels, scheme, k, legend_kwds, classification_kwds)
4947
4948 try:
4949 import mapclassify
4950 except ImportError:
-> 4951 raise ImportError(
4952 "mapclassify is required for this function. Install with `pip install mapclassify`."
4953 )
4954
ImportError: mapclassify is required for this function. Install with `pip install mapclassify`.
Rule 30: all neighbourhoods should have 30% tree canopy cover.
[ ]:
m = leafmap.Map()
m.set_center(center.x, center.y, zoom=13)
m.add_basemap("CartoDB.Positron")
m.add_data(
gdf_mapping, column='perc_crown', scheme='Quantiles', cmap='Greens', legend_title='Crown Area (%)'
)
m
Rule 300: all residents should be able to access a green area within 300 m from their home.
[ ]:
gdf_mapping_gs = gdf_mapping.dropna(subset=['n_res_bldg_near_gs_norm'])
m = leafmap.Map()
m.set_center(center.x, center.y, zoom=13)
m.add_basemap("CartoDB.Positron")
m.add_data(
gdf_mapping_gs, column='perc_near_gs', scheme='Quantiles', cmap='Greens', legend_title='Number of Residential Buildings near green spaces'
)
m
TESTING OF LEAFMAP CUSTOM CATEGORICAL MAPPING
[ ]:
#gdf_mapping_gs = gdf_mapping.dropna(subset=['n_res_bldg_near_gs_norm'])
gdf_mapping_gs = gdf_mapping
# Define the bins
bins = pd.IntervalIndex.from_tuples([(-0.01, 25), (25, 50), (50, 75), (75, 100)])
# Create a new column 'categories' based on these bins
gdf_mapping_gs['bins'] = pd.cut(gdf_mapping_gs['n_res_bldg_near_gs_norm'], bins)
gdf_mapping_gs['bins'] = gdf_mapping_gs['bins'].astype(str)
# Define a color mapping for categories
labels = ["no residential buildings", "0-25%", "25-50%", "50-75%", "75-100%"]
color_dict = {"nan":"no residential buildings", "(-0.01, 25.0]": "0-25%", "(25.0, 50.0]": "25-50%", "(50.0, 75.0]": "50-75%", "(75.0, 100.0]": "75-100%"}
# Apply the color mapping to the 'color' column
gdf_mapping_gs['labels'] = gdf_mapping_gs['bins'].map(color_dict)
# Display the DataFrame
display(gdf_mapping_gs[[
"kommunenavn","grunnkretsnummer", "grunnkretsnavn",
"n_bldg", "n_res_bldg", "n_res_bldg_near_gs", "n_res_bldg_near_gs_norm",
"bins", "labels"
]])
kommunenavn | grunnkretsnummer | grunnkretsnavn | n_bldg | n_res_bldg | n_res_bldg_near_gs | n_res_bldg_near_gs_norm | bins | labels | |
---|---|---|---|---|---|---|---|---|---|
0 | Kristiansand | 42040701 | Grim - Dueknipen | 204 | 87 | 61 | 70.0 | (50.0, 75.0] | 50-75% |
1 | Kristiansand | 42040702 | Grimsmyra | 609 | 310 | 286 | 92.0 | (75.0, 100.0] | 75-100% |
2 | Kristiansand | 42040704 | Møllevannet - Klappane | 82 | 40 | 40 | 100.0 | (75.0, 100.0] | 75-100% |
3 | Kristiansand | 42040705 | Enrum - Paradis | 190 | 78 | 77 | 99.0 | (75.0, 100.0] | 75-100% |
4 | Kristiansand | 42040801 | Kvadraturen Sørvest | 307 | 72 | 0 | 0.0 | (-0.01, 25.0] | 0-25% |
5 | Kristiansand | 42040802 | Kvadraturen Nordvest | 416 | 104 | 0 | 0.0 | (-0.01, 25.0] | 0-25% |
6 | Kristiansand | 42040803 | Kvadraturen Sørøst | 375 | 170 | 13 | 8.0 | (-0.01, 25.0] | 0-25% |
7 | Kristiansand | 42040804 | Kvadraturen Nordøst | 695 | 382 | 54 | 14.0 | (-0.01, 25.0] | 0-25% |
8 | Kristiansand | 42040806 | Eg | 86 | 32 | 32 | 100.0 | (75.0, 100.0] | 75-100% |
9 | Kristiansand | 42040807 | Sykehuset | 99 | 1 | 1 | 100.0 | (75.0, 100.0] | 75-100% |
10 | Kristiansand | 42040901 | Galgeberg | 285 | 129 | 129 | 100.0 | (75.0, 100.0] | 75-100% |
11 | Kristiansand | 42040902 | Hamreheia | 564 | 250 | 248 | 99.0 | (75.0, 100.0] | 75-100% |
12 | Kristiansand | 42040903 | Kuholmen | 395 | 160 | 160 | 100.0 | (75.0, 100.0] | 75-100% |
13 | Kristiansand | 42040904 | Valhalla Sør | 241 | 124 | 114 | 92.0 | (75.0, 100.0] | 75-100% |
14 | Kristiansand | 42040905 | Valhalla Midt | 499 | 261 | 82 | 31.0 | (25.0, 50.0] | 25-50% |
15 | Kristiansand | 42040907 | Valhalla Nord - Kongsgård | 303 | 155 | 155 | 100.0 | (75.0, 100.0] | 75-100% |
16 | Kristiansand | 42040908 | Solbygg | 98 | 50 | 50 | 100.0 | (75.0, 100.0] | 75-100% |
17 | Kristiansand | 42040909 | Kjempegravane | 132 | 61 | 61 | 100.0 | (75.0, 100.0] | 75-100% |
18 | Kristiansand | 42040910 | Tobienborg | 302 | 148 | 148 | 100.0 | (75.0, 100.0] | 75-100% |
19 | Kristiansand | 42040911 | Nedre Lund | 526 | 187 | 177 | 95.0 | (75.0, 100.0] | 75-100% |
20 | Kristiansand | 42040912 | Oddemarka | 108 | 31 | 31 | 100.0 | (75.0, 100.0] | 75-100% |
21 | Kristiansand | 42040913 | Flaten | 162 | 80 | 80 | 100.0 | (75.0, 100.0] | 75-100% |
22 | Kristiansand | 42040915 | Gimlemoen - Jegersberg | 40 | 1 | 1 | 100.0 | (75.0, 100.0] | 75-100% |
23 | Kristiansand | 42040918 | Gimlevang | 42 | 19 | 19 | 100.0 | (75.0, 100.0] | 75-100% |
24 | Kristiansand | 42040919 | Gimle | 21 | 2 | 2 | 100.0 | (75.0, 100.0] | 75-100% |
25 | Kristiansand | 42040920 | Marviksletta | 6 | 0 | 0 | NaN | nan | no residential buildings |
26 | Kristiansand | 42040921 | Lund Industriområde | 9 | 0 | 0 | NaN | nan | no residential buildings |
27 | Kristiansand | 42041101 | Nedre Kongsgård | 390 | 29 | 29 | 100.0 | (75.0, 100.0] | 75-100% |
28 | Kristiansand | 42041102 | Kongsgard 1 - Vige | 9 | 0 | 0 | NaN | nan | no residential buildings |
29 | Kristiansand | 42041103 | Bjørndalsheia | 38 | 12 | 12 | 100.0 | (75.0, 100.0] | 75-100% |
30 | Kristiansand | 42041104 | Vestre Bjørndalen | 20 | 2 | 2 | 100.0 | (75.0, 100.0] | 75-100% |
[ ]:
import leafmap
# Initialize the map and set the center
m = leafmap.Map()
m.set_center(center.x, center.y, zoom=13)
# Add the base map
m.add_basemap("CartoDB.Positron")
# Add the data to the map
m.add_data(
data=gdf_mapping_gs,
name="test",
column="labels",
colors=['#169200','#169200','#FFFFFF','#FFAA00','#FF5500'],
labels=["no residential buildings", "0-25%", "25-50%", "50-75%", "75-100%"],
legend_position='bottomright',
style_kwds=dict(color="gray", LineWidth=10, weight=0.99),
style={
"stroke": True,
"color": "gray",
"weight": .5,
"opacity": .5,
"fill": True,
"fillOpacity": 0.5,
}
)
# Display the map
m
[ ]:
color_map = {
"no residential buildings": (0, 136, 55),
"0-25%": (0, 136, 55),
"25-50%": (127, 195, 28),
"50-75%": (127, 195, 28),
"75-100%": (127, 195, 28),
}
leafmap.view_vector(gdf_mapping_gs, color_column='labels', color_map=color_map, opacity=0.5)
#leafmap.Legend(title="Wetland Type", legend_dict=color_map)
#display(gdf_mapping_gs)