cjber commited on
Commit
810f15e
·
1 Parent(s): 62a60b6

feat: adjust document styling

Browse files
Files changed (2) hide show
  1. planning_ai/document.py +60 -30
  2. planning_ai/main.py +0 -1
planning_ai/document.py CHANGED
@@ -4,6 +4,7 @@ import re
4
  from collections import Counter
5
 
6
  import geopandas as gpd
 
7
  import matplotlib.pyplot as plt
8
  import numpy as np
9
  import polars as pl
@@ -11,6 +12,9 @@ from polars.dependencies import subprocess
11
 
12
  from planning_ai.common.utils import Paths
13
 
 
 
 
14
 
15
  def _process_postcodes(final):
16
  documents = final["documents"]
@@ -83,8 +87,9 @@ def _process_stances(final):
83
 
84
  def _process_themes(final):
85
  documents = final["documents"]
86
- themes = [list(doc["themes"]) for doc in documents]
87
- themes = Counter(list(itertools.chain.from_iterable(themes)))
 
88
  themes = pl.DataFrame(themes).transpose(include_header=True)
89
  themes_breakdown = themes.with_columns(
90
  ((pl.col("column_0") / pl.sum("column_0")) * 100).round(2).alias("percentage")
@@ -96,41 +101,61 @@ def _process_themes(final):
96
 
97
 
98
  def fig_oa(postcodes):
 
 
 
 
 
 
 
 
99
  oac = pl.read_csv(Paths.RAW / "oac21ew.csv")
100
- postcodes = (
 
101
  postcodes.join(oac, left_on="OA21", right_on="oa21cd")
102
  .group_by("supergroup")
103
- .len()
 
104
  .sort("supergroup")
 
 
 
 
 
 
105
  )
106
- postcodes_pd = postcodes.to_pandas()
107
 
108
  _, ax1 = plt.subplots()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- ax1.bar(postcodes_pd["supergroup"], postcodes_pd["len"])
111
  ax1.set_xlabel("Output Area Classification (OAC) Supergroup")
112
- ax1.set_ylabel("Number of Representations")
 
 
113
 
 
114
  plt.tight_layout()
115
 
116
  plt.savefig(Paths.SUMMARY / "figs" / "oas.png")
117
 
118
 
119
  def fig_wards(postcodes):
120
- wards = (
121
- pl.read_csv(Paths.RAW / "TS001-2021-3-filtered-2025-01-09T11_07_15Z.csv")
122
- .rename(
123
- {
124
- "Electoral wards and divisions Code": "OSWARD",
125
- "Electoral wards and divisions": "WARDNAME",
126
- }
127
- )
128
- .group_by(["OSWARD", "WARDNAME"])
129
- .sum()
130
- )
131
- postcodes = postcodes.join(wards, on="OSWARD").with_columns(
132
- ((pl.col("count") / pl.col("Observation")) * 100).alias("prop")
133
- )
134
  ward_boundaries = gpd.read_file(
135
  Paths.RAW / "Wards_December_2021_GB_BFE_2022_7523259277605796091.zip"
136
  )
@@ -218,7 +243,7 @@ def fig_imd(postcodes):
218
  x - bar_width / 2, # Shift to the left
219
  postcodes_pd["perc_count"],
220
  width=bar_width,
221
- label="Percentage of Count (%)",
222
  )
223
 
224
  # Plot the second set of bars
@@ -226,17 +251,17 @@ def fig_imd(postcodes):
226
  x + bar_width / 2, # Shift to the right
227
  postcodes_pd["perc_pop"],
228
  width=bar_width,
229
- label="Percentage of Population (%)",
230
  )
231
 
232
  # Set labels and ticks
233
  ax1.set_xlabel("IMD Quintile")
234
- ax1.set_ylabel("Proportion of Population (%)")
235
  ax1.set_xticks(x) # Set x-ticks to correspond to the positions
236
  ax1.set_xticklabels(postcodes_pd["LA_decile"])
237
 
238
  # Add a legend
239
- ax1.legend()
240
 
241
  # Adjust layout
242
  plt.tight_layout()
@@ -284,15 +309,20 @@ The following section provides a detailed breakdown of notable details from resp
284
  f"{introduction_paragraph}\n\n"
285
  "\n# Figures\n\n"
286
  f"{figures_paragraph}\n\n"
287
- f"![Total number of representations submitted by Ward.](./figs/wards.png){{#fig-wards}}\n\n"
288
- f"![Total number of representations submitted by Output Area (OA 2021).](./figs/oas.png){{#fig-oas}}\n\n"
289
  f"![Percentage of representations submitted by quintile of index of multiple deprivation (2019)](./figs/imd_decile.png){{#fig-imd}}\n\n"
290
- "# Themes and Policies\n\n"
 
291
  f"{themes_paragraph}\n\n"
292
  f"{themes}{{#tbl-themes}}\n\n"
293
- "## Support\n\n"
 
 
294
  f"{support_policies}\n\n"
295
- "## Object\n\n"
 
 
296
  f"{object_policies}\n\n"
297
  "## Other\n\n"
298
  f"{other_policies}\n\n"
 
4
  from collections import Counter
5
 
6
  import geopandas as gpd
7
+ import matplotlib as mpl
8
  import matplotlib.pyplot as plt
9
  import numpy as np
10
  import polars as pl
 
12
 
13
  from planning_ai.common.utils import Paths
14
 
15
+ mpl.rcParams["text.usetex"] = True
16
+ mpl.rcParams["text.latex.preamble"] = r"\usepackage{libertine}"
17
+
18
 
