AlexanderSvarfdal commited on
Commit
aec6e07
·
1 Parent(s): 302cd89

added line scores tiles

Browse files
app/app.py CHANGED
@@ -61,6 +61,7 @@ with ui.sidebar(open="open"):
61
  ui.input_action_button("reset", "Reset zoom")
62
 
63
  with ui.layout_columns(col_widths=[8, 4]):
 
64
  with ui.card(full_screen=True):
65
  ui.card_header("Capital area")
66
 
@@ -69,179 +70,215 @@ with ui.layout_columns(col_widths=[8, 4]):
69
  def map():
70
  return Map(
71
  basemap=basemaps.CartoDB.Positron)
 
 
 
 
 
72
 
73
- with ui.layout_column_wrap(width="250px"):
74
- with ui.card(full_screen=False):
75
- ui.card_header("Stop Data")
76
- with ui.navset_pill(id="tab"):
77
- with ui.nav_panel("Total Score"):
78
- "Total Score"
79
  @render.text
80
- def totalScore():
81
- score = scores()
82
- return f"{round(float(score["total_score"]), 2)}"
 
83
 
84
- @render.plot(alt="A pie chart of score contributions from age, income, and density.")
85
- def contribution_pie_chart():
86
- print("Generating pie chart of contributions")
87
-
88
- # Get score components
89
- score = scores()
90
- age_contribution = score["age_score"]
91
- income_contribution = score["income_score"]
92
- density_contribution = score["density_score"]
93
-
94
- # Data for the pie chart
95
- contributions = [age_contribution, income_contribution, density_contribution]
96
- labels = ["Age", "Income", "Density"]
97
- colors = ["#FD4D86", "#36DEC2", "#704CB0"] # Custom colors for the segments
98
-
99
- # Create a Matplotlib figure
100
- fig, ax = plt.subplots(figsize=(6, 6))
101
-
102
- # Create the pie chart
103
- ax.pie(
104
- contributions,
105
- labels=labels,
106
- autopct='%1.1f%%',
107
- startangle=90,
108
- colors=colors,
109
- textprops={'fontsize': 12}
110
- )
111
-
112
- # Add a title
113
- ax.set_title("Score Contributions", fontsize=16)
114
-
115
- # Return the figure for rendering in Shiny
116
- return fig
117
-
118
- with ui.nav_panel("Income"):
119
- "Income Score"
120
  @render.text
121
- def incomeScore():
122
- score = scores()
123
- return f"{round(float(score["income_score"]), 2)}"
124
- @render.plot(alt="A chart of income distribution.")
125
- def income_plot():
126
- print("Generating income distribution bar chart")
127
-
128
- # Get selected stop coordinates
129
- x, y = stop.get()
130
- station_coord = (y, x)
131
-
132
- # Fetch income distribution data from the Data_provider instance
133
- income_data = initBackend.get_station_score(station_coord, radius=input.rad())['income_data'] # Assume this returns a dictionary
134
-
135
- # Example structure: {1: 150, 2: 200, 3: 180, ...}
136
- income_brackets = list(income_data.keys())
137
- populations = list(income_data.values())
138
-
139
- # Create a Matplotlib figure
140
- fig, ax = plt.subplots(figsize=(8, 4))
141
-
142
- # Create the bar chart
143
- ax.bar(income_brackets, populations, color='#36DEC2')
144
-
145
- # Customize the plot
146
- ax.set_title("Population by Income Bracket")
147
- ax.set_xlabel("Income Bracket")
148
- ax.set_ylabel("Population")
149
- ax.set_xticks(income_brackets)
150
- ax.set_xticklabels(income_brackets, rotation=45, ha="right")
151
-
152
- # Return the figure for rendering in Shiny
153
- return fig
154
 
155
-
156
- with ui.nav_panel("Age"):
157
- "Age Score"
158
  @render.text
159
- def ageScore():
160
- score = scores()
161
- return f"{round(float(score["age_score"]), 2)}"
162
-
163
- @render.plot(alt="A bar chart of age distribution.")
164
- def age_plot():
165
- print("Generating age distribution bar chart")
166
-
167
- # Get selected stop coordinates
168
- x, y = stop.get()
169
- station_coord = (y, x)
170
-
171
- # Fetch age distribution data from the Data_provider instance
172
- age_data = initBackend.get_station_score(station_coord, radius=input.rad())['age_data'] # Assume this returns a dictionary
173
-
174
- # Example structure: {'0-4 ára': 120, '5-9 ára': 140, ...}
175
- age_brackets = list(age_data.keys())
176
- populations = list(age_data.values())
177
-
178
- # Create a Matplotlib figure
179
- fig, ax = plt.subplots(figsize=(8, 4))
180
-
181
- # Create the bar chart with custom colors
182
- ax.bar(age_brackets, populations, color='#FD4D86')
183
-
184
- # Customize the plot
185
- ax.set_title("Population by Age Bracket", fontsize=14)
186
- ax.set_xlabel("Age Bracket", fontsize=12)
187
- ax.set_ylabel("Population", fontsize=12)
188
- ax.set_xticks(range(len(age_brackets)))
189
- ax.set_xticklabels(age_brackets, rotation=45, ha="right", fontsize=10)
190
-
191
- # Return the figure for rendering in Shiny
192
- return fig
193
-
194
- with ui.nav_panel("Density"):
195
- "Density"
196
  @render.text
