Skip to content

Commit 8e2c23e

Browse files
committed
style: update theme colors and enhance chart aesthetics in shelter statistics generation; increase DPI for better image quality
1 parent 7e7feb7 commit 8e2c23e

1 file changed

Lines changed: 81 additions & 71 deletions

File tree

scripts/generate_shelter_statistics.py

Lines changed: 81 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,24 @@
1515
'tufte': {
1616
'name': 'Tufte',
1717
'suffix': '_tufte',
18-
'background': '#f5f5f0',
18+
'background': '#ffffff',
1919
'text': '#333333',
2020
'label': '#555555',
2121
'grid': '#d0d0d0',
2222
'grid_alpha': 0.7,
23-
'bar_color': '#4a7c9b',
24-
'existing_color': '#c45c4a',
25-
'optimal_color': '#4a8c6a',
23+
'bar_color': '#9694FF',
24+
'existing_color': '#D0D0D0',
25+
'existing_line_color': '#2171B5',
26+
'optimal_color': '#3D3BF3',
2627
'value_label': '#666666',
2728
'pie_text': '#ffffff',
28-
'pie_colors': ['#4a7c9b', '#7a9f7a', '#9b8aa0', '#c9a66b', '#d4c878'],
29+
'pie_colors': ['#D0D0D0', '#9694FF', '#7A78FF', '#4292C6', '#2171B5', '#3D3BF3'],
2930
'progression_colors': {
30-
100: '#c45c4a',
31-
150: '#c98a3c',
32-
200: '#a89050',
33-
250: '#4a8c6a',
34-
300: '#3a6a7c'
31+
100: '#9694FF',
32+
150: '#7A78FF',
33+
200: '#4292C6',
34+
250: '#2171B5',
35+
300: '#08306B'
3536
}
3637
},
3738
'dark': {
@@ -184,7 +185,7 @@ def create_shelter_types_chart(type_counts, theme):
184185
ax.set_axisbelow(True)
185186

186187
plt.tight_layout()
187-
plt.savefig(f'output/01_shelter_types{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
188+
plt.savefig(f'output/01_shelter_types{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
188189
facecolor=theme['background'], format='jpeg')
189190
plt.close()
190191

@@ -217,7 +218,7 @@ def create_source_files_chart(source_counts, theme):
217218
ax.set_title('Built Shelters by Data Source', pad=15)
218219

219220
plt.tight_layout()
220-
plt.savefig(f'output/02_data_sources{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
221+
plt.savefig(f'output/02_data_sources{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
221222
facecolor=theme['background'], format='jpeg')
222223
plt.close()
223224

@@ -245,20 +246,23 @@ def create_coverage_analysis(theme):
245246
for stats in coverage_stats.values()]
246247
total_coverage = [stats['coverage_percentage'] for stats in coverage_stats.values()]
247248

248-
ax.plot(radii, existing_coverage, 'o-', linewidth=2, markersize=6, color=theme['existing_color'])
249-
ax.plot(radii, total_coverage, 'o-', linewidth=2, markersize=6, color=theme['optimal_color'])
249+
existing_line_color = theme.get('existing_line_color', theme['existing_color'])
250+
ax.plot(radii, existing_coverage, 'o-', linewidth=3, markersize=6, color=existing_line_color)
251+
ax.plot(radii, total_coverage, 'o-', linewidth=3, markersize=6, color=theme['optimal_color'])
250252

251253
ax.text(radii[-1] + 8, existing_coverage[-1], 'Existing',
252-
va='center', fontsize=9, color=theme['existing_color'])
254+
va='center', fontsize=12, color=existing_line_color)
253255
ax.text(radii[-1] + 8, total_coverage[-1], '+500 Optimal',
254-
va='center', fontsize=9, color=theme['optimal_color'])
256+
va='center', fontsize=12, color=theme['optimal_color'])
255257

256-
ax.set_xlabel('Coverage Radius (m)')
257-
ax.set_ylabel('Building Coverage')
258-
ax.set_title('Shelter Coverage Analysis by Radius', pad=15)
258+
ax.set_xlabel('Coverage Radius (m)', fontsize=14)
259+
ax.set_ylabel('Building Coverage', fontsize=14)
260+
ax.set_title('Shelter Coverage Analysis by Radius', pad=15, fontsize=16)
259261
ax.set_xticks(radii)
262+
ax.set_xticklabels([f'{r}m' for r in radii], fontsize=12)
260263
ax.set_yticks(range(0, 101, 10))
261-
ax.set_yticklabels([f'{y}%' for y in range(0, 101, 10)])
264+
ax.set_yticklabels([f'{y}%' for y in range(0, 101, 10)], fontsize=12)
265+
ax.tick_params(axis='both', labelsize=12)
262266
ax.set_ylim(0, 100)
263267
ax.set_xlim(90, 340)
264268

