{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "0cb477d3", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T06:09:49.902813Z", "start_time": "2023-01-30T06:09:49.080321Z" } }, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "from multiprocessing import Pool\n", "import shapely.geometry as sgeom\n", "import cartopy as ctp\n", "import cartopy.crs as ccrs\n", "import matplotlib.cm as cm\n", "import matplotlib.pyplot as plt\n", "import matplotlib.ticker as mticker\n", "import matplotlib.patches as mpatches\n", "import matplotlib.transforms as mtransforms\n", "\n", "\n", "# Define the URL of the MJO LPT list\n", "MAIN_URL = 'https://orca.atmos.washington.edu/data/lpt/kc2020/20_72h/thresh12/systems/'\n", "\n", "def filter_lpt(years_to_filter, lon_begin_min, lon_begin_max):\n", " \"\"\"\n", " Filters MJO-C and MJO-B from MJO LPT list, returns mjo_c and mjo_b\n", " Predefined variables:\n", " mc_left, mc_right\n", " \"\"\"\n", " lpt_data = pd.read_csv(MAIN_URL + 'mjo_lpt_list.txt', skiprows=0, delim_whitespace=True)\n", " lpt_data[\"eprop_begin\"] = lpt_data[\"eprop_begin\"].astype(str)\n", " \n", " years = None\n", " if isinstance(years_to_filter, list):\n", " years = years_to_filter\n", " elif isinstance(years_to_filter, range):\n", " years = [str(year) for year in range(years_to_filter.start, years_to_filter.stop + 1)]\n", " elif isinstance(years_to_filter, int) or isinstance(years_to_filter, str):\n", " years = [str(years_to_filter)]\n", " else:\n", " raise ValueError(\"years_to_filter must be a list, range, int, or str.\")\n", " \n", " eprop_data = lpt_data[lpt_data[\"eprop_begin\"].str[:4].isin(years)]\n", " \n", " # More filter definition can be added here\n", " mc_left = 95\n", " mc_right = 150\n", " mjo_c = eprop_data[(eprop_data.eprop_lon_begin >= lon_begin_min) \n", " & (eprop_data.eprop_lon_begin <= lon_begin_max) \n", " & (eprop_data.eprop_lon_end >= mc_right)]\n", " mjo_b = eprop_data[(eprop_data.eprop_lon_begin >= lon_begin_min) \n", " & (eprop_data.eprop_lon_begin <= lon_begin_max) \n", " & (eprop_data.eprop_lon_end >= mc_left) \n", " & (eprop_data.eprop_lon_end <= mc_right)]\n", " return mjo_c, mjo_b\n", "\n", "def download_track(args):\n", " \"\"\"\n", " Download tracks for the given lpt index and begin year\n", " \"\"\"\n", " begin_year, eprop_begin = args\n", " end_year = begin_year + 1\n", " url_track = f'{MAIN_URL}lpt_systems_tmpa_{begin_year}060100_{end_year}063021.txt'\n", " lpt_track = pd.read_csv(url_track, skiprows=1, delim_whitespace=True)\n", " start_index = lpt_track.index[(lpt_track[\"YYYYMMDDHH\"] == eprop_begin) & (lpt_track[\"cen_lon.__\"] == eprop_lon_begin)][0]\n", " end_index = lpt_track.index[(lpt_track[\"_A_[km2]\"] > lpt_index) & (lpt_track[\"YYYYMMDDHH\"] == \"LPT\")][0]\n", " selected_track_lpt = lpt_track.loc[start_index+1:end_index-1]\n", " selected_track_lpt.insert(0, 'lpt_index', value=lpt_index)\n", " selected_track_lpt.insert(0, 'begin_year', value=begin_year)\n", " return selected_track_lpt # input for track_list_lpt \n", "\n", "def process_mjo_track(mjo_filtered):\n", " with Pool() as p:\n", " track_list_lpt = pd.concat(p.map(download_track, zip(lpt_filtered[\"begin_year\"],\n", " lpt_filtered[\"eprop_begin\"])), ignore_index=True)\n", " track_list_lpt['mjo_id'] = track_list_lpt.groupby([\"begin_year\", \"lpt_index\"]).ngroup() + 1\n", " new_cols = track_list_lpt.columns.tolist()\n", " for i, col in enumerate(new_cols):\n", " new_cols[i] = col.replace(\".\", \"\").replace(\"[\", \"\").replace(\"]\", \"\").replace(\"__\", \"\")\n", " track_list_lpt.columns = new_cols\n", " return track_list_lpt\n", "\n", "def subset_mjo_from_lpt(track_list_lpt, lpt_filtered):\n", " \n", " start_index = track_list_lpt.index[(track_list_lpt[\"YYYYMMDDHH\"] == )]\n", " end_index\n", " \n", " return track_list_mjo\n", "\n", "def group_tracks_by_mjo_id(track_list_mjo, mjo_id=None):\n", " if mjo_id is None:\n", " tracks_grouped = track_list_mjo.groupby('mjo_id')\n", " else:\n", " tracks_grouped = track_list_mjo[track_list_mjo[\"mjo_id\"]==mjo_id].groupby('mjo_id')\n", " return tracks_grouped\n", "\n", "def plot_maps_add_rectangle(axs, fig):\n", " for label, ax in axs.items():\n", " # Add label to the top-left corner of the axes\n", " trans = mtransforms.ScaledTranslation(5/72, -5/72, fig.dpi_scale_trans)\n", " ax.text(0.0, 1.0, label, transform=ax.transAxes + trans,\n", " fontsize=\"large\", verticalalignment=\"top\", fontfamily=\"serif\",\n", " bbox=dict(facecolor=\"0.8\", edgecolor=\"none\", pad=3.0))\n", "\n", " # Add coastlines and gridlines\n", " ax.coastlines(resolution='50m', linewidth=1, color='dimgrey', zorder=0)\n", " ax.set_extent([40, 40+180, -30, 30], ccrs.PlateCarree())\n", " gridlines = ax.gridlines(crs=ccrs.PlateCarree(), alpha=0.5, \n", " linestyle='--', linewidth=.75, zorder=0,\n", " xlocs=[40, 70, 100, 130, 160, -170, -140], \n", " ylocs=[30, 15, 0, -15, -30])\n", " gridlines.left_labels = True\n", " gridlines.bottom_labels = True\n", "\n", " # Add rectangle patch\n", " ax.add_patch(mpatches.Rectangle(xy=[95, -10], width=55, height=17,\n", " facecolor='green', alpha=0.2, transform=ccrs.PlateCarree()))\n", "\n", "def plot_grouped_tracks(grouped, ax):\n", " \"\"\"\n", " Plot grouped tracks (mjo_c vs mjo_b) on the given axis (subplot a or b).\n", " \n", " Parameters:\n", " grouped (DataFrameGroupBy): Grouped data.\n", " ax (Matplotlib Axes): Axis to plot the grouped tracks.\n", " \"\"\"\n", " # Get a color map and colors for each group\n", " color_map = cm.get_cmap(\"tab10\")\n", " colors = color_map(np.linspace(0,1,len(grouped)))\n", " \n", " for i, (group_name, group) in enumerate(grouped):\n", " # Get the tracks\n", " tracks = sgeom.LineString(zip(group['cen_lon'], group['cen_lat']))\n", " face_color = colors[i,:]\n", " \n", " # Plot the tracks and their buffers\n", " ax.add_geometries([tracks], ccrs.PlateCarree(), facecolor='none')\n", " ax.add_geometries([tracks.buffer(1.5)], ccrs.PlateCarree(), facecolor=face_color, alpha=0.3)\n", " \n", " # Get information from the first and last point of the track \n", " first_row = group.iloc[0]\n", " end_row = group.iloc[-1]\n", " origin_lon = first_row['cen_lon']\n", " origin_lat = first_row['cen_lat']\n", " end_lon = end_row['cen_lon']\n", " end_lat = end_row['cen_lat']\n", " origin_mon = first_row['YYYYMMDDHH'][4:6]\n", " end_mon = end_row['YYYYMMDDHH'][4:6]\n", " \n", " # Plot a circle (or a cross) to mark the origin (end point) of the line\n", " ax.scatter(origin_lon, origin_lat, transform=ccrs.PlateCarree(), \n", " s=150, color='blue', marker='o', facecolor='none', zorder=3)\n", " ax.scatter(end_lon, end_lat, transform=ccrs.PlateCarree(), \n", " s=150, color='red', marker='x', zorder=3)\n", " \n", " # Add text showing month for each MJO event\n", " ax.text(origin_lon, origin_lat, origin_mon, transform=ccrs.PlateCarree(), ha='center', va='center', \n", " fontsize=7, color='black', zorder=4)\n", " ax.text(end_lon, end_lat, end_mon, transform=ccrs.PlateCarree(), ha='center', va='center', \n", " fontsize=7, color='black', zorder=4)" ] }, { "cell_type": "code", "execution_count": 2, "id": "cadde1a9", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T06:09:52.222925Z", "start_time": "2023-01-30T06:09:51.920131Z" } }, "outputs": [], "source": [ "# Filter MJO LPT list based on years, begin_lon_min, and begin_lon_max \n", "lpt_c, lpt_b = filter_lpt(range(1998,1999), 40, 95)" ] }, { "cell_type": "code", "execution_count": 8, "id": "ea60ffe1", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T06:21:27.449709Z", "start_time": "2023-01-30T06:21:27.436108Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
begin_yearlpt_indexlptgroupdurationmean_zonal_spdbeginendvolraineprop_begin_idxeprop_end_idxeprop_spdeprop_dureprop_begineprop_endeprop_lon_begineprop_lon_end
0199826.032637.380.0199901181519990225000.0332664.6329.121999012215199902201885.2188.1
1199830.013016.750.0199903130319990329210.0591359.799.501999032009199903292193.7167.1
\n", "
" ], "text/plain": [ " begin_year lpt_index lptgroup duration mean_zonal_spd begin \\\n", "0 1998 26.03 26 37.38 0.0 1999011815 \n", "1 1998 30.01 30 16.75 0.0 1999031303 \n", "\n", " end volrain eprop_begin_idx eprop_end_idx eprop_spd eprop_dur \\\n", "0 1999022500 0.0 33 266 4.63 29.12 \n", "1 1999032921 0.0 59 135 9.79 9.50 \n", "\n", " eprop_begin eprop_end eprop_lon_begin eprop_lon_end \n", "0 1999012215 1999022018 85.2 188.1 \n", "1 1999032009 1999032921 93.7 167.1 " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.set_option('display.max_columns', 20)\n", "pd.set_option('display.max_rows', 20)\n", "lpt_c.reset_index(drop=True)" ] }, { "cell_type": "code", "execution_count": 4, "id": "0f7137fe", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T06:10:03.366745Z", "start_time": "2023-01-30T06:10:01.882565Z" } }, "outputs": [], "source": [ "track_list_lpt_c = process_lpt_track(lpt_c)\n", "track_list_lpt_b = process_lpt_track(lpt_b)" ] }, { "cell_type": "code", "execution_count": 7, "id": "5a748989", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T06:10:36.560351Z", "start_time": "2023-01-30T06:10:36.544731Z" }, "scrolled": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
begin_yearlpt_indexYYYYMMDDHH_A_km2cen_latcen_lonNobjmjo_id
0199826.031999011815357440.0-2.0499.101.01
1199826.031999011818450715.0-2.3599.191.01
2199826.031999011821637167.0-2.7499.351.01
3199826.031999011900826500.0-3.1199.571.01
4199826.031999011903898833.0-3.1999.661.01
...........................
430199830.0119990329091083796.04.61166.001.02
431199830.0119990329121028297.04.67166.201.02
432199830.011999032915948971.04.74166.341.02
433199830.011999032918737148.05.00166.611.02
434199830.011999032921384565.05.42167.081.02
\n", "

