2018-10-11 20:33:23 -06:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
2018-10-14 13:17:01 -06:00
"The ModelSounding class allows us to create a vertical sounding through any available AWIPS model with isobaric levels.\n",
"\n",
"* A Shapely Point geometry is used to select longitude and latitude:\n",
" from shapely.geometry import Point\n",
" point = Point(-104.67,39.87)\n",
"* Parameters `['T','DpT','uW','vW']` are requested for all isobaric levels available for the selected model.\n",
"\n",
"* There is a single-record query performed for `level = \"0.0FHAG\"` to determine the surface pressure level.\n",
"* Pay attention to units when switching models. This notebook was written for the NAM 40km AWIPS model where temperature and dewpoint are returned as Kelvin and wind components as m/s."
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-14 13:17:01 -06:00
"execution_count": 1,
2018-10-11 20:33:23 -06:00
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2018-10-15 08:25:13 -06:00
"Using NAM40 forecast time 2018-10-15 06:00:00\n"
2018-10-11 20:33:23 -06:00
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"%matplotlib inline\n",
"from awips.dataaccess import DataAccessLayer, ModelSounding\n",
"from awips import ThriftClient\n",
2018-10-11 20:33:23 -06:00
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
2018-10-14 13:17:01 -06:00
"from metpy.plots import SkewT, Hodograph\n",
2018-10-11 20:33:23 -06:00
"from metpy.units import units\n",
2018-10-14 13:17:01 -06:00
"from mpl_toolkits.axes_grid1.inset_locator import inset_axes\n",
"from math import sqrt\n",
"from datetime import datetime, timedelta\n",
"from shapely.geometry import Point, Polygon\n",
"import shapely.wkb\n",
"import timeit\n",
"model=\"NAM40\"\n",
"parms = ['T','DpT','uW','vW']\n",
2018-10-11 20:33:23 -06:00
"server = 'edex-cloud.unidata.ucar.edu'\n",
"DataAccessLayer.changeEDEXHost(server)\n",
2018-10-14 13:17:01 -06:00
"\n",
"# note the order is LON,lat and not lat,LON\n",
"point = Point(-104.67,39.87)\n",
"\n",
"inc = 0.005\n",
"bbox=[point.y-inc, point.y+inc, point.x-inc, point.x+inc]\n",
"polygon = Polygon([(bbox[0],bbox[2]),(bbox[0],bbox[3]), \n",
" (bbox[1],bbox[3]),(bbox[1],bbox[2]),\n",
" (bbox[0],bbox[2])])\n",
"\n",
"# Get latest forecast cycle run\n",
"timeReq = DataAccessLayer.newDataRequest(\"grid\")\n",
"timeReq.setLocationNames(model)\n",
"cycles = DataAccessLayer.getAvailableTimes(timeReq, True)\n",
"times = DataAccessLayer.getAvailableTimes(timeReq)\n",
2018-10-15 08:25:13 -06:00
"fcstRun = DataAccessLayer.getForecastRun(cycles[-2], times)\n",
2018-10-14 13:17:01 -06:00
"\n",
"print(\"Using \" + model + \" forecast time \" + str(fcstRun[0]))"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-14 13:17:01 -06:00
"execution_count": 2,
2018-10-11 20:33:23 -06:00
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2018-10-15 08:25:13 -06:00
"Found surface record at 836.9MB\n"
2018-10-11 20:33:23 -06:00
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"p,t,d,u,v = [],[],[],[],[]\n",
"use_parms = ['T','DpT','uW','vW','P']\n",
"use_level = \"0.0FHAG\"\n",
"sndObject = ModelSounding.getSounding(model, use_parms, \n",
2018-10-15 08:25:13 -06:00
" [\"0.0FHAG\"], point, timeRange=[fcstRun[0]])\n",
2018-10-14 13:17:01 -06:00
"if len(sndObject) > 0:\n",
" for time in sndObject._dataDict:\n",
" p.append(float(sndObject._dataDict[time][use_level]['P']))\n",
" t.append(float(sndObject._dataDict[time][use_level]['T']))\n",
" d.append(float(sndObject._dataDict[time][use_level]['DpT']))\n",
" u.append(float(sndObject._dataDict[time][use_level]['uW']))\n",
" v.append(float(sndObject._dataDict[time][use_level]['vW']))\n",
" print(\"Found surface record at \" + \"%.1f\" % p[0] + \"MB\")\n",
"else:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (model, use_parms, point, use_level)) +\"]\")\n",
2018-10-15 08:25:13 -06:00
" \n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using 32 levels between 836.9 and 50.0MB\n"
]
}
],
"source": [
2018-10-14 13:17:01 -06:00
"\n",
"# Get isobaric levels with our requested parameters\n",
"levelReq = DataAccessLayer.newDataRequest(\"grid\", envelope=point)\n",
"levelReq.setLocationNames(model)\n",
"levelReq.setParameters('T','DpT','uW','vW')\n",
"availableLevels = DataAccessLayer.getAvailableLevels(levelReq)\n",
"\n",
"# Clean levels list of unit string (MB, FHAG, etc.)\n",
"levels = []\n",
"for lvl in availableLevels:\n",
" name=str(lvl)\n",
" if 'MB' in name and '_' not in name:\n",
" # If this level is above (less than in mb) our 0.0FHAG record\n",
" if float(name.replace('MB','')) < p[0]:\n",
" levels.append(lvl)\n",
"\n",
"# Get Sounding\n",
"sndObject = ModelSounding.getSounding(model, parms, levels, point, \n",
" timeRange=[fcstRun[0]])\n",
"\n",
"if not len(sndObject) > 0:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (model, parms, point, levels)) +\"]\")\n",
" \n",
"for time in sndObject._dataDict:\n",
" for lvl in sndObject._dataDict[time].levels():\n",
" for parm in sndObject._dataDict[time][lvl].parameters():\n",
" if parm == \"T\":\n",
" t.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == \"DpT\":\n",
" d.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'uW':\n",
" u.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'vW':\n",
" v.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" else:\n",
" print(\"WHAT IS THIS\")\n",
" print(sndObject._dataDict[time][lvl][parm])\n",
" # Pressure is our requested level rather than a returned parameter\n",
" p.append(float(lvl.replace('MB','')))\n",
"\n",
"# convert to numpy.array()\n",
"p = np.array(p, dtype=float)\n",
"t = (np.array(t, dtype=float) - 273.15) * units.degC\n",
"d = (np.array(d, dtype=float) - 273.15) * units.degC\n",
"u = (np.array(u, dtype=float) * units('m/s')).to('knots')\n",
"v = (np.array(v, dtype=float) * units('m/s')).to('knots')\n",
"w = np.sqrt(u**2 + v**2)\n",
"\n",
"print(\"Using \" + str(len(levels)) + \" levels between \" + \n",
" str(\"%.1f\" % max(p)) + \" and \" + str(\"%.1f\" % min(p)) + \"MB\")"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
2018-10-14 13:17:01 -06:00
"## Skew-T/Log-P"
2018-10-11 20:33:23 -06:00
]
},
{
"cell_type": "code",
2018-10-15 08:25:13 -06:00
"execution_count": 4,
2018-10-11 20:33:23 -06:00
"metadata": {},
"outputs": [
{
"data": {
2018-10-15 08:25:13 -06:00
"image/png": "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
2018-10-11 20:33:23 -06:00
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.rcParams['figure.figsize'] = (12, 14)\n",
2018-10-14 13:17:01 -06:00
"\n",
"# Skew-T\n",
"skew = SkewT(rotation=45)\n",
"skew.plot(p, t, 'r', linewidth=2)\n",
"skew.plot(p, d, 'g', linewidth=2)\n",
"skew.plot_barbs(p, u, v)\n",
"skew.plot_dry_adiabats()\n",
"skew.plot_moist_adiabats()\n",
"skew.plot_mixing_lines(linestyle=':')\n",
"\n",
"skew.ax.set_ylim(1000, np.min(p))\n",
"skew.ax.set_xlim(-50, 40)\n",
"\n",
"# Title\n",
"plt.title( model + \" (\" + str(point) + \") \" + str(time.getRefTime()))\n",
"\n",
"# Hodograph\n",
2018-10-11 20:33:23 -06:00
"ax_hod = inset_axes(skew.ax, '40%', '40%', loc=2)\n",
2018-10-14 13:17:01 -06:00
"h = Hodograph(ax_hod, component_range=max(w.magnitude))\n",
2018-10-11 20:33:23 -06:00
"h.add_grid(increment=20)\n",
2018-10-14 13:17:01 -06:00
"h.plot_colormapped(u, v, w)\n",
"\n",
"# Dotted line at 0C isotherm\n",
"l = skew.ax.axvline(0, color='c', linestyle='-', linewidth=1)\n",
"\n",
2018-10-11 20:33:23 -06:00
"plt.show()"
]
2018-10-15 08:25:13 -06:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model Sounding Comparison"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using CMC forecast time 2018-10-15 06:00:00\n",
"Found surface record at 849.0MB\n",
"Using 19 levels between 849.0 and 50.0MB\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtIAAANjCAYAAACHi/3OAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzsnXd8VFX6/99nkkBCIHQIRQggHRIgBYINBFEUBFRUwIINLLuubvuuZb+7bnP7d79b1NXv+mMVpCgiiIouCIKCkhBp0gktEEqAhPQyc35/3BkcQspk5s7MnZnn/XrNa+a2c565c+fc557zfM6jtNYIgiAIgiAIgtA0bME2QBAEQRAEQRBCEXGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQBEEQBEEQvEAcaUEQBEEQBEHwAnGkBUEQBEEQBMELxJEWBEEQBEEQBC8QR1oQwgCl1EKl1NRg2+EpSqnmSqldSqnEYNsSjiilblVKLaq17l2l1E3BskkQBCEcEUdaEExCKTVTKZWtlCpRSuUrpT5SSl3t3PZzpZRWSj1Z65innOt/7rYuQSn1F6XUUWdZB5zLHeqpNxlIAZY7l2crpezOYy8opbYqpSa57d9GKfWyUuqkUqpMKbVDKfVArTIPK6XGu5WnlVI/qrVPnlJqjFLqFWddJUqpKqVUtdvyR/WcrjnAeq31yXq+UzOl1DtOO7RSakyt7Uop9Tul1Fnn6/dKKVVHOfc7j3+4Hjtc+92tlNqtlCpVSh1USl3jXD/L7buUOM+XVkql1lPO75VSx5zn/YhS6rla2ycrpXY6y9qolBrUgE3tlFKLlVIFztcCpVSCc1uPWnaVOO36AYDWegUwxHltuPgt8OsG6hullPqPUuqcUuqMUuptpVQXt+0NnnOl1KtKqb1KKYdSanatspVS6ldKqeNKqSKl1Dql1OAGbOmilFqhlDrh/F5JtbY3V0q97jzPJ5VS36+vLOf+31HGf7NSKTWv1rYkZx3u5/KnDZTVTim1zHmtHFFKzay1vaNS6i2lVKFS6rxSakEDZTX4PZRS45RSe5zX3VqlVM8AlZXk3KfMecz4WtufdtZR5KyzuafHCkLYobWWl7zk5eML+D5wGrgNiAdigMnAH5zbfw7sBbbUOi7Huf7nzuVmQBbwH2AQxsNuJ+CnwM311P0P4Dm35dnA587PNuC7QBnQzll+NvAh0Mtp503AKeD7bmUcBsa7lXcWKAAS3PbJA8bUsuXnwHwPztdO4KoGtjcDngKuBvLrqGeu87x1B7oBu4BHa+3TFtjjrOvhBuq6ATgCjHKer25At3r2nQ0cBFQ92/sD8c7P3YBvgNucy32BC87vFA08AxwAousp6yXgEyABaA2sBv5cz769ADuQ5LbuOeDvtfbbD6TVU8ZEYLqzvhbA68AqT8858AQwznl9za5V9p3ACaA3EAW8COQ08Jt0Bh4HMgHt/r2c218ENjh/44HASeCmBsq7DZgKvAzMq7UtyVlHnb9DHWUtBBYDLZ2/ZREw2G37BuDPzt8sBhjeQFn1fg+gg7Ps6UAs8AfgywCVtcn5HeKA24FCoKNz240Y7cVgZ13rgN96cqy85BWOr6AbIC95hfrLecMsAaY3sM/PgfnAbtdN13kj2u1c/3PnuoedN6mWTag/F7jabXk2TkfauRzvdBTSgIcwHP74WmXc5fwOCc7lw1zqSH8OvA/8zO0YrxxpoAdQ3gTHpa56NgJz3JYfqu0YAK9gOGPraNiR3gg85KEta93PQSP7dgN2AD92Ln8H+MBtu815HsbVc/xHwONuy08AH9ez78+AtbXWXQUcqrXutSbYPwIobso5d67/nMsd6f8ClrgtDwYqPLAhmrod6ePABLflXwKLPCjvV/jgSDv/S1VAP7d1b+J0JIEJzv9OlIfnuN7vgTFqs7FW3eXAAH+WBfQDKoFWbus24HxoAt4CfuO2bRxw0pNj5SWvcHxJaIcg+E4mRi/PMg/2fRO4z/n5fuCNWtvHY/QClnhSsVIqHqM3cm8926MxnPMSjN7IG4CPtNaltXZd6vwOmQ1U91PgaaVUO09sa4ChQK7WusaHMgYD29yWtznXAaCUysB4cHiloUKUUlHO/ToqI4QmTyn1d6VUXB379gSu5fLfrPZ+P1FKlWA8AMRjOB4Ayvmi1vKQeor6BzBJKdVWKdUWo3evvlCZ+4B/11q3G0hyhYO4rUtpyH43rsXoUXfR4DlvhEXAlUqpfkqpGIxrf5WHx16C81x09cGW+jji/P3/n6onjArDUbRrrffVU/cojP/iv53hL1lKqevcbP+JUmqlh9/jkvPt/M8edG03s6xaDMb4fxZ7Upbzc2elVHsPjhWEsEMcaUHwnfZAgYeO4XxghtOZuNu5XLus/CbU3cb5Xlxr/SilVCHG8O4MYJrWughjiPey8p22Fzi314nWeitGqMF/NcG++myubW9TaYkxVO2iCGjpjMWNwgiL+K7W2tFIOZ0xht/vAK4BhgHDgefr2Pc+YIPW+lBDBWqtfwu0wujRfdPNzv8A1ykjrrwZ8CxGCEuLeorKcW4/63zZnd/rEpQRz90ZeKfWJtc5blNrXRsaQRmx1f8NuMfF13vOGysP45rbgOFklmOEGDztwXF10dKtfndbWnlZXgGQDvQEUp3l1BfXXPsc1K67O0av9FogEfgTsNzlmGutf6u1nuRWVkPfo8G6zCyrid+xrusA5/am1CMIYYE40oLgO2eBDs7e3wbRWh/FiIv9DbBfa32sjrK6XHZg/RQ632vfqL7UWrfRWnfQWo/SWq92ri+oq3yn7R2c2xviv4HHlG+zbZx3t1fVEs55WEYJRiyviwSgRGutMcI5tmutN3lQTrnz/W9a63ytdQFGfOfNdexbV69vnWiDr53lv+BctwejJ/bvGI5lB4w447x6inkb2IdxrhIwehBrP3jhLHNpHaMYrnNcWGtdIQ2glLoSo+f7e1rrDW6bGjrnjfEzDGf1CoyRjxeAT5VSLZRS17j9/t80WMq3drjqd7el2Gn/R27lzWqsMK11idY6W2tdo7U+hRGCM6FWT7573bXXX6wb4/c+rLX+l9a6Wmu9CDiGEWbTpO/hQV3+LKuhfeu6DnBub0o9ghAWiCMtCL6zCajAEDN5whvAD6g7RGA1cKMzZKNR3IZo+3lY92pgYh3l344R2/hlI/XtAd7F6E31lu1Ab9eDh9b6qNa6pevlYRnfcGmIQgrfhiGMA6Y5ZxU4CYwG/qSU+nvtQrTW5zEc2QadQaXUVRhD57V7fRsjGujjVt87WushWuv2GM5lTwxxaV2kAP/UWpc6neRXqOXgO0NQplO3gz8Qw6m7UGvdtjr2dZXXE+Ma+aXW+s1amxs6542RAizWWuc5HdZ5GEK1QVr
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using GFS20 forecast time 2018-10-15 06:00:00\n",
"Found surface record at 848.4MB\n",
"Using 22 levels between 848.4 and 100.0MB\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using NAM40 forecast time 2018-10-15 12:00:00\n",
"Found surface record at 836.4MB\n",
"Using 32 levels between 836.4 and 50.0MB\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Using RAP13 forecast time 2018-10-15 13:00:00\n",
"Found surface record at 843.9MB\n",
"Using 30 levels between 843.9 and 100.0MB\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x1008 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"models = [\"CMC\", \"GFS20\", \"NAM40\", \"RAP13\"]\n",
"parms = ['T','DpT','uW','vW']\n",
"\n",
"for modelName in models:\n",
" timeReq = DataAccessLayer.newDataRequest(\"grid\")\n",
" timeReq.setLocationNames(modelName)\n",
" cycles = DataAccessLayer.getAvailableTimes(timeReq, True)\n",
" times = DataAccessLayer.getAvailableTimes(timeReq)\n",
" fcstRun = DataAccessLayer.getForecastRun(cycles[-1], times)\n",
" print(\"Using \" + modelName + \" forecast time \" + str(fcstRun[0]))\n",
" \n",
" p,t,d,u,v = [],[],[],[],[]\n",
" use_parms = ['T','DpT','uW','vW','P']\n",
" use_level = \"0.0FHAG\"\n",
" \n",
" sndObject = ModelSounding.getSounding(modelName, use_parms, \n",
" [use_level], point, timeRange=[fcstRun[0]])\n",
" if len(sndObject) > 0:\n",
" for time in sndObject._dataDict:\n",
" p.append(float(sndObject._dataDict[time][use_level]['P']))\n",
" t.append(float(sndObject._dataDict[time][use_level]['T']))\n",
" d.append(float(sndObject._dataDict[time][use_level]['DpT']))\n",
" u.append(float(sndObject._dataDict[time][use_level]['uW']))\n",
" v.append(float(sndObject._dataDict[time][use_level]['vW']))\n",
" print(\"Found surface record at \" + \"%.1f\" % p[0] + \"MB\")\n",
" else:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (modelName, use_parms, point, use_level)) +\"]\")\n",
" \n",
" # Get isobaric levels with our requested parameters\n",
" levelReq = DataAccessLayer.newDataRequest(\"grid\", envelope=point)\n",
" levelReq.setLocationNames(modelName)\n",
" levelReq.setParameters('T','DpT','uW','vW')\n",
" availableLevels = DataAccessLayer.getAvailableLevels(levelReq)\n",
" # Clean levels list of unit string (MB, FHAG, etc.)\n",
" levels = []\n",
" for lvl in availableLevels:\n",
" name=str(lvl)\n",
" if 'MB' in name and '_' not in name:\n",
" # If this level is above (less than in mb) our 0.0FHAG record\n",
" if float(name.replace('MB','')) < p[0]:\n",
" levels.append(lvl)\n",
" \n",
" # Get Sounding\n",
" sndObject = ModelSounding.getSounding(modelName, parms, levels, point, \n",
" timeRange=[fcstRun[0]])\n",
" if not len(sndObject) > 0:\n",
" raise ValueError(\"sndObject returned empty for query [\" \n",
" + ', '.join(str(x) for x in (modelName, parms, point, levels)) +\"]\")\n",
" for time in sndObject._dataDict:\n",
" for lvl in sndObject._dataDict[time].levels():\n",
" for parm in sndObject._dataDict[time][lvl].parameters():\n",
" if parm == \"T\":\n",
" t.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == \"DpT\":\n",
" d.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'uW':\n",
" u.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" elif parm == 'vW':\n",
" v.append(float(sndObject._dataDict[time][lvl][parm]))\n",
" else:\n",
" print(\"WHAT IS THIS\")\n",
" print(sndObject._dataDict[time][lvl][parm])\n",
" # Pressure is our requested level rather than a returned parameter\n",
" p.append(float(lvl.replace('MB','')))\n",
"\n",
" # convert to numpy.array()\n",
" p = np.array(p, dtype=float)\n",
" t = (np.array(t, dtype=float) - 273.15) * units.degC\n",
" d = (np.array(d, dtype=float) - 273.15) * units.degC\n",
" u = (np.array(u, dtype=float) * units('m/s')).to('knots')\n",
" v = (np.array(v, dtype=float) * units('m/s')).to('knots')\n",
" w = np.sqrt(u**2 + v**2)\n",
"\n",
" print(\"Using \" + str(len(levels)) + \" levels between \" + \n",
" str(\"%.1f\" % max(p)) + \" and \" + str(\"%.1f\" % min(p)) + \"MB\")\n",
"\n",
" # Skew-T\n",
" plt.rcParams['figure.figsize'] = (12, 14)\n",
" skew = SkewT(rotation=45)\n",
" skew.plot(p, t, 'r', linewidth=2)\n",
" skew.plot(p, d, 'g', linewidth=2)\n",
" skew.plot_barbs(p, u, v)\n",
" skew.plot_dry_adiabats()\n",
" skew.plot_moist_adiabats()\n",
" skew.plot_mixing_lines(linestyle=':')\n",
" skew.ax.set_ylim(1000, 100)\n",
" skew.ax.set_xlim(-50, 40)\n",
" # Title\n",
" plt.title( modelName + \" (\" + str(point) + \") \" + str(time.getRefTime()))\n",
" # Hodograph\n",
" ax_hod = inset_axes(skew.ax, '40%', '40%', loc=2)\n",
" h = Hodograph(ax_hod, component_range=max(w.magnitude))\n",
" h.add_grid(increment=20)\n",
" h.plot_colormapped(u, v, w)\n",
" # Dotted line at 0C isotherm\n",
" l = skew.ax.axvline(0, color='c', linestyle='-', linewidth=1)\n",
" plt.show()"
]
2018-10-11 20:33:23 -06:00
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}