@@ -267,7 +271,7 @@ def create_coverage_analysis(theme):
267271
ax.set_axisbelow(True)
268272

269273
plt.tight_layout()
270-
plt.savefig(f'output/03_coverage_analysis{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
274+
plt.savefig(f'output/03_coverage_analysis{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
271275
facecolor=theme['background'], format='jpeg')
272276
plt.close()
273277

@@ -284,28 +288,29 @@ def create_coverage_analysis(theme):
284288
bars1 = ax.bar(x - width/2, buildings_existing, width, color=theme['existing_color'], alpha=0.9)
285289
bars2 = ax.bar(x + width/2, buildings_total, width, color=theme['optimal_color'], alpha=0.9)
286290

287-
ax.set_xlabel('Coverage Radius (meters)')
288-
ax.set_ylabel('Buildings Covered')
289-
ax.set_title('Number of Buildings Covered by Radius', pad=15)
291+
ax.set_xlabel('Coverage Radius (meters)', fontsize=14)
292+
ax.set_ylabel('Buildings Covered', fontsize=14)
293+
ax.set_title('Number of Buildings Covered by Radius', pad=15, fontsize=16)
290294
ax.set_xticks(x)
291-
ax.set_xticklabels([f'{r}m' for r in radii])
295+
ax.set_xticklabels([f'{r}m' for r in radii], fontsize=12)
296+
ax.tick_params(axis='y', labelsize=12)
292297

293-
ax.text(x[0] - width/2, buildings_existing[0] + 200, 'Existing',
294-
ha='center', fontsize=8, color=theme['existing_color'])
295-
ax.text(x[0] + width/2, buildings_total[0] + 200, '+500 Optimal',
296-
ha='center', fontsize=8, color=theme['optimal_color'])
298+
ax.text(x[0] - width/2, buildings_existing[0] + 300, 'Existing',
299+
ha='center', fontsize=10, color='#000000')
300+
ax.text(x[0] + width/2, buildings_total[0] + 300, '+500 Optimal',
301+
ha='center', fontsize=10, color='#000000')
297302

298303
ax.text(bars1[-1].get_x() + bars1[-1].get_width()/2., bars1[-1].get_height() + 100,
299-
f'{int(bars1[-1].get_height()):,}', ha='center', va='bottom', fontsize=8, color=theme['value_label'])
304+
f'{int(bars1[-1].get_height()):,}', ha='center', va='bottom', fontsize=10, color='#000000')
300305
ax.text(bars2[-1].get_x() + bars2[-1].get_width()/2., bars2[-1].get_height() + 100,
301-
f'{int(bars2[-1].get_height()):,}', ha='center', va='bottom', fontsize=8, color=theme['value_label'])
306+
f'{int(bars2[-1].get_height()):,}', ha='center', va='bottom', fontsize=10, color='#000000')
302307

303308
setup_tufte_axis(ax)
304309
ax.grid(True, axis='y', linewidth=0.5)
305310
ax.set_axisbelow(True)
306311

