From dedffde5d01b6bdad105e7e3738f5801120caf26 Mon Sep 17 00:00:00 2001 From: erexer <13180883+erexer@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:08:46 -0800 Subject: [PATCH] add llm --- .github/workflows/test.yml | 11 +- format_file.py | 43 +++ requirements.txt | 2 + scripts/ba_peakiness_analysis.ipynb | 443 ++++++++++++++++++++++++++++ 4 files changed, 496 insertions(+), 3 deletions(-) create mode 100644 format_file.py create mode 100644 requirements.txt create mode 100644 scripts/ba_peakiness_analysis.ipynb diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7895338..a4220c3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,8 +14,13 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' + + - name: Install Dependencies + run: pip install -r requirements.txt - name: Run Python Code - run: | - echo 'print("It works!")' > script.py - python script.py + env: + AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} + AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }} + run: python format_file.py + diff --git a/format_file.py b/format_file.py new file mode 100644 index 0000000..002c8ef --- /dev/null +++ b/format_file.py @@ -0,0 +1,43 @@ +import os + +from langchain_openai import AzureChatOpenAI +from langchain_core.prompts import ChatPromptTemplate + + +try: + # This code will raise a NameError because 'my_variable' is not defined + os.environ["AZURE_OPENAI_API_KEY"] +except Error as e: + # This block will execute if an Error occurs + print(f"No AZURE_OPENAI_API_KEY environment variable was found: {e}") + +llm = AzureChatOpenAI( + azure_deployment="gpt-4o", + api_version="2024-02-01", + temperature=0.7, + max_tokens=250, + timeout=None, + max_retries=2, + # other params... +) + +prompt = ChatPromptTemplate.from_messages( + [ + ( + "system", + "You are a friendly {language} expert performing a code review to provide helpful feedback to the programmer.", + ), + ("human", "{input}"), + ] +) + +chain = prompt | llm +chain.invoke( + { + "language": "Python", + "input": "Go through all the scripts in this repository and provide detailed feedback and suggestions on how to make the scripts easier to read, cleaner, and more reproducible.", + } +) + +print(chain) +print(chain.content) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..427186e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +langchain_openai==0.3.0 +langchain_core==0.3.29 \ No newline at end of file diff --git a/scripts/ba_peakiness_analysis.ipynb b/scripts/ba_peakiness_analysis.ipynb new file mode 100644 index 0000000..ee98144 --- /dev/null +++ b/scripts/ba_peakiness_analysis.ipynb @@ -0,0 +1,443 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "dd40f4f4-5a80-40b7-94b3-aed136daa9d8", + "metadata": {}, + "source": [ + "# Analysis of Load Peakiness by Balancing Authority\n", + "\n", + "This notebook analyzes changes in the peak end of the load divergence curve by Balancing Authority." + ] + }, + { + "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 numpy as np\n", + "\n", + "from glob import glob\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", + "data_input_dir = '/Users/burl878/Documents/IMMM/Data/TELL/Production_Runs_V2/tell_data/outputs/tell_output/'\n", + "data_output_dir = '/Users/burl878/Documents/Code/code_repos/burleyson-etal_2024_applied_energy/data/peakiness/'\n", + "image_output_dir = '/Users/burl878/Documents/Code/code_repos/burleyson-etal_2024_applied_energy/figures/'\n" + ] + }, + { + "cell_type": "markdown", + "id": "7f055d71-411a-4b85-b0b8-5fd3f9059796", + "metadata": {}, + "source": [ + "## Process the Annual Mean Load Difference" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4b04f656-5fab-4fcb-86db-63c64db9c2c0", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to calculate the annual load duration curve:\n", + "def process_ba_peakiness(data_input_dir: str, data_output_dir: str, threshold: int):\n", + " # Initiate a counter to store the results:\n", + " counter = 0;\n", + " output_df = pd.DataFrame()\n", + " \n", + " # Set the scenarios to process:\n", + " scenarios = ['historic', 'rcp45cooler_ssp3', 'rcp45cooler_ssp5', 'rcp45hotter_ssp3', 'rcp45hotter_ssp5', 'rcp85cooler_ssp3', 'rcp85cooler_ssp5', 'rcp85hotter_ssp3', 'rcp85hotter_ssp5']\n", + "\n", + " # Loop over the scenarios and process each time series:\n", + " for s in range(len(scenarios)):\n", + " if scenarios[s] == 'historic':\n", + " start_year = 1980; end_year = 2020; interval = 1;\n", + " else:\n", + " start_year = 2020; end_year = 2100; interval = 5;\n", + " \n", + " # Loop over the years from the start_year to the end_year:\n", + " for year in range(start_year, end_year, interval):\n", + " # Read in the TELL BA output file for that year and scenario:\n", + " tell_df = pd.read_csv(data_input_dir + scenarios[s] + '/' + str(year) + '/TELL_Balancing_Authority_Hourly_Load_Data_' + str(year) + '_Scaled_' + str(year) + '.csv')\n", + " \n", + " # Make a list of all of the BAs:\n", + " bas = tell_df['BA_Code'].unique()\n", + " \n", + " # Loop over the BAs and calculate peak load statistics for each year and BA combination:\n", + " for i in range(len(bas)):\n", + " # Subset to just the data for the BA being processed:\n", + " subset_df = tell_df[tell_df['BA_Code'].isin([bas[i]])].copy()\n", + " \n", + " # Calculate the load normalized by the annual maximum value:\n", + " subset_df['Load_Normalized'] = (subset_df['Scaled_TELL_BA_Load_MWh'] / subset_df['Scaled_TELL_BA_Load_MWh'].max())\n", + " \n", + " # Iterate the counter by one:\n", + " counter = counter + 1\n", + " \n", + " # Put the output in a new dataframe:\n", + " output_df.loc[counter, 'Year'] = str(year)\n", + " output_df.loc[counter, 'BA'] = bas[i]\n", + " output_df.loc[counter, 'Scenario'] = scenarios[s]\n", + " output_df.loc[counter, 'Threshold'] = threshold\n", + " output_df.loc[counter, 'Peak_Load'] = subset_df['Scaled_TELL_BA_Load_MWh'].max()\n", + " output_df.loc[counter, 'Hours_Above_Threshold'] = len(subset_df[subset_df['Load_Normalized'] >= threshold])\n", + " output_df.loc[counter, 'Percent_Above_Threshold'] = 100*(len(subset_df[subset_df['Load_Normalized'] >= threshold]) / len(subset_df))\n", + "\n", + " # Clean up and move to the next step in the loop:\n", + " del subset_df\n", + " \n", + " # Generate the .csv output file name:\n", + " csv_output_filename = os.path.join(data_output_dir, 'BA_Peakiness_' + str(threshold) + '_Threshold.csv')\n", + " \n", + " # Write out the dataframe to a .csv file:\n", + " output_df.to_csv(csv_output_filename, sep=',', index=False)\n", + " \n", + " return output_df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aeab7320-44c8-4afd-b81e-2865afc12ec3", + "metadata": {}, + "outputs": [], + "source": [ + "# Process the BA peakiness dataframe:\n", + "output_df = process_ba_peakiness(data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = 0.9)\n", + "\n", + "output_df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87193b6d-cc06-4faa-8046-ddd5cef605a9", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to calculate the change in peakiness:\n", + "def process_ba_peakiness_deltas(data_input_dir: str, data_output_dir: str, threshold: int):\n", + " # Initiate a counter to store the results:\n", + " counter = 0;\n", + " output_df = pd.DataFrame()\n", + " \n", + " # Check to see if the processed output file exist and if not then create it:\n", + " if os.path.isfile(os.path.join(data_output_dir, 'BA_Peakiness_' + str(threshold) + '_Threshold.csv')) == False:\n", + " # Process the BA peakiness dataframe:\n", + " peak_df = process_ba_peakiness(data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = 0.9) \n", + " else:\n", + " # Read in the output file:\n", + " peak_df = pd.read_csv(os.path.join(data_output_dir, 'BA_Peakiness_' + str(threshold) + '_Threshold.csv'))\n", + " \n", + " # Make a list of all of the BAs:\n", + " bas = peak_df['BA'].unique()\n", + " \n", + " # Loop over the BAs and calculate peak load statistics for each year and BA combination:\n", + " for i in range(len(bas)):\n", + " #for i in range(1):\n", + " # Subset to just the data for the BA being processed:\n", + " subset_df = peak_df[peak_df['BA'].isin([bas[i]])].copy()\n", + " \n", + " # Set the scenarios to process:\n", + " scenarios = ['rcp45cooler_ssp3', 'rcp45cooler_ssp5', 'rcp45hotter_ssp3', 'rcp45hotter_ssp5', 'rcp85cooler_ssp3', 'rcp85cooler_ssp5', 'rcp85hotter_ssp3', 'rcp85hotter_ssp5']\n", + " \n", + " # Loop over the scenarios and process each time series:\n", + " for s in range(len(scenarios)):\n", + " \n", + " # Loop over the years from the start_year to the end_year:\n", + " for year in range(2020, 2100, 5):\n", + " \n", + " # Set the time change value:\n", + " if year < 2060:\n", + " year_delta = -40\n", + " else:\n", + " year_delta = -80\n", + " \n", + " # Iterate the counter by one:\n", + " counter = counter + 1\n", + " \n", + " # Put the output in a new dataframe:\n", + " output_df.loc[counter, 'Year'] = year\n", + " output_df.loc[counter, 'BA'] = bas[i]\n", + " output_df.loc[counter, 'Scenario'] = scenarios[s]\n", + " output_df.loc[counter, 'Threshold'] = threshold\n", + " output_df.loc[counter, 'Future_Value'] = subset_df['Hours_Above_Threshold'].loc[(subset_df['Year'] == year) & (subset_df['Scenario'] == scenarios[s])].values\n", + " output_df.loc[counter, 'Historical_Value'] = subset_df['Hours_Above_Threshold'].loc[(subset_df['Year'] == (year + year_delta)) & (subset_df['Scenario'] == 'historic')].values\n", + " output_df.loc[counter, 'Delta'] = output_df.loc[counter,'Future_Value'] - output_df.loc[counter,'Historical_Value']\n", + " \n", + " del subset_df, scenarios, s, year\n", + " \n", + " # Break the data down into the two era:\n", + " era_one = output_df.loc[(output_df['Year'] <= 2059)].copy()\n", + " era_two = output_df.loc[(output_df['Year'] >= 2060)].copy()\n", + " \n", + " # Sum the county loads as a function of time:\n", + " era_one['Era_One_Delta_Value'] = era_one.groupby(['BA','Scenario'])['Delta'].transform('mean')\n", + " era_two['Era_Two_Delta_Value'] = era_two.groupby(['BA','Scenario'])['Delta'].transform('mean')\n", + " \n", + " # Merge the two stats dataframes together and output the combined data:\n", + " stats_one_df = era_one[['BA', 'Scenario', 'Era_One_Delta_Value']].drop_duplicates()\n", + " stats_two_df = era_two[['BA', 'Scenario', 'Era_Two_Delta_Value']].drop_duplicates()\n", + " \n", + " stats_df = stats_one_df.merge(stats_two_df, on=['BA', 'Scenario'])\n", + " \n", + " # Generate the .csv output file name:\n", + " csv_output_filename = os.path.join(data_output_dir, 'BA_Peakiness_Statistics_' + str(threshold) + '_Threshold.csv')\n", + " \n", + " # Write out the dataframe to a .csv file:\n", + " stats_df.to_csv(csv_output_filename, sep=',', index=False)\n", + " \n", + " return stats_df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "be1e437f-6eb5-4134-b85b-2ce20ff1539d", + "metadata": {}, + "outputs": [], + "source": [ + "# Process the change in peakiness:\n", + "stats_df = process_ba_peakiness_deltas(data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = 0.9)\n", + "\n", + "stats_df\n" + ] + }, + { + "cell_type": "markdown", + "id": "0dc65f89-cd8f-4a78-9cb9-c93e4f6b91ac", + "metadata": {}, + "source": [ + "## Make the Plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14c1da15-a45c-4f31-b8b4-85e7428bee64", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to plot the time series of annual demand for each BA:\n", + "def plot_ba_peakiness(ba_to_plot: str, data_input_dir: str, data_output_dir: str, threshold: int, image_output_dir: str, image_resolution: int, save_images=False):\n", + " \n", + " # Check to see if the processed output file exist and if not then create it:\n", + " if os.path.isfile(os.path.join(data_output_dir, 'BA_Peakiness_' + str(threshold) + '_Threshold.csv')) == False:\n", + " # Process the BA peakiness dataframe:\n", + " output_df = process_ba_peakiness(data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = threshold) \n", + " else:\n", + " # Read in the output file:\n", + " output_df = pd.read_csv(os.path.join(data_output_dir, 'BA_Peakiness_' + str(threshold) + '_Threshold.csv')) \n", + " \n", + " # Subset to just the BA you want to plot:\n", + " ba_df = output_df[output_df['BA'] == ba_to_plot]\n", + " \n", + " # Subset to the time series for each scenario:\n", + " ba_historic = ba_df[ba_df['Scenario'].isin(['historic'])]\n", + " ba_rcp45cooler_ssp3 = ba_df[ba_df['Scenario'].isin(['rcp45cooler_ssp3'])]\n", + " ba_rcp45cooler_ssp5 = ba_df[ba_df['Scenario'].isin(['rcp45cooler_ssp5'])]\n", + " ba_rcp45hotter_ssp3 = ba_df[ba_df['Scenario'].isin(['rcp45hotter_ssp3'])]\n", + " ba_rcp45hotter_ssp5 = ba_df[ba_df['Scenario'].isin(['rcp45hotter_ssp5'])]\n", + " ba_rcp85cooler_ssp3 = ba_df[ba_df['Scenario'].isin(['rcp85cooler_ssp3'])]\n", + " ba_rcp85cooler_ssp5 = ba_df[ba_df['Scenario'].isin(['rcp85cooler_ssp5'])]\n", + " ba_rcp85hotter_ssp3 = ba_df[ba_df['Scenario'].isin(['rcp85hotter_ssp3'])]\n", + " ba_rcp85hotter_ssp5 = ba_df[ba_df['Scenario'].isin(['rcp85hotter_ssp5'])]\n", + " \n", + " # Subset to just the 5-year intervals:\n", + " ba_historic = ba_historic[ba_historic['Year'].isin({1980, 1985, 1990, 1995, 2000, 2005, 2010, 2015})]\n", + " historical_max = ba_historic['Hours_Above_Threshold'].max()\n", + " historical_min = ba_historic['Hours_Above_Threshold'].min()\n", + " \n", + " # Make the raw load plots:\n", + " plt.figure(figsize=(24, 12))\n", + " plt.rcParams['font.size'] = 16\n", + " \n", + " plt.plot(ba_historic['Year'], ba_historic['Hours_Above_Threshold'], color='black', linestyle='-', label='historic', linewidth=2)\n", + " plt.plot(ba_rcp45cooler_ssp3['Year'], ba_rcp45cooler_ssp3['Hours_Above_Threshold'], color='blue', linestyle=':', label='rcp45cooler_ssp3', linewidth=2)\n", + " plt.plot(ba_rcp45cooler_ssp5['Year'], ba_rcp45cooler_ssp5['Hours_Above_Threshold'], color='blue', linestyle='-', label='rcp45cooler_ssp5', linewidth=2)\n", + " plt.plot(ba_rcp45hotter_ssp3['Year'], ba_rcp45hotter_ssp3['Hours_Above_Threshold'], color='cyan', linestyle=':', label='rcp45hotter_ssp3', linewidth=2)\n", + " plt.plot(ba_rcp45hotter_ssp5['Year'], ba_rcp45hotter_ssp5['Hours_Above_Threshold'], color='cyan', linestyle='-', label='rcp45hotter_ssp5', linewidth=2)\n", + " plt.plot(ba_rcp85cooler_ssp3['Year'], ba_rcp85cooler_ssp3['Hours_Above_Threshold'], color='orange', linestyle=':', label='rcp85cooler_ssp3', linewidth=2)\n", + " plt.plot(ba_rcp85cooler_ssp5['Year'], ba_rcp85cooler_ssp5['Hours_Above_Threshold'], color='orange', linestyle='-', label='rcp85cooler_ssp5', linewidth=2)\n", + " plt.plot(ba_rcp85hotter_ssp3['Year'], ba_rcp85hotter_ssp3['Hours_Above_Threshold'], color='red', linestyle=':', label='rcp85hotter_ssp3', linewidth=2)\n", + " plt.plot(ba_rcp85hotter_ssp5['Year'], ba_rcp85hotter_ssp5['Hours_Above_Threshold'], color='red', linestyle='-', label='rcp85hotter_ssp5', linewidth=2)\n", + " plt.plot([1980, 2100], [historical_min, historical_min], color='gray', linestyle='--', label='', linewidth=2)\n", + " plt.plot([1980, 2100], [historical_max, historical_max], color='gray', linestyle='--', label='', linewidth=2)\n", + " \n", + " plt.xlim([1980, 2100]); plt.xticks([1980, 1990, 2000, 2010, 2020, 2030, 2040, 2050, 2060, 2070, 2080, 2090, 2100],['1980','','2000','','2020','','2040','','2060','','2080','','2100'])\n", + " plt.legend(loc='upper left', prop={'size': 12})\n", + " plt.ylabel('Hours Above 90% of the Annual Maximum Load')\n", + " plt.grid(False)\n", + " plt.title((ba_to_plot + ' Peakiness Projections'))\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b3afb30-0856-4d4c-af57-d1f2edc1c0d8", + "metadata": {}, + "outputs": [], + "source": [ + "output_df = plot_ba_peakiness(ba_to_plot = 'CISO',\n", + " data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = 0.9,\n", + " image_output_dir = image_output_dir, \n", + " image_resolution = 50, \n", + " save_images = False)\n", + "\n", + "output_df\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "890561c6-d3f0-40c4-871b-5fc732b845d8", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to plot change in peakiness across BAs:\n", + "def plot_ba_peakiness_deltas(scenario_to_plot: str, data_input_dir: str, data_output_dir: str, threshold: int, image_output_dir: str, image_resolution: int, save_images=False):\n", + " \n", + " # Check to see if the processed output file exist and if not then create it:\n", + " if os.path.isfile(os.path.join(data_output_dir, 'BA_Peakiness_Statistics_' + str(threshold) + '_Threshold.csv')) == False:\n", + " # Process the BA peakiness dataframe:\n", + " stats_df = process_ba_peakiness_deltas(data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = threshold)\n", + " else:\n", + " # Read in the output file:\n", + " stats_df = pd.read_csv(os.path.join(data_output_dir, 'BA_Peakiness_Statistics_' + str(threshold) + '_Threshold.csv'))\n", + " \n", + " # Subset to just the scenario you want to plot:\n", + " plot_df = stats_df[stats_df['Scenario'] == scenario_to_plot]\n", + " \n", + " # Create an x-axis the length of the dataframe to be used in plotting:\n", + " x_axis = np.arange(len(plot_df))\n", + " \n", + " # Make the plot:\n", + " plt.figure(figsize=(24, 11))\n", + " plt.rcParams['font.size'] = 14\n", + " \n", + " plt.subplot(211)\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp45cooler_ssp5')], stats_df['Era_One_Delta_Value'].loc[(stats_df['Scenario']=='rcp45cooler_ssp5')], s=75, c='blue', label='rcp45cooler_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp45hotter_ssp5')], stats_df['Era_One_Delta_Value'].loc[(stats_df['Scenario']=='rcp45hotter_ssp5')], s=75, c='cyan', label='rcp45hotter_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp85cooler_ssp5')], stats_df['Era_One_Delta_Value'].loc[(stats_df['Scenario']=='rcp85cooler_ssp5')], s=75, c='orange', label='rcp85cooler_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp85hotter_ssp5')], stats_df['Era_One_Delta_Value'].loc[(stats_df['Scenario']=='rcp85hotter_ssp5')], s=75, c='red', label='rcp85hotter_ssp5')\n", + " plt.grid()\n", + " plt.gca().set_axisbelow(True)\n", + " plt.xticks(color='w')\n", + " plt.xlim(-1, 54)\n", + " plt.ylim(-165, 165)\n", + " plt.xticks(rotation=90)\n", + " plt.xlabel('')\n", + " plt.ylabel('Delta Hours > 90% of the Annual Max')\n", + " plt.title('Annual Mean Change in Load Peakiness: 2020-2059')\n", + " plt.title('a)', loc='left', fontsize=13)\n", + " \n", + " plt.subplot(212)\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp45cooler_ssp5')], stats_df['Era_Two_Delta_Value'].loc[(stats_df['Scenario']=='rcp45cooler_ssp5')], s=75, c='blue', label='rcp45cooler_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp45hotter_ssp5')], stats_df['Era_Two_Delta_Value'].loc[(stats_df['Scenario']=='rcp45hotter_ssp5')], s=75, c='cyan', label='rcp45hotter_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp85cooler_ssp5')], stats_df['Era_Two_Delta_Value'].loc[(stats_df['Scenario']=='rcp85cooler_ssp5')], s=75, c='orange', label='rcp85cooler_ssp5')\n", + " plt.scatter(stats_df['BA'].loc[(stats_df['Scenario']=='rcp85hotter_ssp5')], stats_df['Era_Two_Delta_Value'].loc[(stats_df['Scenario']=='rcp85hotter_ssp5')], s=75, c='red', label='rcp85hotter_ssp5')\n", + " plt.grid()\n", + " plt.gca().set_axisbelow(True)\n", + " plt.legend(loc='lower left', prop={'size': 12})\n", + " plt.xlim(-1, 54)\n", + " plt.ylim(-165, 165)\n", + " plt.xticks(rotation=90)\n", + " plt.xlabel('Balancing Authority')\n", + " plt.ylabel('Delta Hours > 90% of the Annual Max')\n", + " plt.title('Annual Mean Change in Load Peakiness: 2060-2099')\n", + " plt.title('b)', loc='left', fontsize=13)\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 = ('Peakiness.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": "27f44b7f-6259-4dbd-b67d-17fdc3e4bfdc", + "metadata": {}, + "outputs": [], + "source": [ + "plot_ba_peakiness_deltas(scenario_to_plot = 'rcp85hotter_ssp5', \n", + " data_input_dir = data_input_dir,\n", + " data_output_dir = data_output_dir,\n", + " threshold = 0.90,\n", + " image_output_dir = image_output_dir, \n", + " image_resolution = 300, \n", + " save_images = True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31e027c8-476d-44b7-aa8c-b0b71f933f22", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "py.3.9.15_tell", + "language": "python", + "name": "py.3.9.15_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.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}