| 124 | }) |
| 125 | |
| 126 | def create_map(df, selected_region=None): |
| 127 | region_totals = df.groupby('REGIONAL_OFFICE_NAME')['TOTAL_COST'].sum() |
| 128 | |
| 129 | map_data = [] |
| 130 | for region in region_totals.index: |
| 131 | if region in REGION_COORDINATES: |
| 132 | coords = REGION_COORDINATES[region] |
| 133 | total_cost = region_totals[region] |
| 134 | |
| 135 | map_data.append({ |
| 136 | 'Region': region, |
| 137 | 'Latitude': coords['lat'], |
| 138 | 'Longitude': coords['lon'], |
| 139 | 'Total_Cost': total_cost, |
| 140 | 'Size': (total_cost / region_totals.max() * 40 + 10) * coords['size_multiplier'], |
| 141 | 'Color': 'Selected' if region == selected_region else 'Other', |
| 142 | 'Rank': int(region_totals.rank(ascending=False)[region]) |
| 143 | }) |
| 144 | |
| 145 | map_df = pd.DataFrame(map_data) |
| 146 | |
| 147 | fig = px.scatter_mapbox( |
| 148 | map_df, |
| 149 | lat="Latitude", |
| 150 | lon="Longitude", |
| 151 | size="Size", |
| 152 | color="Color", |
| 153 | hover_name="Region", |
| 154 | hover_data={ |
| 155 | 'Latitude': False, |
| 156 | 'Longitude': False, |
| 157 | 'Size': False, |
| 158 | 'Color': False, |
| 159 | 'Total_Cost': ':,.0f', |
| 160 | 'Rank': True |
| 161 | }, |
| 162 | color_discrete_map={'Selected': '#FF6B6B', 'Other': '#4ECDC4'}, |
| 163 | size_max=35, |
| 164 | zoom=5.5, |
| 165 | center={"lat": 54.0, "lon": -2.0}, |
| 166 | mapbox_style="open-street-map", |
| 167 | title="NHS Regional Prescription Costs" |
| 168 | ) |
| 169 | |
| 170 | fig.update_layout( |
| 171 | height=500, |
| 172 | margin={"r":0,"t":50,"l":0,"b":0}, |
| 173 | showlegend=True, |
| 174 | legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) |
| 175 | ) |
| 176 | |
| 177 | return fig |
| 178 | |
| 179 | def gen_pred_errors(df): |
| 180 | np.random.seed(42) |