307312
plt.tight_layout()
308-
plt.savefig(f'output/04_buildings_covered{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
313+
plt.savefig(f'output/04_buildings_covered{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
309314
facecolor=theme['background'], format='jpeg')
310315
plt.close()
311316

@@ -383,13 +388,14 @@ def create_accessibility_coverage_progression(theme, radius_data, coverage_radii
383388
num_shelters = len(coverage) - 1
384389
x_values = list(range(num_shelters + 1))
385390

386-
ax.plot(x_values, coverage, '-', linewidth=1.8, color=colors[radius], alpha=0.85)
391+
ax.plot(x_values, coverage, '-', linewidth=3, color=colors[radius], alpha=0.85)
387392
ax.text(x_values[-1] + 5, coverage[-1], f'{radius}m',
388-
va='center', fontsize=8, color=colors[radius])
393+
va='center', fontsize=12, color=colors[radius])
389394

390-
ax.set_xlabel('Number of Shelters Added')
391-
ax.set_ylabel('Coverage')
392-
ax.set_title('Coverage Progression by Accessibility Level', pad=15)
395+
ax.set_xlabel('Number of Shelters Added', fontsize=14)
396+
ax.set_ylabel('Coverage', fontsize=14)
397+
ax.set_title('Coverage Progression by Accessibility Level', pad=15, fontsize=16)
398+
ax.tick_params(axis='both', labelsize=12)
393399
ax.set_ylim([0, 100])
394400
ax.set_yticks(range(0, 101, 10))
395401
ax.set_yticklabels([f'{y}%' for y in range(0, 101, 10)])
@@ -399,7 +405,7 @@ def create_accessibility_coverage_progression(theme, radius_data, coverage_radii
399405
ax.set_axisbelow(True)
400406

401407
plt.tight_layout()
402-
plt.savefig(f'output/06_accessibility_coverage_progression{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
408+
plt.savefig(f'output/06_accessibility_coverage_progression{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
403409
facecolor=theme['background'], format='jpeg')
404410
plt.close()
405411

@@ -610,7 +616,7 @@ def create_buildings_per_shelter_comparison(theme, radii, existing_avg, optimal_
610616
ax.set_axisbelow(True)
611617

612618
plt.tight_layout()
613-
plt.savefig(f'output/05_buildings_per_shelter{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
619+
plt.savefig(f'output/05_buildings_per_shelter{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
614620
facecolor=theme['background'], format='jpeg')
615621
plt.close()
616622

@@ -854,7 +860,7 @@ def create_density_scatter(theme, density_data):
854860
ax.set_axisbelow(True)
855861

856862
plt.tight_layout()
857-
plt.savefig(f'output/07_density_scatter{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
863+
plt.savefig(f'output/07_density_scatter{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
858864
facecolor=theme['background'], format='jpeg')
859865
plt.close()
860866

@@ -1101,15 +1107,15 @@ def create_local_density_distribution(theme, local_density_data, theme_name='tuf
11011107
bins = np.arange(0, max_density + 5, 5)
11021108

11031109
# Version 1: All distance layers with intuitive color gradient
1104-
# Gradient from red (no shelter) to green (closest shelter)
1110+
# Gradient from grey (no shelter) to dark purple (closest shelter)
11051111
if theme_name == 'tufte':
11061112
colors_all = [
1107-
'#c45c4a', # no_shelter (red)
1108-
'#d4885a', # 300m (orange-red)
1109-
'#e0a86a', # 250m (orange)
1110-
'#ecc87a', # 200m (yellow-orange)
1111-
'#a8c87a', # 150m (yellow-green)
1112-
'#4a8c6a', # 100m (green)
1113+
'#D0D0D0', # no_shelter (light grey)
1114+
'#EBEAFF', # 300m (light purple/pink)
1115+
'#D5D4FF', # 250m (light-medium purple)
1116+
'#B8B6FF', # 200m (medium-light purple)
1117+
'#9694FF', # 150m (medium purple)
1118+
'#3D3BF3', # 100m (dark purple)
11131119
]
11141120
else: # dark theme
11151121
colors_all = [
@@ -1135,19 +1141,20 @@ def create_local_density_distribution(theme, local_density_data, theme_name='tuf
11351141
ax.hist(data_layers_all, bins=bins,
11361142
color=colors_all, alpha=0.8, edgecolor='none', stacked=True, label=labels_all)
11371143

1138-
ax.set_xlabel('Buildings within 300m')
1139-
ax.set_ylabel('Number of Buildings')
1140-
ax.set_title('Buildings within 300m of Each Building', pad=15)
1144+
ax.set_xlabel('Buildings within 300m', fontsize=14)
1145+
ax.set_ylabel('Number of Buildings', fontsize=14)
1146+
ax.set_title('Buildings within 300m of Each Building', pad=15, fontsize=16)
1147+
ax.tick_params(axis='both', labelsize=12)
11411148

11421149
# Add legend
1143-
ax.legend(loc='upper right', fontsize=8, frameon=False)
1150+
ax.legend(loc='upper right', fontsize=11, frameon=False)
11441151

11451152
setup_tufte_axis(ax)
11461153
ax.grid(True, axis='y', linewidth=0.5)
11471154
ax.set_axisbelow(True)
11481155

11491156
plt.tight_layout()
1150-
plt.savefig(f'output/09_local_density_distribution{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
1157+
plt.savefig(f'output/09_local_density_distribution{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
11511158
facecolor=theme['background'], format='jpeg')
11521159
plt.close()
11531160

@@ -1164,8 +1171,8 @@ def create_local_density_distribution(theme, local_density_data, theme_name='tuf
11641171
])
11651172

11661173
colors_simple = [
1167-
theme['existing_color'], # no_shelter (red)
1168-
theme['progression_colors'][300], # has shelter (green)
1174+
theme['existing_color'], # no_shelter (grey)
1175+
theme['progression_colors'][300], # has shelter (dark purple)
11691176
]
11701177

11711178
data_layers_simple = [
@@ -1178,19 +1185,20 @@ def create_local_density_distribution(theme, local_density_data, theme_name='tuf
11781185
ax2.hist(data_layers_simple, bins=bins,
11791186
color=colors_simple, alpha=0.8, edgecolor='none', stacked=True, label=labels_simple)
11801187

1181-
ax2.set_xlabel('Buildings within 300m')
1182-
ax2.set_ylabel('Number of Buildings')
1183-
ax2.set_title('Buildings within 300m of Each Building', pad=15)
1188+
ax2.set_xlabel('Buildings within 300m', fontsize=14)
1189+
ax2.set_ylabel('Number of Buildings', fontsize=14)
1190+
ax2.set_title('Buildings within 300m of Each Building', pad=15, fontsize=16)
1191+
ax2.tick_params(axis='both', labelsize=12)
11841192

11851193
# Add legend
1186-
ax2.legend(loc='upper right', fontsize=8, frameon=False)
1194+
ax2.legend(loc='upper right', fontsize=11, frameon=False)
11871195

11881196
setup_tufte_axis(ax2)
11891197
ax2.grid(True, axis='y', linewidth=0.5)
11901198
ax2.set_axisbelow(True)
11911199

11921200
plt.tight_layout()
1193-
plt.savefig(f'output/09b_local_density_distribution_simple{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
1201+
plt.savefig(f'output/09b_local_density_distribution_simple{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
11941202
facecolor=theme['background'], format='jpeg')
11951203
plt.close()
11961204

@@ -1253,19 +1261,20 @@ def create_distance_to_shelter_line(theme, local_density_data):
12531261
_, ax = plt.subplots(figsize=(10, 6))
12541262

12551263
# Create line graph
1256-
ax.plot(bin_centers, counts, color=theme['bar_color'], linewidth=2, marker='o', markersize=3)
1264+
ax.plot(bin_centers, counts, color=theme['bar_color'], linewidth=3, marker='o', markersize=3)
12571265

1258-
ax.set_xlabel('Distance to Nearest Shelter (m)')
1259-
ax.set_ylabel('Number of Buildings')
1260-
ax.set_title('Buildings by Distance to Nearest Shelter', pad=15)
1266+
ax.set_xlabel('Distance to Nearest Shelter (m)', fontsize=14)
1267+
ax.set_ylabel('Number of Buildings', fontsize=14)
1268+
ax.set_title('Buildings by Distance to Nearest Shelter', pad=15, fontsize=16)
1269+
ax.tick_params(axis='both', labelsize=12)
12611270
ax.set_xlim(0, 500)
12621271

12631272
setup_tufte_axis(ax)
12641273
ax.grid(True, axis='y', linewidth=0.5)
12651274
ax.set_axisbelow(True)
12661275

12671276
plt.tight_layout()
1268-
plt.savefig(f'output/10_distance_to_shelter_line{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
1277+
plt.savefig(f'output/10_distance_to_shelter_line{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
12691278
facecolor=theme['background'], format='jpeg')
12701279
plt.close()
12711280

@@ -1327,8 +1336,8 @@ def create_local_density_200m(theme, local_density_data, theme_name='tufte'):
13271336

13281337
# Create stacked histogram
13291338
colors_simple = [
1330-
theme['existing_color'], # no_shelter (red)
1331-
theme['optimal_color'], # has shelter (green)
1339+
theme['existing_color'], # no_shelter (grey)
1340+
theme['optimal_color'], # has shelter (dark purple)
13321341
]
13331342

13341343
data_layers = [
@@ -1341,19 +1350,20 @@ def create_local_density_200m(theme, local_density_data, theme_name='tufte'):
13411350
ax.hist(data_layers, bins=bins,
13421351
color=colors_simple, alpha=0.8, edgecolor='none', stacked=True, label=labels)
13431352

1344-
ax.set_xlabel('Buildings within 200m')
1345-
ax.set_ylabel('Number of Buildings')
1346-
ax.set_title('Buildings within 200m of Each Building', pad=15)
1353+
ax.set_xlabel('Buildings within 200m', fontsize=14)
1354+
ax.set_ylabel('Number of Buildings', fontsize=14)
1355+
ax.set_title('Buildings within 200m of Each Building', pad=15, fontsize=16)
1356+
ax.tick_params(axis='both', labelsize=12)
13471357

13481358
# Add legend
1349-
ax.legend(loc='upper right', fontsize=8, frameon=False)
1359+
ax.legend(loc='upper right', fontsize=11, frameon=False)
13501360

13511361
setup_tufte_axis(ax)
13521362
ax.grid(True, axis='y', linewidth=0.5)
13531363
ax.set_axisbelow(True)
13541364

13551365
plt.tight_layout()
1356-
plt.savefig(f'output/09c_local_density_200m{theme["suffix"]}.jpg', dpi=300, bbox_inches='tight',
1366+
plt.savefig(f'output/09c_local_density_200m{theme["suffix"]}.jpg', dpi=600, bbox_inches='tight',
13571367
facecolor=theme['background'], format='jpeg')
13581368
plt.close()
13591369

0 commit comments

Comments
 (0)