435 rows × 8 columns

\n", "
" ], "text/plain": [ " begin_year lpt_index YYYYMMDDHH _A_km2 cen_lat cen_lon Nobj \\\n", "0 1998 26.03 1999011815 357440.0 -2.04 99.10 1.0 \n", "1 1998 26.03 1999011818 450715.0 -2.35 99.19 1.0 \n", "2 1998 26.03 1999011821 637167.0 -2.74 99.35 1.0 \n", "3 1998 26.03 1999011900 826500.0 -3.11 99.57 1.0 \n", "4 1998 26.03 1999011903 898833.0 -3.19 99.66 1.0 \n", ".. ... ... ... ... ... ... ... \n", "430 1998 30.01 1999032909 1083796.0 4.61 166.00 1.0 \n", "431 1998 30.01 1999032912 1028297.0 4.67 166.20 1.0 \n", "432 1998 30.01 1999032915 948971.0 4.74 166.34 1.0 \n", "433 1998 30.01 1999032918 737148.0 5.00 166.61 1.0 \n", "434 1998 30.01 1999032921 384565.0 5.42 167.08 1.0 \n", "\n", " mjo_id \n", "0 1 \n", "1 1 \n", "2 1 \n", "3 1 \n", "4 1 \n", ".. ... \n", "430 2 \n", "431 2 \n", "432 2 \n", "433 2 \n", "434 2 \n", "\n", "[435 rows x 8 columns]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pd.set_option('display.max_rows', 10)\n", "track_list_lpt_c" ] }, { "cell_type": "code", "execution_count": null, "id": "124c9711", "metadata": {}, "outputs": [], "source": [ "track_list_mjo = subset_mjo_from_lpt(track_list_lpt_c, lpt_c)" ] }, { "cell_type": "code", "execution_count": null, "id": "4922b150", "metadata": { "ExecuteTime": { "end_time": "2023-01-30T05:32:09.221661Z", "start_time": "2023-01-30T05:32:04.775767Z" }, "scrolled": false }, "outputs": [], "source": [ "# Create figure and axes\n", "fig, axs = plt.subplot_mosaic(\n", " [[\"a)\"], [\"b)\"]], figsize=(6.5, 4.25), dpi=600, constrained_layout=True, \n", " subplot_kw={\"projection\": ccrs.PlateCarree(central_longitude=180)})\n", "\n", "plot_maps_add_rectangle(axs, fig)\n", " \n", "grouped_c = group_tracks_by_mjo_id(track_list_mjo_c, mjo_id=None)\n", "grouped_b = group_tracks_by_mjo_id(track_list_mjo_b, mjo_id=None)\n", " \n", "plot_grouped_tracks(grouped_c, axs[\"a)\"])\n", "plot_grouped_tracks(grouped_b, axs[\"b)\"])\n", "\n", "plt.rcParams['axes.facecolor'] = 'white'\n", "plt.rcParams['savefig.facecolor'] = 'white'\n", "plt.show()\n", "\n", "fig.savefig('../figures/tracks-mjo-c-and-b.png', dpi=600, bbox_inches='tight')" ] }, { "cell_type": "code", "execution_count": null, "id": "9ef69ee7", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "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.7.12" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 5 }