-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
1,501 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,292 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "dd40f4f4-5a80-40b7-94b3-aed136daa9d8", | ||
"metadata": {}, | ||
"source": [ | ||
"# Plot the Evolution of Service Territory Maps\n", | ||
"\n", | ||
"This notebook plots the evolution of the map of service territory for a given BA." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "27e597e9-538f-41d4-afa9-a268b10ab1df", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Start by importing the packages we need:\n", | ||
"import os\n", | ||
"\n", | ||
"import pandas as pd\n", | ||
"import matplotlib.pyplot as plt\n", | ||
"import geopandas as gpd\n", | ||
"\n", | ||
"from glob import glob\n", | ||
"from mpl_toolkits.axes_grid1 import make_axes_locatable\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "795f6fe5-0769-4298-887e-7c4cffc64a0d", | ||
"metadata": {}, | ||
"source": [ | ||
"## Set the Directory Structure" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "bd887600-32da-46dc-b411-fa63c75f564f", | ||
"metadata": { | ||
"pycharm": { | ||
"name": "#%%\n" | ||
} | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"# Identify the top-level directory and the subdirectory where the data will be stored:\n", | ||
"ba_mapping_input_dir = '/Users/burl878/Documents/Code/code_repos/tell/tell/tell_data/tell_quickstarter_data/outputs/ba_service_territory'\n", | ||
"population_input_dir = '/Users/burl878/Documents/Code/code_repos/tell/tell/tell_data/tell_raw_data/Population'\n", | ||
"county_shapefile_input_dir = '/Users/burl878/Documents/Code/code_repos/tell/tell/tell_data/tell_raw_data/County_Shapefiles'\n", | ||
"state_shapefile_input_dir = '/Users/burl878/Documents/Code/code_repos/tell/tell/tell_data/tell_raw_data/State_Shapefiles/'\n", | ||
"image_output_dir = '/Users/burl878/Documents/Code/code_repos/tell/tell/tell_data/visualizations/ba_service_territory'\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "7f055d71-411a-4b85-b0b8-5fd3f9059796", | ||
"metadata": {}, | ||
"source": [ | ||
"## Process the Data" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "4b04f656-5fab-4fcb-86db-63c64db9c2c0", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Define a function process the mapping file over a range of years:\n", | ||
"def process_ba_mapping_evolution(ba_mapping_input_dir: str, population_input_dir: str, ba_to_process: str, start_year: int, end_year: int):\n", | ||
" # Loop over the years from the start_year to the end_year and read in the mapping data:\n", | ||
" for year in range(start_year, end_year, 1):\n", | ||
" # Read in the BA-to-county mapping file for that year:\n", | ||
" ba_mapping_df = pd.read_csv((os.path.join(ba_mapping_input_dir, f'ba_service_territory_{str(year)}.csv')), index_col=None, header=0)\n", | ||
" \n", | ||
" # Subset the data to only the BA you want to plot:\n", | ||
" ba_mapping_df = ba_mapping_df.loc[(ba_mapping_df['BA_Code'] == ba_to_process)]\n", | ||
"\n", | ||
" # Read in county populations file:\n", | ||
" population_df = pd.read_csv(os.path.join(population_input_dir, r'county_populations_2000_to_2023.csv'))\n", | ||
"\n", | ||
" # Keep only the columns we need:\n", | ||
" population_df = population_df[['county_FIPS', ('pop_' + str(year))]].copy(deep=False)\n", | ||
"\n", | ||
" # Rename the columns:\n", | ||
" population_df.rename(columns={\"county_FIPS\": \"County_FIPS\", ('pop_' + str(year)): \"Population\"}, inplace=True)\n", | ||
"\n", | ||
" # Merge the ba_mapping_df and population_df together using county FIPS codes to join them:\n", | ||
" ba_mapping_df = ba_mapping_df.merge(population_df, on='County_FIPS', how='left')\n", | ||
" \n", | ||
" # Concatenate all the years into a single dataframe:\n", | ||
" if year == start_year:\n", | ||
" output_df = ba_mapping_df.copy()\n", | ||
" else:\n", | ||
" output_df = pd.concat([output_df, ba_mapping_df])\n", | ||
"\n", | ||
" return output_df\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "37a9d4be-aa9d-446d-b31e-d640e9525019", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"mapping_df = process_ba_mapping_evolution(ba_mapping_input_dir = ba_mapping_input_dir,\n", | ||
" population_input_dir = population_input_dir,\n", | ||
" ba_to_process = 'CISO',\n", | ||
" start_year = 2015,\n", | ||
" end_year = 2024)\n", | ||
"\n", | ||
"mapping_df\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0dc65f89-cd8f-4a78-9cb9-c93e4f6b91ac", | ||
"metadata": {}, | ||
"source": [ | ||
"## Make the Plot" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "25c2d2d2-dadf-45cf-b0e1-40b8856595f9", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Define a function to plot the BA-to-county maps:\n", | ||
"def plot_ba_mapping_evolution(ba_mapping_input_dir: str, population_input_dir: str, county_shapefile_input_dir: str, state_shapefile_input_dir: str,\n", | ||
" ba_to_process: str, start_year: int, end_year: int, image_output_dir: str, image_resolution: int, save_images=False):\n", | ||
"\n", | ||
" # Process the mapping file using the function defined above:\n", | ||
" mapping_df = process_ba_mapping_evolution(ba_mapping_input_dir = ba_mapping_input_dir,\n", | ||
" population_input_dir = population_input_dir,\n", | ||
" ba_to_process = ba_to_process,\n", | ||
" start_year = start_year,\n", | ||
" end_year = end_year)\n", | ||
"\n", | ||
" # Read in the county shapefile and reassign the 'FIPS' variable as integers:\n", | ||
" counties_df = gpd.read_file(os.path.join(county_shapefile_input_dir, r'tl_2020_us_county.shp')).rename(columns={'GEOID': 'County_FIPS'})\n", | ||
" counties_df['County_FIPS'] = counties_df['County_FIPS'].astype(int)\n", | ||
"\n", | ||
" # Merge the ba_mapping_df and counties_df together using county FIPS codes to join them:\n", | ||
" counties_df = counties_df.merge(mapping_df, on='County_FIPS', how='left')\n", | ||
"\n", | ||
" # Subset to only the BA you want to plot:\n", | ||
" counties_subset_df = counties_df.loc[counties_df['BA_Code'] == ba_to_process]\n", | ||
" \n", | ||
" # Read in the state shapefile:\n", | ||
" states_df = gpd.read_file(os.path.join(state_shapefile_input_dir, 'tl_2020_us_state.shp')).rename(columns={'NAME': 'State_Name'})\n", | ||
" \n", | ||
" # Subset the state shapefile to just the states contained in the maping file:\n", | ||
" state_subset_df = states_df[states_df['State_Name'].isin(mapping_df['State_Name'].unique().tolist())]\n", | ||
" \n", | ||
" # Set the colormap and colorlimit:\n", | ||
" colors = plt.get_cmap('YlGnBu', 15)\n", | ||
" pop_max = counties_subset_df['Population'].max()\n", | ||
" \n", | ||
" # Subset based on year:\n", | ||
" counties_a_df = counties_subset_df.loc[counties_subset_df['Year'] == 2016]\n", | ||
" counties_b_df = counties_subset_df.loc[counties_subset_df['Year'] == 2017]\n", | ||
" counties_c_df = counties_subset_df.loc[counties_subset_df['Year'] == 2018]\n", | ||
" counties_d_df = counties_subset_df.loc[counties_subset_df['Year'] == 2019]\n", | ||
" counties_e_df = counties_subset_df.loc[counties_subset_df['Year'] == 2020]\n", | ||
" counties_f_df = counties_subset_df.loc[counties_subset_df['Year'] == 2021]\n", | ||
" counties_g_df = counties_subset_df.loc[counties_subset_df['Year'] == 2022]\n", | ||
" counties_h_df = counties_subset_df.loc[counties_subset_df['Year'] == 2023]\n", | ||
" \n", | ||
" # Create the figure:\n", | ||
" fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(25,13))\n", | ||
" \n", | ||
" # Plot each year using subplots starting in 2016\n", | ||
" ax1 = counties_a_df.plot(ax=axes[0,0], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[0,0], linewidth=2, color='k')\n", | ||
" ax1.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax1.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax1.set_title((ba_to_process + ' Territory: 2016'), fontsize=16)\n", | ||
" ax1.set_title('a)', loc='left', fontsize=16)\n", | ||
" \n", | ||
" ax2 = counties_b_df.plot(ax=axes[0,1], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[0,1], linewidth=2, color='k')\n", | ||
" ax2.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax2.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax2.set_title((ba_to_process + ' Territory: 2017'), fontsize=16)\n", | ||
" ax2.set_title('b)', loc='left', fontsize=16) \n", | ||
"\n", | ||
" ax3 = counties_c_df.plot(ax=axes[0,2], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[0,2], linewidth=2, color='k')\n", | ||
" ax3.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax3.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax3.set_title((ba_to_process + ' Territory: 2018'), fontsize=16)\n", | ||
" ax3.set_title('c)', loc='left', fontsize=16)\n", | ||
"\n", | ||
" ax4 = counties_d_df.plot(ax=axes[0,3], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[0,3], linewidth=2, color='k')\n", | ||
" ax4.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax4.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax4.set_title((ba_to_process + ' Territory: 2019'), fontsize=16)\n", | ||
" ax4.set_title('d)', loc='left', fontsize=16)\n", | ||
"\n", | ||
" ax5 = counties_e_df.plot(ax=axes[1,0], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[1,0], linewidth=2, color='k')\n", | ||
" ax5.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax5.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax5.set_title((ba_to_process + ' Territory: 2020'), fontsize=16)\n", | ||
" ax5.set_title('e)', loc='left', fontsize=16)\n", | ||
"\n", | ||
" ax6 = counties_f_df.plot(ax=axes[1,1], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[1,1], linewidth=2, color='k')\n", | ||
" ax6.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax6.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax6.set_title((ba_to_process + ' Territory: 2021'), fontsize=16)\n", | ||
" ax6.set_title('f)', loc='left', fontsize=16)\n", | ||
"\n", | ||
" ax7 = counties_g_df.plot(ax=axes[1,2], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[1,2], linewidth=2, color='k')\n", | ||
" ax7.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax7.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax7.set_title((ba_to_process + ' Territory: 2022'), fontsize=16)\n", | ||
" ax7.set_title('g)', loc='left', fontsize=16)\n", | ||
"\n", | ||
" ax8 = counties_h_df.plot(ax=axes[1,3], column='Population', cmap=colors, vmin=0, vmax=pop_max, edgecolor='k', linewidth=1)\n", | ||
" state_subset_df.boundary.plot(ax=axes[1,3], linewidth=2, color='k')\n", | ||
" ax8.set_xlabel('Longitude', fontsize=14); \n", | ||
" ax8.set_ylabel('Latitude', fontsize=14);\n", | ||
" ax8.set_title((ba_to_process + ' Territory: 2023'), fontsize=16)\n", | ||
" ax8.set_title('h)', loc='left', fontsize=16)\n", | ||
" \n", | ||
" # If the \"save_images\" flag is set to true then save the plot to a .png file:\n", | ||
" if save_images == True:\n", | ||
" filename = ('BA_Service_Territory_Evolution_' + ba_to_process + '.png')\n", | ||
" plt.savefig(os.path.join(image_output_dir, filename), dpi=image_resolution, bbox_inches='tight', facecolor='white')\n", | ||
" " | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "c57ac364-4aeb-40e2-adf8-9ece04233c00", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"plot_ba_mapping_evolution(ba_mapping_input_dir = ba_mapping_input_dir,\n", | ||
" population_input_dir = population_input_dir,\n", | ||
" county_shapefile_input_dir = county_shapefile_input_dir,\n", | ||
" state_shapefile_input_dir = state_shapefile_input_dir,\n", | ||
" ba_to_process = 'NEVP',\n", | ||
" start_year = 2015,\n", | ||
" end_year = 2024,\n", | ||
" image_output_dir = image_output_dir,\n", | ||
" image_resolution = 300,\n", | ||
" save_images = True)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "e75d231a-c5a3-49ed-9890-ffd5fb436cef", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "tell", | ||
"language": "python", | ||
"name": "tell" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.10.8" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Oops, something went wrong.