197
- def sensityScoer():
198
- score = scores()
199
- return f"{round(float(score["density_score"] * 1000000), 2)} Person / Kilometer"
200
-
201
-
202
- return f"{round(float(score["density_score"]), 2)}"
203
- @render.plot(alt="A bar chart of density scores for all areas within the radius.")
204
- def density_plot():
205
- print("Generating density score bar chart")
206
-
207
- # Get selected stop coordinates
208
- x, y = stop.get()
209
- station_coord = (y, x)
210
-
211
- # Fetch small area contributions from the Data_provider instance
212
- small_area_contributions = initBackend.get_station_score(
213
- station_coord,
214
- radius=input.rad(),
215
- w_density=input.w_density(),
216
- w_income=input.w_income(),
217
- w_age=input.w_age()
218
- )['small_area_contributions']
219
-
220
- # Extract density scores for each small area
221
- area_ids = [area_id for area_id in small_area_contributions.keys()]
222
- density_scores = [area_data['density_score'] for area_data in small_area_contributions.values()]
223
 
224
- # Create a Matplotlib figure
225
- fig, ax = plt.subplots(figsize=(8, 4))
226
 
227
- # Create the bar chart
228
- ax.bar(area_ids, density_scores, color='#704CB0')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
- # Customize the plot
231
- ax.set_title("Density Scores of Small Areas", fontsize=14)
232
- ax.set_xlabel("Small Area ID", fontsize=12)
233
- ax.set_ylabel("Density Score", fontsize=12)
234
- ax.set_xticks(range(len(area_ids)))
235
- ax.set_xticklabels(area_ids, rotation=45, ha="right", fontsize=10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- # Return the figure for rendering in Shiny
238
- return fig
239
 
240
- with ui.nav_panel("The Line"):
241
- "The Total Score For Lines"
242
- @render.text
243
- def line():
244
- return lineScore()
245
 
246
 
247
 
@@ -324,27 +361,37 @@ def scores():
324
  score = initBackend.get_station_score(station_coord=(y, x), w_density=input.w_density(), w_income=input.w_income(), w_age=input. w_age(), radius=input.rad())
325
  return score
326
 
327
-
328
  @reactive.calc
329
  def lineScore():
 
330
  listOfStops = generateStops(input.year())
331
  listOflines = {}
 
 
332
  for stop, color in listOfStops:
333
  x, y = stop
334
- if color not in listOflines:
335
- listOflines[color] = []
336
- listOflines[color].append((y, x))
337
-
338
-
 
 
 
 
 
 
339
 
340
- lines = []
 
341
  for key, val in listOflines.items():
342
-
343
- score = initBackend.line_score(val, w_density=input.w_density(), w_income=input.w_income(), w_age=input. w_age(), radius=input.rad())
344
-
345
- lines.append((key, score["final_score"]))
346
-
347
- # Format the output
348
- formatted_output = "\n".join(f"{key}: {float(value):.3f}" for key, value in lines)
349
- print(formatted_output)
350
- return formatted_output
 
 
61
  ui.input_action_button("reset", "Reset zoom")
62
 
63
  with ui.layout_columns(col_widths=[8, 4]):
64
+
65
  with ui.card(full_screen=True):
66
  ui.card_header("Capital area")
67
 
 
70
  def map():
71
  return Map(
72
  basemap=basemaps.CartoDB.Positron)
73
+
74
+
75
+
76
+
77
+
78
 
79
+
80
+
81
+ with ui.layout_column_wrap(width="450px"):
82
+ with ui.layout_columns(col_widths=(6, 6)):
83
+ with ui.value_box(theme="bg-gradient-red-yellow"):
84
+ "Red line"
85
  @render.text
86
+ def render_line_score():
87
+ return str(lineScore().get("red", 0))
88
+
89
+ with ui.value_box(theme="bg-gradient-blue-cyan"):
90
 
91
+ "Blue line"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  @render.text
93
+ def render_line_score1():
94
+ return str(lineScore().get("blue", 0))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
+ with ui.value_box(theme="bg-gradient-orange-yellow"):
97
+ "Orange line"
 
98
  @render.text
99
+ def render_line_score2():
100
+ return str(lineScore().get("orange", 0))
101
+
102
+ with ui.value_box(theme="bg-gradient-indigo-purple"):
103
+ "Purple line"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  @render.text
105
+ def render_line_score3():
106
+ return str(lineScore().get("purple", 0))
107
+
108
+ with ui.value_box(theme="bg-gradient-green-teal"):
109
+ "Green line"
110
+ @render.text
111
+ def render_line_score4():
112
+ return str(lineScore().get("green", 0))
113
+
114
+ with ui.value_box():
115
+ "Total score"
116
+ @render.text
117
+ def render_line_score5():
118
+ return str(sum(lineScore().get(color, 0) for color in ["red", "blue", "orange", "purple", "green"]))
119
+
120
+
121
+ with ui.card(min_height="600px"):
122
+ ui.card_header("Stop Data")
123
+ with ui.navset_pill(id="tab"):
124
+ with ui.nav_panel("Score Contributions"):
 
 
 
 
 
 
125
 
 
 
126
 
127
+ @render.plot(alt="A pie chart of score contributions from age, income, and density.")
128
+ def contribution_pie_chart():
129
+ print("Generating pie chart of contributions")
130
+
131
+ # Get score components
132
+ score = scores()
133
+ age_contribution = score["age_score"]
134
+ income_contribution = score["income_score"]
135
+ density_contribution = score["density_score"]
136
+
137
+ # Data for the pie chart
138
+ contributions = [age_contribution, income_contribution, density_contribution]
139
+ labels = ["Age", "Income", "Density"]
140
+ colors = ["#FD4D86", "#36DEC2", "#704CB0"] # Custom colors for the segments
141
+
142
+ # Create a Matplotlib figure
143
+ fig, ax = plt.subplots(figsize=(6, 6))
144
+
145
+ # Create the pie chart
146
+ ax.pie(
147
+ contributions,
148
+ labels=labels,
149
+ autopct='%1.1f%%',
150
+ startangle=90,
151
+ colors=colors,
152
+ textprops={'fontsize': 12}
153
+ )
154
+
155
+ # Add a title
156
+ ax.set_title("Score Contributions", fontsize=16)
157
+
158
+ # Return the figure for rendering in Shiny
159
+ return fig
160
+
161
+ with ui.nav_panel("Income"):
162
+ "Income Score"
163
+ @render.text
164
+ def incomeScore():
165
+ score = scores()
166
+ return score["income_score"]
167
+ @render.plot(alt="A chart of income distribution.")
168
+ def income_plot():
169
+ print("Generating income distribution bar chart")
170
+
171
+ # Get selected stop coordinates
172
+ x, y = stop.get()
173
+ station_coord = (y, x)
174
+
175
+ # Fetch income distribution data from the Data_provider instance
176
+ income_data = initBackend.get_station_score(station_coord, radius=input.rad())['income_data'] # Assume this returns a dictionary
177
+
178
+ # Example structure: {1: 150, 2: 200, 3: 180, ...}
179
+ income_brackets = list(income_data.keys())
180
+ populations = list(income_data.values())
181
+
182
+ # Create a Matplotlib figure
183
+ fig, ax = plt.subplots(figsize=(8, 4))
184
+
185
+ # Create the bar chart
186
+ ax.bar(income_brackets, populations, color='#36DEC2')
187
+
188
+ # Customize the plot
189
+ ax.set_title("Population by Income Bracket")
190
+ ax.set_xlabel("Income Bracket")
191
+ ax.set_ylabel("Population")
192
+ ax.set_xticks(income_brackets)
193
+ ax.set_xticklabels(income_brackets, rotation=45, ha="right")
194
+
195
+ # Return the figure for rendering in Shiny
196
+ return fig
197
+
198
+
199
+ with ui.nav_panel("Age"):
200
+ "Age Score"
201
+ @render.text
202
+ def ageScore():
203
+ score = scores()
204
+ return score["age_score"]
205
+ @render.plot(alt="A bar chart of age distribution.")
206
+ def age_plot():
207
+ print("Generating age distribution bar chart")
208
+
209
+ # Get selected stop coordinates
210
+ x, y = stop.get()
211
+ station_coord = (y, x)
212
+
213
+ # Fetch age distribution data from the Data_provider instance
214
+ age_data = initBackend.get_station_score(station_coord, radius=input.rad())['age_data'] # Assume this returns a dictionary
215
+
216
+ # Example structure: {'0-4 ára': 120, '5-9 ára': 140, ...}
217
+ age_brackets = list(age_data.keys())
218
+ populations = list(age_data.values())
219
+
220
+ # Create a Matplotlib figure
221
+ fig, ax = plt.subplots(figsize=(8, 4))
222
+
223
+ # Create the bar chart with custom colors
224
+ ax.bar(age_brackets, populations, color='#FD4D86')
225
+
226
+ # Customize the plot
227
+ ax.set_title("Population by Age Bracket", fontsize=14)
228
+ ax.set_xlabel("Age Bracket", fontsize=12)
229
+ ax.set_ylabel("Population", fontsize=12)
230
+ ax.set_xticks(range(len(age_brackets)))
231
+ ax.set_xticklabels(age_brackets, rotation=45, ha="right", fontsize=10)
232
+
233
+ # Return the figure for rendering in Shiny
234
+ return fig
235
 
236
+ with ui.nav_panel("Density"):
237
+ "Density"
238
+ @render.text
239
+ def sensityScoer():
240
+ score = scores()
241
+ return float(score["density_score"] * 1000000)
242
+
243
+
244
+ @render.plot(alt="A bar chart of density scores for all areas within the radius.")
245
+ def density_plot():
246
+ print("Generating density score bar chart")
247
+
248
+ # Get selected stop coordinates
249
+ x, y = stop.get()
250
+ station_coord = (y, x)
251
+
252
+ # Fetch small area contributions from the Data_provider instance
253
+ small_area_contributions = initBackend.get_station_score(
254
+ station_coord,
255
+ radius=input.rad(),
256
+ w_density=input.w_density(),
257
+ w_income=input.w_income(),
258
+ w_age=input.w_age()
259
+ )['small_area_contributions']
260
+
261
+ # Extract density scores for each small area
262
+ area_ids = [area_id for area_id in small_area_contributions.keys()]
263
+ density_scores = [area_data['density_score'] for area_data in small_area_contributions.values()]
264
+
265
+ # Create a Matplotlib figure
266
+ fig, ax = plt.subplots(figsize=(8, 4))
267
+
268
+ # Create the bar chart
269
+ ax.bar(area_ids, density_scores, color='#704CB0')
270
+
271
+ # Customize the plot
272
+ ax.set_title("Density Scores of Small Areas", fontsize=14)
273
+ ax.set_xlabel("Small Area ID", fontsize=12)
274
+ ax.set_ylabel("Density Score", fontsize=12)
275
+ ax.set_xticks(range(len(area_ids)))
276
+ ax.set_xticklabels(area_ids, rotation=45, ha="right", fontsize=10)
277
+
278
+ # Return the figure for rendering in Shiny
279
+ return fig
280
 
 
 
281
 
 
 
 
 
 
282
 
283
 
284
 
 
361
  score = initBackend.get_station_score(station_coord=(y, x), w_density=input.w_density(), w_income=input.w_income(), w_age=input. w_age(), radius=input.rad())
362
  return score
363
 
 
364
  @reactive.calc
365
  def lineScore():
366
+ # Generate stops based on the input year
367
  listOfStops = generateStops(input.year())
368
  listOflines = {}
369
+
370
+ # Handle stops with single and multiple colors
371
  for stop, color in listOfStops:
372
  x, y = stop
373
+ # If the color is a list (multiple colors), iterate through it
374
+ if isinstance(color, list):
375
+ for single_color in color:
376
+ if single_color not in listOflines:
377
+ listOflines[single_color] = []
378
+ listOflines[single_color].append((y, x))
379
+ else:
380
+ # If it's a single color, process it normally
381
+ if color not in listOflines:
382
+ listOflines[color] = []
383
+ listOflines[color].append((y, x))
384
 
385
+ # Calculate scores for each line
386
+ lines = {}
387
  for key, val in listOflines.items():
388
+ score = initBackend.line_score(
389
+ val,
390
+ w_density=input.w_density(),
391
+ w_income=input.w_income(),
392
+ w_age=input.w_age(),
393
+ radius=input.rad()
394
+ )
395
+ lines[key] = score["final_score"]
396
+
397
+ return lines
app/data_processing/get_station_coverage.py CHANGED
@@ -35,7 +35,7 @@ def get_station_coverage(
35
 
36
  # Validate and fix invalid geometries
37
  if not geometry.is_valid:
38
- print(f"Invalid geometry detected for Area ID: {area['id']}. Attempting to fix.")
39
  geometry = make_valid(geometry)
40
 
41
  # Simplify geometry to avoid potential issues with highly complex polygons
 
35
 
36
  # Validate and fix invalid geometries
37
  if not geometry.is_valid:
38
+ # print(f"Invalid geometry detected for Area ID: {area['id']}. Attempting to fix.")
39
  geometry = make_valid(geometry)
40
 
41
  # Simplify geometry to avoid potential issues with highly complex polygons