Skip to content

Commit

Permalink
updated plot trends notebook with annual min precip plots
Browse files Browse the repository at this point in the history
  • Loading branch information
grantbuster committed Mar 29, 2024
1 parent 0ad7f2f commit 88c1451
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 36 deletions.
17 changes: 10 additions & 7 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ publicly available climate change datasets can be used for this purpose, but
the selection of inputs from the myriad of available models and datasets is a
nuanced and subjective process. In this work, we assess datasets from various
global climate models (GCMs) from the Coupled Model Intercomparison Project
(CMIP6). We present evaluations of their skills with respect to the historical
climate and comparisons of their future projections of climate change. We
present the results for different climatic and energy system regions and
include interactive figures in the accompanying software repository. Previous
work has presented similar GCM evaluations, but none have presented variables
and metrics specifically intended for comprehensive energy systems analysis
including impacts on energy demand, thermal cooling, hydropower, water
Phase 6 (CMIP6). We present evaluations of their skills with respect to the
historical climate and comparisons of their future projections of climate
change. We present the results for different climatic and energy system regions
and include interactive figures in the accompanying software repository.
Previous work has presented similar GCM evaluations, but none have presented
variables and metrics specifically intended for comprehensive energy systems
analysis including impacts on energy demand, thermal cooling, hydropower, water
availability, solar energy generation, and wind energy generation. We focus on
GCM output meteorological variables that directly affect these energy system
components including the representation of extreme values that can drive grid
Expand All @@ -33,6 +33,9 @@ All of the plots after the skill tables are interactive. Try hovering your
mouse over data points, clicking and dragging, scrolling, and double clicking
on the legends.

An NREL technical report is in preparation and will accompany this repository
with a discussion of the methods and results.

The NREL software record for this repository is SWR-24-37

