gov-uk-dashboards 13.5.0__tar.gz → 13.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {gov_uk_dashboards-13.5.0/gov_uk_dashboards.egg-info → gov_uk_dashboards-13.5.2}/PKG-INFO +1 -1
  2. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/choropleth_map.py +125 -95
  3. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/stacked_barchart.py +1 -1
  4. gov_uk_dashboards-13.5.2/gov_uk_dashboards/constants.py +12 -0
  5. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/plotting_helper_functions.py +1 -1
  6. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2/gov_uk_dashboards.egg-info}/PKG-INFO +1 -1
  7. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards.egg-info/SOURCES.txt +1 -0
  8. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/setup.py +1 -1
  9. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/LICENSE +0 -0
  10. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/MANIFEST.in +0 -0
  11. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/README.md +0 -0
  12. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/__init__.py +0 -0
  13. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/__init__.py +0 -0
  14. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/attach-event-to-dash.js +0 -0
  15. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/dashboard.css +0 -0
  16. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/fonts/bold-affa96571d-v2.woff +0 -0
  17. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/fonts/bold-b542beb274-v2.woff2 +0 -0
  18. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/fonts/light-94a07e06a1-v2.woff2 +0 -0
  19. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/fonts/light-f591b13f7d-v2.woff +0 -0
  20. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/get_assets_folder.py +0 -0
  21. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/govuk-frontend-3.14.0.min.js +0 -0
  22. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/DLUHC_WHITE_Master_AW_sm.png +0 -0
  23. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/MHCLG-favicon.png +0 -0
  24. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/MHCLG_favicon.png +0 -0
  25. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/dcms_coatofarms.png +0 -0
  26. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/dluhc_favicon.ico +0 -0
  27. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/gov_favicon.ico +0 -0
  28. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/govuk-crest.svg +0 -0
  29. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/hm-government-logo.png +0 -0
  30. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/mhclg_coat_of_arms.png +0 -0
  31. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/mhclg_white_no_background.png +0 -0
  32. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/MedianAbsolute.png +0 -0
  33. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/how_to_1_selecting_data.png +0 -0
  34. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/how_to_2_viewing_tabs.png +0 -0
  35. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/how_to_3_viewing_charts.png +0 -0
  36. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/how_to_4_viewing_trends.png +0 -0
  37. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/images/oflog/how_to_5_viewing_tables.png +0 -0
  38. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/mobile-nav.js +0 -0
  39. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/topojson/usa_110m.json +0 -0
  40. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/assets/topojson/world_110m.json +0 -0
  41. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/axes.py +0 -0
  42. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/colours.py +0 -0
  43. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/__init__.py +0 -0
  44. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/create_download_chart_button.py +0 -0
  45. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/create_download_data_button.py +0 -0
  46. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/display_chart_or_table_with_header.py +0 -0
  47. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/__init__.py +0 -0
  48. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/apply_and_reset_filters_buttons.py +0 -0
  49. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/banners.py +0 -0
  50. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/captioned_figure.py +0 -0
  51. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/card.py +0 -0
  52. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/card_full_width.py +0 -0
  53. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/collapsible_panel.py +0 -0
  54. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/comparison_la_filter_button.py +0 -0
  55. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/context_banner.py +0 -0
  56. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/dashboard_container.py +0 -0
  57. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/details.py +0 -0
  58. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/download_button.py +0 -0
  59. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/filter_panel.py +0 -0
  60. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/footer.py +0 -0
  61. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/generate_dash_graph_from_figure.py +0 -0
  62. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/graph.py +0 -0
  63. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/header.py +0 -0
  64. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/heading.py +0 -0
  65. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/html_list.py +0 -0
  66. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/key_value_pair.py +0 -0
  67. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/main_content.py +0 -0
  68. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/navbar.py +0 -0
  69. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/no_data_message.py +0 -0
  70. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/notification_banner.py +0 -0
  71. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/paragraph.py +0 -0
  72. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/phase_banner.py +0 -0
  73. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/row_component.py +0 -0
  74. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/side_navbar.py +0 -0
  75. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/table.py +0 -0
  76. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/tooltip.py +0 -0
  77. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/tooltip_title.py +0 -0
  78. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/visualisation_commentary.py +0 -0
  79. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/visualisation_title.py +0 -0
  80. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/components/plotly/warning_text.py +0 -0
  81. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/__init__.py +0 -0
  82. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/chart_data.py +0 -0
  83. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/enums/__init__.py +0 -0
  84. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/enums/dash_patterns.py +0 -0
  85. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/line_chart.py +0 -0
  86. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/styles/__init__.py +0 -0
  87. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/figures/styles/line_style.py +0 -0
  88. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/formatting/__init__.py +0 -0
  89. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/formatting/human_readable.py +0 -0
  90. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/formatting/round_and_add_prefix_and_suffix.py +0 -0
  91. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/formatting/rounding.py +0 -0
  92. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/__init__.py +0 -0
  93. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/dap/__init__.py +0 -0
  94. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/dap/dap_deployment.py +0 -0
  95. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/dap/get_dataframe_from_cds.py +0 -0
  96. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/enable_basic_auth.py +0 -0
  97. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/http_headers.py +0 -0
  98. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/logging.py +0 -0
  99. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/lib/update_layout_bgcolor_margin.py +0 -0
  100. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/symbols.py +0 -0
  101. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/template.html +0 -0
  102. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards/template.py +0 -0
  103. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards.egg-info/dependency_links.txt +0 -0
  104. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards.egg-info/requires.txt +0 -0
  105. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/gov_uk_dashboards.egg-info/top_level.txt +0 -0
  106. {gov_uk_dashboards-13.5.0 → gov_uk_dashboards-13.5.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gov_uk_dashboards
3
- Version: 13.5.0
3
+ Version: 13.5.2
4
4
  Summary: Provides access to functionality common to creating a data dashboard.
5
5
  Author: Department for Levelling Up, Housing and Communities
6
6
  Description-Content-Type: text/markdown
@@ -3,6 +3,9 @@
3
3
  import polars as pl
4
4
  import plotly.graph_objects as go
5
5
  from dash import dcc
6
+
7
+ from gov_uk_dashboards.constants import DEFAULT_COLOURSCALE
8
+
6
9
  from gov_uk_dashboards import colours
7
10
  from gov_uk_dashboards.components.display_chart_or_table_with_header import (
8
11
  display_chart_or_table_with_header,
@@ -11,8 +14,10 @@ from gov_uk_dashboards.components.display_chart_or_table_with_header import (
11
14
 
12
15
  class ChoroplethMap:
13
16
  """Class for generating choropleth map charts.
14
- Note: dataframe_function must contain columns: 'Region', 'Area_Code', 'Local authority',
15
- category_column, column_to_plot, custom_data"""
17
+ Note: dataframe_function must contain columns: 'Region', 'Area_Code',
18
+ discrete_category_column, column_to_plot, hover_data_list
19
+ If discrete_category_column & discrete_category_order are None,
20
+ the choropleth map will be a continuos one, otherwise discrete"""
16
21
 
17
22
  # pylint: disable=too-many-instance-attributes
18
23
  # pylint: disable=too-many-arguments
@@ -20,34 +25,42 @@ class ChoroplethMap:
20
25
  # pylint: disable=too-few-public-methods
21
26
  def __init__(
22
27
  self,
23
- dataframe_function,
24
- region,
25
- get_geos_function,
26
- category_column,
27
- column_to_plot,
28
- desired_category_order,
29
- custom_data,
30
- hover_header_list,
31
- download_data_button_id,
32
- legend_title_text=None,
28
+ map_name: str, # used for the id in the choropleth map and the data download button
29
+ get_dataframe: callable,
30
+ get_geos: callable,
31
+ region: str,
32
+ area_focus_level: str,
33
+ column_to_plot: str,
34
+ hover_header_list: list[str],
35
+ hover_data_list: list[str],
36
+ discrete_category_column: str = None,
37
+ discrete_category_order: list[str] = None,
38
+ legend_title_text: str = None,
33
39
  **choropleth_properties,
34
40
  ):
35
- self.dataframe = dataframe_function()
41
+ self.map_name = map_name
42
+ self.dataframe = get_dataframe()
43
+ self.geographic_boundaries = get_geos()
36
44
  self.region = region
37
- self.geographic_boundaries = get_geos_function()
38
- self.boundaries_by_area = self._get_boundaries_by_area(self.dataframe)
39
- self.category_column = category_column
45
+ self.area_focus_level = area_focus_level
40
46
  self.column_to_plot = column_to_plot
41
- self.df_dict = self._get_dataframe_dict_by_category()
42
- self.desired_category_order = desired_category_order
43
- self.colours_list = self._get_colour_list()
44
- self.custom_data = custom_data
45
47
  self.hover_header_list = hover_header_list
46
- self.download_data_button_id = download_data_button_id
48
+ self.hover_data_list = hover_data_list
49
+
50
+ self.discrete_category_column = discrete_category_column
47
51
  self.legend_title_text = legend_title_text
48
- self.fig = go.Figure()
52
+ self.discrete_category_order = discrete_category_order
49
53
  self.choropleth_properties = choropleth_properties
50
54
 
55
+ self.fig = go.Figure()
56
+ self.discrete_map = (
57
+ self.discrete_category_column is not None
58
+ and self.discrete_category_order is not None
59
+ )
60
+ if self.discrete_map:
61
+ self.df_dict = self._get_dataframe_dict_by_category()
62
+ self.colours_list = self._get_colour_list()
63
+
51
64
  def get_choropleth_map(self):
52
65
  """Creates and returns choropleth map chart for display on application.
53
66
 
@@ -56,7 +69,7 @@ class ChoroplethMap:
56
69
  """
57
70
  self._update_fig()
58
71
  choropleth_map = dcc.Graph(
59
- id="local-authority-choropleth",
72
+ id=f"{self.map_name}-choropleth",
60
73
  responsive=True,
61
74
  config={"topojsonURL": "/assets/topojson/", "displayModeBar": False},
62
75
  figure=self.fig,
@@ -66,7 +79,7 @@ class ChoroplethMap:
66
79
  }, # height hard-coded so that map always displays within tab
67
80
  )
68
81
  return display_chart_or_table_with_header(
69
- choropleth_map, download_data_button_id=self.download_data_button_id
82
+ choropleth_map, download_data_button_id=self.map_name
70
83
  )
71
84
 
72
85
  def _update_fig(self):
@@ -75,61 +88,10 @@ class ChoroplethMap:
75
88
  self._crop_to_region()
76
89
  self._remove_background_map()
77
90
 
78
- def _get_dataframe_dict_by_category(self):
79
- if self.region is not None and self.region != "England":
80
- self.dataframe = self.dataframe.filter(pl.col("Region") == self.region)
81
- else:
82
- self.dataframe = self.dataframe
83
- grouped_dfs_dict_keys_as_tuples = self.dataframe.partition_by(
84
- self.category_column, as_dict=True
85
- )
86
- grouped_dfs_dict = {
87
- key[0]: value for key, value in grouped_dfs_dict_keys_as_tuples.items()
88
- }
89
- return grouped_dfs_dict
90
-
91
- def _get_boundaries_by_area(self, dataframe):
92
- las_to_display = dataframe["Area_Code"].to_list()
93
- filtered_boundaries = {
94
- key: (
95
- value
96
- if key != "features"
97
- else [
98
- features
99
- for features in value
100
- if features["properties"]["geo_id"] in las_to_display
101
- ]
102
- )
103
- for key, value in self.geographic_boundaries.items()
104
- }
105
- return filtered_boundaries
106
-
107
- def _add_traces(self):
108
- for count, category in enumerate(self.desired_category_order):
109
- if category not in self.df_dict:
110
- df = self._create_df_for_empty_trace(category)
111
- else:
112
- df = self.df_dict[category]
113
- colour = self.colours_list[count % len(self.colours_list)]
114
- self.fig.add_trace(
115
- self._create_choropleth_trace(
116
- df,
117
- colour,
118
- )
119
- )
120
-
121
- def _create_df_for_empty_trace(self, category):
122
- """Method to create df where all columns are empty except for the category column to force
123
- all legend items to always appear"""
124
- columns = next(iter(self.df_dict.values())).columns
125
- data = {col: [None] for col in columns}
126
- data[self.category_column] = [category]
127
- return pl.DataFrame(data)
128
-
129
91
  def _create_choropleth_trace(
130
92
  self,
131
93
  dataframe,
132
- colour,
94
+ colourscale,
133
95
  column_to_plot=None,
134
96
  is_missing_data=False,
135
97
  marker=None,
@@ -151,6 +113,7 @@ class ChoroplethMap:
151
113
  hovertemplate = (
152
114
  "<b>%{customdata[0]}</b><br>" + "%{hovertext}<extra></extra>"
153
115
  )
116
+
154
117
  return go.Choropleth(
155
118
  geojson=self.geographic_boundaries,
156
119
  featureidkey="properties.geo_id",
@@ -158,48 +121,79 @@ class ChoroplethMap:
158
121
  locationmode="geojson-id",
159
122
  z=dataframe[column_to_plot],
160
123
  hovertext=(
161
- dataframe["Local authority"]
124
+ dataframe[self.area_focus_level]
162
125
  if not is_missing_data
163
- else ["No data available"] * len(dataframe["Local authority"])
126
+ else ["No data available"] * len(dataframe[self.area_focus_level])
164
127
  ),
165
128
  customdata=(
166
- dataframe[self.custom_data]
129
+ dataframe[self.hover_data_list]
167
130
  if not is_missing_data
168
- else dataframe[["Local authority"]]
131
+ else dataframe[[self.area_focus_level]]
169
132
  ),
133
+ colorbar=self._get_color_bar(),
170
134
  hovertemplate=hovertemplate,
171
135
  marker=marker,
172
136
  marker_line_color=colours.GovUKColours.DARK_GREY.value,
173
- showscale=False,
174
- showlegend=True,
175
- colorscale=[
176
- [0, colour],
177
- [1, colour],
178
- ], # dataframe is grouped by column_to_plot, hence only
179
- # contains one value for column_to_plot- this ensures a discrete categorical colourscale
180
- # for trace
181
- name=(
182
- dataframe[self.category_column][0]
183
- if not is_missing_data
184
- else "No data available"
185
- ),
137
+ showscale=self._get_scale(),
138
+ showlegend=self._get_legend(),
139
+ colorscale=colourscale,
140
+ name=self._get_trace_name(dataframe, is_missing_data),
186
141
  **self.choropleth_properties,
187
142
  )
188
143
 
144
+ def _add_traces(self):
145
+ if not self.discrete_map:
146
+ self.fig.add_trace(
147
+ self._create_choropleth_trace(self.dataframe, DEFAULT_COLOURSCALE)
148
+ )
149
+ else:
150
+ for count, category in enumerate(self.discrete_category_order):
151
+ if category not in self.df_dict:
152
+ df = self._create_df_for_empty_trace(category)
153
+ else:
154
+ df = self.df_dict[category]
155
+ colour = [
156
+ [0, self.colours_list[count % len(self.colours_list)]],
157
+ [1, self.colours_list[count % len(self.colours_list)]],
158
+ ]
159
+ self.fig.add_trace(
160
+ self._create_choropleth_trace(
161
+ df,
162
+ colour,
163
+ )
164
+ )
165
+
189
166
  def _handle_missing_data(self):
190
167
  missing_data = self.dataframe.filter(pl.col(self.column_to_plot).is_null())
191
168
  missing_data = missing_data.with_columns(pl.lit(0).alias("data"))
192
169
 
170
+ colour = [
171
+ [0, colours.GovUKColours.MID_GREY.value],
172
+ [1, colours.GovUKColours.MID_GREY.value],
173
+ ]
193
174
  if not missing_data.is_empty():
194
175
  self.fig.add_trace(
195
176
  self._create_choropleth_trace(
196
177
  missing_data,
197
- colours.GovUKColours.MID_GREY.value,
178
+ colour,
198
179
  column_to_plot="data",
199
180
  is_missing_data=True,
200
181
  )
201
182
  )
202
183
 
184
+ def _get_dataframe_dict_by_category(self):
185
+ if self.region is not None and self.region != "England":
186
+ self.dataframe = self.dataframe.filter(pl.col("Region") == self.region)
187
+ else:
188
+ self.dataframe = self.dataframe
189
+ grouped_dfs_dict_keys_as_tuples = self.dataframe.partition_by(
190
+ self.discrete_category_column, as_dict=True
191
+ )
192
+ grouped_dfs_dict = {
193
+ key[0]: value for key, value in grouped_dfs_dict_keys_as_tuples.items()
194
+ }
195
+ return grouped_dfs_dict
196
+
203
197
  def _crop_to_region(self):
204
198
  self.fig.update_layout(
205
199
  {
@@ -216,6 +210,33 @@ class ChoroplethMap:
216
210
  },
217
211
  )
218
212
 
213
+ def _get_color_bar(self):
214
+ if self.discrete_map:
215
+ return None
216
+
217
+ return {
218
+ "title": self.column_to_plot,
219
+ "thickness": 20,
220
+ "len": 0.8,
221
+ "x": 0.9,
222
+ "y": 0.5,
223
+ }
224
+
225
+ def _get_scale(self):
226
+ return not self.discrete_map
227
+
228
+ def _get_legend(self):
229
+ return self.discrete_map
230
+
231
+ def _get_trace_name(self, dataframe, missing_data=False):
232
+ if self.discrete_category_column is None:
233
+ return None
234
+
235
+ if not missing_data:
236
+ return dataframe[self.discrete_category_column][0]
237
+
238
+ return "No data available"
239
+
219
240
  def _remove_background_map(self):
220
241
  self.fig.update_geos(
221
242
  center={"lat": 53, "lon": -2},
@@ -226,6 +247,15 @@ class ChoroplethMap:
226
247
  def _get_colour_list(self):
227
248
  """Amends colour list based on the number of categories"""
228
249
  colour_list = ["#217847", "#23BBBE", "#8CCE69", "#FFEA80"]
229
- if len(self.desired_category_order) == 3:
250
+
251
+ if self.discrete_map and len(self.discrete_category_order) == 3:
230
252
  colour_list.pop(1)
231
253
  return colour_list
254
+
255
+ def _create_df_for_empty_trace(self, category):
256
+ """Method to create df where all columns are empty except for the category column to force
257
+ all legend items to always appear"""
258
+ columns = next(iter(self.df_dict.values())).columns
259
+ data = {col: [None] for col in columns}
260
+ data[self.discrete_category_column] = [category]
261
+ return pl.DataFrame(data)
@@ -8,7 +8,7 @@ import polars as pl
8
8
 
9
9
  import plotly.graph_objects as go
10
10
 
11
- from constants import (
11
+ from gov_uk_dashboards.constants import (
12
12
  CHART_LABEL_FONT_SIZE,
13
13
  CUSTOM_DATA,
14
14
  DATE_VALID,
@@ -0,0 +1,12 @@
1
+ """Constants that are common across the dashboard."""
2
+
3
+ CUSTOM_DATA = "custom_data"
4
+ HOVER_TEXT_HEADERS = "hover_text_headers"
5
+ DATE_VALID = "Date valid"
6
+ CHART_LABEL_FONT_SIZE = 19
7
+ FINANCIAL_YEAR_ENDING = "Financial year ending"
8
+ VALUE = "Value"
9
+ MAIN_TITLE = "main_title"
10
+ SUBTITLE = "subtitle"
11
+ MEASURE = "measure"
12
+ DEFAULT_COLOURSCALE = "tealgrn"
@@ -1,7 +1,7 @@
1
1
  """Helper functions for use to plot charts"""
2
2
 
3
3
 
4
- from constants import (
4
+ from gov_uk_dashboards.constants import (
5
5
  CHART_LABEL_FONT_SIZE,
6
6
  )
7
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gov_uk_dashboards
3
- Version: 13.5.0
3
+ Version: 13.5.2
4
4
  Summary: Provides access to functionality common to creating a data dashboard.
5
5
  Author: Department for Levelling Up, Housing and Communities
6
6
  Description-Content-Type: text/markdown
@@ -5,6 +5,7 @@ setup.py
5
5
  gov_uk_dashboards/__init__.py
6
6
  gov_uk_dashboards/axes.py
7
7
  gov_uk_dashboards/colours.py
8
+ gov_uk_dashboards/constants.py
8
9
  gov_uk_dashboards/symbols.py
9
10
  gov_uk_dashboards/template.html
10
11
  gov_uk_dashboards/template.py
@@ -10,7 +10,7 @@ setup(
10
10
  author="Department for Levelling Up, Housing and Communities",
11
11
  description="Provides access to functionality common to creating a data dashboard.",
12
12
  name="gov_uk_dashboards",
13
- version="13.5.0",
13
+ version="13.5.2",
14
14
  long_description=long_description,
15
15
  long_description_content_type="text/markdown",
16
16
  packages=find_packages(),