19
  def _process_postcodes(final):
20
  documents = final["documents"]
 
87
 
88
  def _process_themes(final):
89
  documents = final["documents"]
90
+ themes = Counter(
91
+ [theme["theme"].value for doc in documents for theme in doc["themes"]]
92
+ )
93
  themes = pl.DataFrame(themes).transpose(include_header=True)
94
  themes_breakdown = themes.with_columns(
95
  ((pl.col("column_0") / pl.sum("column_0")) * 100).round(2).alias("percentage")
 
101
 
102
 
103
  def fig_oa(postcodes):
104
+ oa_pop = pl.read_csv(Paths.RAW / "oa_populations.csv")
105
+ oa_pop = (
106
+ oa_pop.group_by(pl.col("Output Areas Code"))
107
+ .sum()
108
+ .rename({"Output Areas Code": "OA2021", "Observation": "population"})
109
+ .select(["OA2021", "population"])
110
+ )
111
+
112
  oac = pl.read_csv(Paths.RAW / "oac21ew.csv")
113
+ oac = oac.join(oa_pop, left_on="oa21cd", right_on="OA2021")
114
+ oac = (
115
  postcodes.join(oac, left_on="OA21", right_on="oa21cd")
116
  .group_by("supergroup")
117
+ .sum()
118
+ .select(["supergroup", "population", "count"])
119
  .sort("supergroup")
120
+ .with_columns(
121
+ ((pl.col("count") / pl.col("count").sum()) * 100).alias("perc_count"),
122
+ ((pl.col("population") / pl.col("population").sum()) * 100).alias(
123
+ "perc_pop"
124
+ ),
125
+ )
126
  )
127
+ oa_pd = oac.to_pandas()
128
 
129
  _, ax1 = plt.subplots()
130
+ bar_width = 0.35
131
+ x = np.arange(len(oa_pd))
132
+
133
+ ax1.bar(
134
+ x - bar_width / 2,
135
+ oa_pd["perc_count"],
136
+ width=bar_width,
137
+ label="Percentage of Representations (\%)",
138
+ )
139
+
140
+ ax1.bar(
141
+ x + bar_width / 2,
142
+ oa_pd["perc_pop"],
143
+ width=bar_width,
144
+ label="Percentage of Population (\%)",
145
+ )
146
 
 
147
  ax1.set_xlabel("Output Area Classification (OAC) Supergroup")
148
+ ax1.set_ylabel("Proportion of Population (\%)")
149
+ ax1.set_xticks(x)
150
+ ax1.set_xticklabels(oa_pd["supergroup"])
151
 
152
+ ax1.legend(loc="upper center", bbox_to_anchor=(0.5, -0.1), ncol=5, frameon=False)
153
  plt.tight_layout()
154
 
155
  plt.savefig(Paths.SUMMARY / "figs" / "oas.png")
156
 
157
 
158
  def fig_wards(postcodes):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  ward_boundaries = gpd.read_file(
160
  Paths.RAW / "Wards_December_2021_GB_BFE_2022_7523259277605796091.zip"
161
  )
 
243
  x - bar_width / 2, # Shift to the left
244
  postcodes_pd["perc_count"],
245
  width=bar_width,
246
+ label="Percentage of Representations (\%)",
247
  )
248
 
249
  # Plot the second set of bars
 
251
  x + bar_width / 2, # Shift to the right
252
  postcodes_pd["perc_pop"],
253
  width=bar_width,
254
+ label="Percentage of Population (\%)",
255
  )
256
 
257
  # Set labels and ticks
258
  ax1.set_xlabel("IMD Quintile")
259
+ ax1.set_ylabel("Proportion of Population (\%)")
260
  ax1.set_xticks(x) # Set x-ticks to correspond to the positions
261
  ax1.set_xticklabels(postcodes_pd["LA_decile"])
262
 
263
  # Add a legend
264
+ ax1.legend(loc="upper center", bbox_to_anchor=(0.5, -0.1), ncol=5, frameon=False)
265
 
266
  # Adjust layout
267
  plt.tight_layout()
 
309
  f"{introduction_paragraph}\n\n"
310
  "\n# Figures\n\n"
311
  f"{figures_paragraph}\n\n"
312
+ f"![Total number of representations submitted by Ward](./figs/wards.png){{#fig-wards}}\n\n"
313
+ f"![Total number of representations submitted by Output Area (OA 2021)](./figs/oas.png){{#fig-oas}}\n\n"
314
  f"![Percentage of representations submitted by quintile of index of multiple deprivation (2019)](./figs/imd_decile.png){{#fig-imd}}\n\n"
315
+ r"\newpage"
316
+ "\n\n# Themes and Policies\n\n"
317
  f"{themes_paragraph}\n\n"
318
  f"{themes}{{#tbl-themes}}\n\n"
319
+ "## Supporting Representations\n\n"
320
+ "The following section outlines key points relating to policies, taken from documents where the "
321
+ "respondent indicated that they support the plan.\n\n"
322
  f"{support_policies}\n\n"
323
+ "## Objecting Representations\n\n"
324
+ "The following section outlines key points relating to policies, taken from documents where the "
325
+ "respondent indicated that they object to the plan.\n\n"
326
  f"{object_policies}\n\n"
327
  "## Other\n\n"
328
  f"{other_policies}\n\n"
planning_ai/main.py CHANGED
@@ -1,4 +1,3 @@
1
- import random
2
  import time
3
  from pathlib import Path
4
 
 
 
1
  import time
2
  from pathlib import Path
3