kunifujiwara commited on
Commit
fa6051a
·
1 Parent(s): 6e3a184

modify pages

Browse files
Files changed (1) hide show
  1. pages/1_🌲_Japan_Vegetation_Cover.py +44 -204
pages/1_🌲_Japan_Vegetation_Cover.py CHANGED
@@ -1,14 +1,12 @@
1
- import datetime
2
- import os
 
 
 
3
  import pathlib
 
4
  import requests
5
  import zipfile
6
- import pandas as pd
7
- import pydeck as pdk
8
- import geopandas as gpd
9
- import streamlit as st
10
- import leafmap.colormaps as cm
11
- from leafmap.common import hex_to_rgb
12
 
13
  st.set_page_config(layout="wide")
14
 
@@ -27,197 +25,31 @@ st.sidebar.info(
27
  )
28
 
29
  STREAMLIT_STATIC_PATH = pathlib.Path(st.__path__[0]) / "static"
30
- # We create a downloads directory within the streamlit static asset directory
31
- # and we write output files to it
32
  DOWNLOADS_PATH = STREAMLIT_STATIC_PATH / "downloads"
33
  if not DOWNLOADS_PATH.is_dir():
34
  DOWNLOADS_PATH.mkdir()
35
 
36
- # Data source: https://www.realtor.com/research/data/
37
- # link_prefix = "https://econdata.s3-us-west-2.amazonaws.com/Reports/"
38
- link_prefix = "https://raw.githubusercontent.com/giswqs/data/main/housing/"
39
-
40
  data_links = {
41
- "Chiba": {
42
- "national": link_prefix + "Core/listing_weekly_core_aggregate_by_country.csv",
43
- "metro": link_prefix + "Core/listing_weekly_core_aggregate_by_metro.csv",
44
- },
45
- "monthly_current": {
46
- "national": link_prefix + "Core/RDC_Inventory_Core_Metrics_Country.csv",
47
- "state": link_prefix + "Core/RDC_Inventory_Core_Metrics_State.csv",
48
- "metro": link_prefix + "Core/RDC_Inventory_Core_Metrics_Metro.csv",
49
- "county": link_prefix + "Core/RDC_Inventory_Core_Metrics_County.csv",
50
- "zip": link_prefix + "Core/RDC_Inventory_Core_Metrics_Zip.csv",
51
- },
52
- "monthly_historical": {
53
- "national": link_prefix + "Core/RDC_Inventory_Core_Metrics_Country_History.csv",
54
- "state": link_prefix + "Core/RDC_Inventory_Core_Metrics_State_History.csv",
55
- "metro": link_prefix + "Core/RDC_Inventory_Core_Metrics_Metro_History.csv",
56
- "county": link_prefix + "Core/RDC_Inventory_Core_Metrics_County_History.csv",
57
- "zip": link_prefix + "Core/RDC_Inventory_Core_Metrics_Zip_History.csv",
58
- },
59
- "hotness": {
60
- "metro": link_prefix
61
- + "Hotness/RDC_Inventory_Hotness_Metrics_Metro_History.csv",
62
- "county": link_prefix
63
- + "Hotness/RDC_Inventory_Hotness_Metrics_County_History.csv",
64
- "zip": link_prefix + "Hotness/RDC_Inventory_Hotness_Metrics_Zip_History.csv",
65
- },
66
  }
67
 