Acknowledgments
Expand Down
108 changes: 79 additions & 29 deletions analysis/plot_trends.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,12 @@
"metadata": {},
"outputs": [],
"source": [
"def get_trend_df(region, scenario, feature, period=365*10, option='mean', baseline=True, tslice=None, relative=False, years=None):\n",
"def get_trend_df(region, scenario, feature, period=365*10, option='mean', baseline=True, tslice=None, relative=False, years=None, pr_convert=False):\n",
" \n",
" df = None\n",
"\n",
" if feature == 'pr_min':\n",
" feature = 'pr'\n",
" \n",
" for tag, model in zip(TAGS, MODELS):\n",
" \n",
Expand All @@ -256,7 +259,7 @@
" fp = fp.replace(f'_min', '')\n",
" fp = fp.replace('era5_temperature_2m', 'era5_trh')\n",
" fp = fp.replace('era5_relativehumidity_2m', 'era5_trh')\n",
" \n",
"\n",
" if os.path.exists(fp):\n",
" idf = pd.read_csv(fp, index_col=0)\n",
" idf.index = pd.to_datetime(idf.index)\n",
Expand Down Expand Up @@ -290,6 +293,13 @@
" # drop leap days (some GCMs have them, some do not)\n",
" mask = (df.index.month == 2) & (df.index.day == 29)\n",
" df = df[~mask]\n",
"\n",
" if pr_convert and feature.lower().startswith('pr'):\n",
" # convert kg/m2/s to mm/day and to mm/year\n",
" df *= 86400\n",
" df = df.groupby(df.index.year).sum()\n",
" df.index = pd.to_datetime(df.index, format=\"%Y\")\n",
" df[(df == 0)] = np.nan\n",
" \n",
" if period is not None and option == 'mean':\n",
" df = df.rolling(period, center=True).mean()\n",
Expand Down Expand Up @@ -357,7 +367,7 @@
"outputs": [],
"source": [
"def plot(df_245, df_585, ylabel, xlabel, \n",
" figsize=(10, 4),\n",
" figsize=(10, 4.5),\n",
" del_degf_ylabel=False, abs_degf_ylabel=False,\n",
" y_offset_frac=0.05, \n",
" fp_out=None, show=False):\n",
Expand Down Expand Up @@ -516,20 +526,33 @@
" colors_3d.append(colors.get(tag, 'k'))\n",
" df.at[i, 'Model'] = model\n",
" for key, feat_df in all_df.items():\n",
" value = feat_df[model].values[-1]\n",
" value = np.nan\n",
" if feat_df[model].any():\n",
" if '_max' in key:\n",
" value = feat_df[model].values.max()\n",
" elif '_min' in key:\n",
" value = feat_df[model].values.min()\n",
" else:\n",
" value = feat_df[model].values[-1]\n",
" \n",
" if key == 'rsds':\n",
" key = 'ghi'\n",
" if key == 'pr':\n",
" key = 'precipitation'\n",
" if key == 'pr_min':\n",
" key = 'precipitation_min'\n",
" if np.isnan(value):\n",
" value = 0.0\n",
"\n",
" df.at[i, key] = np.round(value, 3)\n",
" \n",
" col_order = ['Model', \n",
" 'windspeed_100m', 'precipitation', \n",
" 'temperature_2m', 'temperature_2m_degf', \n",
" 'temperature_max_2m', 'temperature_max_2m_degf', 'temperature_min_2m', 'temperature_min_2m_degf',\n",
" 'ghi', 'relativehumidity_2m']\n",
" 'temperature_max_2m', 'temperature_max_2m_degf', \n",
" 'temperature_min_2m', 'temperature_min_2m_degf',\n",
" 'precipitation_min', \n",
" 'ghi', 'relativehumidity_2m']\n",
" df = df[col_order]\n",
" \n",
" offset=1\n",
Expand Down Expand Up @@ -578,7 +601,9 @@
"outputs": [],
"source": [
"all_regions = list(REGIONS.keys())\n",
"all_regions += ['atlantic', 'pacific', 'gulf']"
"all_regions += ['atlantic', 'pacific', 'gulf']\n",
"if 'pr_min' not in FEATURES:\n",
" FEATURES.append('pr_min')"
]
},
{
Expand All @@ -589,44 +614,43 @@
"outputs": [],
"source": [
"for region in all_regions:\n",
"# for region in ['conus']:\n",
"# for region in ['TVA']:\n",
" all_df_245 = {}\n",
" all_df_370 = {}\n",
" all_df_585 = {}\n",
" display(region)\n",
" region = region.lower().replace(' ', '_')\n",
" \n",
" data_kwargs = {\n",
" 'temperature_2m': dict(period=365*10, baseline=True, tslice=slice(None, None, 365*5)),\n",
" 'temperature_2m': dict(period=365*20, baseline=True, tslice=slice(None, None, 365*5)),\n",
" 'temperature_max_2m': dict(period=365*10, option='max', baseline='ERA5', tslice=slice(None, None, 365*5)),\n",
" 'temperature_min_2m': dict(period=365*10, option='min', baseline='ERA5', tslice=slice(None, None, 365*5)),\n",
" 'relativehumidity_2m': dict(period=365*10, baseline=True, tslice=slice(None, None, 365*5), relative=False),\n",
" 'relativehumidity_2m': dict(period=365*20, baseline=True, tslice=slice(None, None, 365*5), relative=False),\n",
" 'rsds': dict(period=365*10, baseline=True, tslice=slice(None, None, 365*5), relative=True, years=list(range(2005, 2060))),\n",
" 'pr': dict(period=365*10, baseline=True, tslice=slice(None, None, 365*5), relative=True),\n",
" 'windspeed_100m': dict(period=365*10, baseline=True, tslice=slice(None, None, 365*5), relative=True),\n",
" 'pr': dict(period=20, baseline=True, tslice=slice(None, None, 5), relative=True, pr_convert=True),\n",
" 'pr_min': dict(period=10, option='min', tslice=slice(None, None, 5), baseline='DAYMET', relative=False, pr_convert=True),\n",
" 'windspeed_100m': dict(period=365*20, baseline=True, tslice=slice(None, None, 365*5), relative=True),\n",
" }\n",
" \n",
"\n",
" plot_kwargs = {\n",
" 'temperature_2m': dict(ylabel='Change in Temperature ($^\\circ$C)', xlabel='Year (10-Year Moving Average)', \n",
" figsize=(10, 4), del_degf_ylabel=True, y_offset_frac=0.05,\n",
" 'temperature_2m': dict(ylabel='Change in Temperature ($^\\circ$C)', xlabel='Year (20-Year Moving Average)', \n",
" del_degf_ylabel=True, \n",
" fp_out=f'./trend_plots/{region}_t2m.png'),\n",
" 'temperature_max_2m': dict(ylabel='10-Year Maximum Temperature ($^\\circ$C)', xlabel='Year (10-Year Window Maximum)', \n",
" figsize=(10, 4), abs_degf_ylabel=True, y_offset_frac=0.05, \n",
" 'temperature_max_2m': dict(ylabel='10-Year Maximum Temperature ($^\\circ$C)', xlabel='Year (10-Year Window)', \n",
" abs_degf_ylabel=True, y_offset_frac=0.02, \n",
" fp_out=f'./trend_plots/{region}_t2m_max.png'),\n",
" 'temperature_min_2m': dict(ylabel='10-Year Minimum Temperature ($^\\circ$C)', xlabel='Year (10-Year Window Minimum)', \n",
" figsize=(10, 4), abs_degf_ylabel=True, y_offset_frac=0.2, \n",
" 'temperature_min_2m': dict(ylabel='10-Year Minimum Temperature ($^\\circ$C)', xlabel='Year (10-Year Window)', \n",
" abs_degf_ylabel=True, y_offset_frac=0.2, \n",
" fp_out=f'./trend_plots/{region}_t2m_min.png'),\n",
" 'relativehumidity_2m': dict(ylabel='Percent Change in Relative Humidity (%)', xlabel='Year (10-Year Moving Average)', \n",
" figsize=(10, 4), y_offset_frac=0.05,\n",
" 'relativehumidity_2m': dict(ylabel='Percent Change in Relative Humidity (%)', xlabel='Year (20-Year Moving Average)', \n",
" fp_out=f'./trend_plots/{region}_rh.png'),\n",
" 'rsds': dict(ylabel='Percent Change in GHI (%)', xlabel='Year (10-Year Moving Average)',\n",
" figsize=(10, 4), y_offset_frac=0.05,\n",
" fp_out=f'./trend_plots/{region}_ghi.png'),\n",
" 'pr': dict(ylabel='Percent Change in Precipitation (%)', xlabel='Year (10-Year Moving Average)', \n",
" figsize=(10, 4), y_offset_frac=0.05,\n",
" 'pr': dict(ylabel='Percent Change in Precipitation (%)', xlabel='Year (20-Year Moving Average)', \n",
" fp_out=f'./trend_plots/{region}_pr.png'),\n",
" 'windspeed_100m': dict(ylabel='Percent Change in Windspeed (%)', xlabel='Year (10-Year Moving Average)', \n",
" figsize=(10, 4), y_offset_frac=0.05,\n",
" 'pr_min': dict(ylabel='10-Year Minimum Annual Rainfall (mm)', xlabel='Year (10-Year Window)', \n",
" y_offset_frac=0.02, fp_out=f'./trend_plots/{region}_pr_min.png'),\n",
" 'windspeed_100m': dict(ylabel='Percent Change in Windspeed (%)', xlabel='Year (20-Year Moving Average)', \n",
" fp_out=f'./trend_plots/{region}_ws100m.png'),\n",
" }\n",
"\n",
Expand All @@ -638,8 +662,9 @@
" all_df_245[feature] = df_245\n",
" all_df_370[feature] = df_370\n",
" all_df_585[feature] = df_585\n",
" \n",
" plot(df_245, df_585, show=False, **plot_kwargs[feature])\n",
"\n",
" if df_245.any().any():\n",
" plot(df_245, df_585, show=False, **plot_kwargs[feature])\n",
" \n",
" all_df_245 = add_degf(all_df_245)\n",
" all_df_370 = add_degf(all_df_370)\n",
Expand All @@ -650,8 +675,33 @@
" scatter_3d(all_df_585, 'SSP5 8.5', f'./trend_plots/{region}_scatter_ssp585.png', show=False)\n",
" \n",
" for feature in FEATURES:\n",
" plotly(feature, all_df_245, all_df_370, all_df_585, show=False, **plot_kwargs[feature])"
" if all_df_245[feature].any().any():\n",
" plotly(feature, all_df_245, all_df_370, all_df_585, show=False, **plot_kwargs[feature])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "07bbc940-da9d-4941-aa57-3536ce859299",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "21b43d25-c17c-4980-a5d8-a3d1ce2b02e2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "da31f35a-b61f-4951-ab5d-baea8a67536e",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down

0 comments on commit 88c1451

Please sign in to comment.