68
-
69
- def get_data_columns(df, category, frequency="monthly"):
70
- if frequency == "monthly":
71
- if category.lower() == "county":
72
- del_cols = ["month_date_yyyymm", "county_fips", "county_name"]
73
- elif category.lower() == "state":
74
- del_cols = ["month_date_yyyymm", "state", "state_id"]
75
- elif category.lower() == "national":
76
- del_cols = ["month_date_yyyymm", "country"]
77
- elif category.lower() == "metro":
78
- del_cols = ["month_date_yyyymm", "cbsa_code", "cbsa_title", "HouseholdRank"]
79
- elif category.lower() == "zip":
80
- del_cols = ["month_date_yyyymm", "postal_code", "zip_name", "flag"]
81
- elif frequency == "weekly":
82
- if category.lower() == "national":
83
- del_cols = ["week_end_date", "geo_country"]
84
- elif category.lower() == "metro":
85
- del_cols = ["week_end_date", "cbsa_code", "cbsa_title", "hh_rank"]
86
-
87
- cols = df.columns.values.tolist()
88
-
89
- for col in cols:
90
- if col.strip() in del_cols:
91
- cols.remove(col)
92
- if category.lower() == "metro":
93
- return cols[2:]
94
- else:
95
- return cols[1:]
96
-
97
-
98
- @st.cache_data
99
- def get_inventory_data(url):
100
- df = pd.read_csv(url)
101
- url = url.lower()
102
- if "county" in url:
103
- df["county_fips"] = df["county_fips"].map(str)
104
- df["county_fips"] = df["county_fips"].str.zfill(5)
105
- elif "state" in url:
106
- df["STUSPS"] = df["state_id"].str.upper()
107
- elif "metro" in url:
108
- df["cbsa_code"] = df["cbsa_code"].map(str)
109
- elif "zip" in url:
110
- df["postal_code"] = df["postal_code"].map(str)
111
- df["postal_code"] = df["postal_code"].str.zfill(5)
112
-
113
- if "listing_weekly_core_aggregate_by_country" in url:
114
- columns = get_data_columns(df, "national", "weekly")
115
- for column in columns:
116
- if column != "median_days_on_market_by_day_yy":
117
- df[column] = df[column].str.rstrip("%").astype(float) / 100
118
- if "listing_weekly_core_aggregate_by_metro" in url:
119
- columns = get_data_columns(df, "metro", "weekly")
120
- for column in columns:
121
- if column != "median_days_on_market_by_day_yy":
122
- df[column] = df[column].str.rstrip("%").astype(float) / 100
123
- df["cbsa_code"] = df["cbsa_code"].str[:5]
124
- return df
125
-
126
-
127
- def filter_weekly_inventory(df, week):
128
- df = df[df["week_end_date"] == week]
129
- return df
130
-
131
-
132
- def get_start_end_year(df):
133
- start_year = int(str(df["month_date_yyyymm"].min())[:4])
134
- end_year = int(str(df["month_date_yyyymm"].max())[:4])
135
- return start_year, end_year
136
-
137
-
138
- def get_periods(df):
139
- return [str(d) for d in list(set(df["month_date_yyyymm"].tolist()))]
140
-
141
-
142
  @st.cache_data
143
- def get_geom_data(category):
144
-
145
- prefix = (
146
- "https://raw.githubusercontent.com/giswqs/streamlit-geospatial/master/data/"
147
- )
148
- links = {
149
- "national": prefix + "us_nation.geojson",
150
- "state": prefix + "us_states.geojson",
151
- "county": prefix + "us_counties.geojson",
152
- "metro": prefix + "us_metro_areas.geojson",
153
- "zip": "https://www2.census.gov/geo/tiger/GENZ2018/shp/cb_2018_us_zcta510_500k.zip",
154
- }
155
-
156
- if category.lower() == "zip":
157
- r = requests.get(links[category])
158
- out_zip = os.path.join(DOWNLOADS_PATH, "cb_2018_us_zcta510_500k.zip")
159
- with open(out_zip, "wb") as code:
160
- code.write(r.content)
161
- zip_ref = zipfile.ZipFile(out_zip, "r")
162
- zip_ref.extractall(DOWNLOADS_PATH)
163
- gdf = gpd.read_file(out_zip.replace("zip", "shp"))
164
- else:
165
- gdf = gpd.read_file(links[category])
166
  return gdf
167
 
168
-
169
- def join_attributes(gdf, df, category):
170
-
171
- new_gdf = None
172
- if category == "county":
173
- new_gdf = gdf.merge(df, left_on="GEOID", right_on="county_fips", how="outer")
174
- elif category == "state":
175
- new_gdf = gdf.merge(df, left_on="STUSPS", right_on="STUSPS", how="outer")
176
- elif category == "national":
177
- if "geo_country" in df.columns.values.tolist():
178
- df["country"] = None
179
- df.loc[0, "country"] = "United States"
180
- new_gdf = gdf.merge(df, left_on="NAME", right_on="country", how="outer")
181
- elif category == "metro":
182
- new_gdf = gdf.merge(df, left_on="CBSAFP", right_on="cbsa_code", how="outer")
183
- elif category == "zip":
184
- new_gdf = gdf.merge(df, left_on="GEOID10", right_on="postal_code", how="outer")
185
- return new_gdf
186
-
187
 
188
  def select_non_null(gdf, col_name):
189
- new_gdf = gdf[~gdf[col_name].isna()]
190
- return new_gdf
191
-
192
 
193
  def select_null(gdf, col_name):
194
- new_gdf = gdf[gdf[col_name].isna()]
195
- return new_gdf
196
-
197
-
198
- def get_data_dict(name):
199
- in_csv = os.path.join(os.getcwd(), "data/realtor_data_dict.csv")
200
- df = pd.read_csv(in_csv)
201
- label = list(df[df["Name"] == name]["Label"])[0]
202
- desc = list(df[df["Name"] == name]["Description"])[0]
203
- return label, desc
204
-
205
-
206
- def get_weeks(df):
207
- seq = list(set(df[~df["week_end_date"].isnull()]["week_end_date"].tolist()))
208
- weeks = [
209
- datetime.date(int(d.split("/")[2]), int(d.split("/")[0]), int(d.split("/")[1]))
210
- for d in seq
211
- ]
212
- weeks.sort()
213
- return weeks
214
-
215
-
216
- def get_saturday(in_date):
217
- idx = (in_date.weekday() + 1) % 7
218
- sat = in_date + datetime.timedelta(6 - idx)
219
- return sat
220
-
221
 
222
  def app():
223
  st.title("Japan Vegetation Cover Fraction")
@@ -225,18 +57,14 @@ def app():
225
  """**Introduction:** This interactive dashboard is designed for visualizing Japan Fractional Vegetation Cover at town block levels.
226
  The data sources include [Vegetation Cover Fraction](https://zenodo.org/records/5553516) from a research project (https://doi.org/10.3130/aijt.28.521),
227
  and [Cartographic Boundary Files](https://www.e-stat.go.jp/gis/statmap-search?page=1&type=2&aggregateUnitForBoundary=A&toukeiCode=00200521&toukeiYear=2015&serveyId=A002005212015&coordsys=1&format=shape&datum=2000) from Census of Japan 2015.
228
- Several open-source packages are used to process the data and generate the visualizations, e.g., [streamlit](https://streamlit.io),
229
- [geopandas](https://geopandas.org), [leafmap](https://leafmap.org), and [pydeck](https://deckgl.readthedocs.io).
230
- """
231
  )
232
 
233
  prefecture = st.selectbox("Prefecture", ["Tokyo", "Kanagawa", "Chiba", "Saitama"])
234
 
235
- # Load GeoJSON data
236
- gdf = gpd.read_file(f'https://github.com/kunifujiwara/data/blob/master/frac_veg/FRAC_VEG_{prefecture}.geojson')
237
 
238
- # Select attribute to visualize
239
- attributes = gdf.select_dtypes(include=[float, int]).columns.tolist()
240
  selected_attribute = st.selectbox("Select attribute to visualize", attributes)
241
 
242
  row2_col1, row2_col2, row2_col3, row2_col4, row2_col5, row2_col6 = st.columns(
@@ -262,14 +90,13 @@ def app():
262
  else:
263
  elev_scale = 1
264
 
265
- # Create color map
266
  color_scale = cm.LinearColormap(colors=cm.get_palette(palette, n_colors), vmin=gdf[selected_attribute].min(), vmax=gdf[selected_attribute].max())
267
  gdf['color'] = gdf[selected_attribute].apply(lambda x: color_scale(x))
268
-
269
- # Convert hex colors to RGB
270
  gdf['color'] = gdf['color'].apply(lambda x: [int(x[1:3], 16), int(x[3:5], 16), int(x[5:7], 16)])
271
 
272
- # Create PyDeck layer
 
 
273
  layer = pdk.Layer(
274
  "GeoJsonLayer",
275
  gdf,
@@ -287,7 +114,24 @@ def app():
287
  line_width_min_pixels=1,
288
  )
289
 
290
- # Set initial view state
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  view_state = pdk.ViewState(
292
  latitude=gdf.geometry.centroid.y.mean(),
293
  longitude=gdf.geometry.centroid.x.mean(),
@@ -295,23 +139,19 @@ def app():
295
  pitch=45 if show_3d else 0,
296
  )
297
 
298
- # Create PyDeck chart
299
  r = pdk.Deck(
300
- layers=[layer],
301
  initial_view_state=view_state,
302
  map_style="mapbox://styles/mapbox/light-v9",
303
  tooltip={"text": "{NAME}\n{" + selected_attribute + "}"}
304
  )
305
 
306
- # Display the map
307
  st.pydeck_chart(r)
308
 
309
- # Display color scale
310
  st.write(color_scale)
311
 
312
- # Option to show raw data
313
  if st.checkbox("Show raw data"):
314
  st.write(gdf[[selected_attribute, 'NAME']])
315
 
316
-
317
- app()
 
1
+ import streamlit as st
2
+ import geopandas as gpd
3
+ import pydeck as pdk
4
+ import pandas as pd
5
+ from branca import colormap as cm
6
  import pathlib
7
+ import os
8
  import requests
9
  import zipfile
 
 
 
 
 
 
10
 
11
  st.set_page_config(layout="wide")
12
 
 
25
  )
26
 
27
  STREAMLIT_STATIC_PATH = pathlib.Path(st.__path__[0]) / "static"
 
 
28
  DOWNLOADS_PATH = STREAMLIT_STATIC_PATH / "downloads"
29
  if not DOWNLOADS_PATH.is_dir():
30
  DOWNLOADS_PATH.mkdir()
31
 
32
+ # Data source
 
 
 
33
  data_links = {
34
+ "Tokyo": "https://github.com/kunifujiwara/data/blob/master/frac_veg/FRAC_VEG_Tokyo.geojson",
35
+ "Kanagawa": "https://github.com/kunifujiwara/data/blob/master/frac_veg/FRAC_VEG_Kanagawa.geojson",
36
+ "Chiba": "https://github.com/kunifujiwara/data/blob/master/frac_veg/FRAC_VEG_Chiba.geojson",
37
+ "Saitama": "https://github.com/kunifujiwara/data/blob/master/frac_veg/FRAC_VEG_Saitama.geojson",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  @st.cache_data
41
+ def get_geom_data(prefecture):
42
+ gdf = gpd.read_file(data_links[prefecture])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  return gdf
44
 
45
+ def get_data_columns(gdf):
46
+ return gdf.select_dtypes(include=[float, int]).columns.tolist()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  def select_non_null(gdf, col_name):
49
+ return gdf[~gdf[col_name].isna()]
 
 
50
 
51
  def select_null(gdf, col_name):
52
+ return gdf[gdf[col_name].isna()]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  def app():
55
  st.title("Japan Vegetation Cover Fraction")
 
57
  """**Introduction:** This interactive dashboard is designed for visualizing Japan Fractional Vegetation Cover at town block levels.
58
  The data sources include [Vegetation Cover Fraction](https://zenodo.org/records/5553516) from a research project (https://doi.org/10.3130/aijt.28.521),
59
  and [Cartographic Boundary Files](https://www.e-stat.go.jp/gis/statmap-search?page=1&type=2&aggregateUnitForBoundary=A&toukeiCode=00200521&toukeiYear=2015&serveyId=A002005212015&coordsys=1&format=shape&datum=2000) from Census of Japan 2015.
60
+ """
 
 
61
  )
62
 
63
  prefecture = st.selectbox("Prefecture", ["Tokyo", "Kanagawa", "Chiba", "Saitama"])
64
 
65
+ gdf = get_geom_data(prefecture)
 
66
 
67
+ attributes = get_data_columns(gdf)
 
68
  selected_attribute = st.selectbox("Select attribute to visualize", attributes)
69
 
70
  row2_col1, row2_col2, row2_col3, row2_col4, row2_col5, row2_col6 = st.columns(
 
90
  else:
91
  elev_scale = 1
92
 
 
93
  color_scale = cm.LinearColormap(colors=cm.get_palette(palette, n_colors), vmin=gdf[selected_attribute].min(), vmax=gdf[selected_attribute].max())
94
  gdf['color'] = gdf[selected_attribute].apply(lambda x: color_scale(x))
 
 
95
  gdf['color'] = gdf['color'].apply(lambda x: [int(x[1:3], 16), int(x[3:5], 16), int(x[5:7], 16)])
96
 
97
+ gdf_null = select_null(gdf, selected_attribute)
98
+ gdf = select_non_null(gdf, selected_attribute)
99
+
100
  layer = pdk.Layer(
101
  "GeoJsonLayer",
102
  gdf,
 
114
  line_width_min_pixels=1,
115
  )
116
 
117
+ if show_nodata:
118
+ nodata_layer = pdk.Layer(
119
+ "GeoJsonLayer",
120
+ gdf_null,
121
+ pickable=True,
122
+ opacity=0.2,
123
+ stroked=True,
124
+ filled=True,
125
+ extruded=False,
126
+ get_fill_color=[200, 200, 200],
127
+ get_line_color=[0, 0, 0],
128
+ get_line_width=2,
129
+ line_width_min_pixels=1,
130
+ )
131
+ layers = [layer, nodata_layer]
132
+ else:
133
+ layers = [layer]
134
+
135
  view_state = pdk.ViewState(
136
  latitude=gdf.geometry.centroid.y.mean(),
137
  longitude=gdf.geometry.centroid.x.mean(),
 
139
  pitch=45 if show_3d else 0,
140
  )
141
 
 
142
  r = pdk.Deck(
143
+ layers=layers,
144
  initial_view_state=view_state,
145
  map_style="mapbox://styles/mapbox/light-v9",
146
  tooltip={"text": "{NAME}\n{" + selected_attribute + "}"}
147
  )
148
 
 
149
  st.pydeck_chart(r)
150
 
 
151
  st.write(color_scale)
152
 
 
153
  if st.checkbox("Show raw data"):
154
  st.write(gdf[[selected_attribute, 'NAME']])
155
 
156
+ if __name__ == "__main__":
157
+ app()