mirror of
https://github.com/Unidata/python-awips.git
synced 2025-02-23 22:57:56 -05:00
189 lines
1.1 MiB
Text
189 lines
1.1 MiB
Text
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"Based on the MetPy example [\"Station Plot with Layout\"](http://metpy.readthedocs.org/en/latest/examples/generated/Station_Plot_with_Layout.html)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 4,
|
||
|
"metadata": {
|
||
|
"collapsed": false,
|
||
|
"scrolled": true
|
||
|
},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"(Mar 15 16 22:52:00 , Mar 15 16 22:52:00 )\n",
|
||
|
"430\n",
|
||
|
"86\n"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"data": {
|
||
|
"image/png": "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\n0atvfKaFs6fZ1Ru+8Jp
|
||
|
"text/plain": [
|
||
|
"<matplotlib.figure.Figure at 0x7f56101be290>"
|
||
|
]
|
||
|
},
|
||
|
"metadata": {},
|
||
|
"output_type": "display_data"
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"import matplotlib.pyplot as plt\n",
|
||
|
"import numpy as np\n",
|
||
|
"\n",
|
||
|
"from metpy.calc import get_wind_components\n",
|
||
|
"from metpy.cbook import get_test_data\n",
|
||
|
"from metpy.plots import StationPlot, StationPlotLayout, simple_layout\n",
|
||
|
"from metpy.units import units\n",
|
||
|
"\n",
|
||
|
"# Initialize\n",
|
||
|
"data,latitude,longitude,stationName,temperature,dewpoint,seaLevelPress,windDir,windSpeed = [],[],[],[],[],[],[],[],[]\n",
|
||
|
"request = DataAccessLayer.newDataRequest()\n",
|
||
|
"request.setDatatype(\"obs\")\n",
|
||
|
"\n",
|
||
|
"#\n",
|
||
|
"# we need to set one station to query latest time. this is hack-y and should be fixed\n",
|
||
|
"# because when you DON'T set a location name, you tend to get a single observation\n",
|
||
|
"# that came in a second ago, so your \"latest data for the last time for all stations\"\n",
|
||
|
"# data array consists of one village in Peru and time-matching is suspect right now.\n",
|
||
|
"#\n",
|
||
|
"# So here take a known US station (OKC) and hope/assume that a lot of other stations \n",
|
||
|
"# are also reporting (and that this is a 00/20/40 ob). \n",
|
||
|
"#\n",
|
||
|
"request.setLocationNames(\"KOKC\")\n",
|
||
|
"datatimes = DataAccessLayer.getAvailableTimes(request)\n",
|
||
|
"\n",
|
||
|
"# Get most recent time for location\n",
|
||
|
"time = datatimes[-1].validPeriod\n",
|
||
|
"\n",
|
||
|
"# \"presWeather\",\"skyCover\",\"skyLayerBase\"\n",
|
||
|
"# are multi-dimensional(??) and returned seperately (not sure why yet)... deal with those later\n",
|
||
|
"request.setParameters(\"presWeather\",\"skyCover\", \"skyLayerBase\",\"stationName\",\"temperature\",\"dewpoint\",\"windDir\",\"windSpeed\",\n",
|
||
|
" \"seaLevelPress\",\"longitude\",\"latitude\")\n",
|
||
|
"request.setLocationNames()\n",
|
||
|
"response = DataAccessLayer.getGeometryData(request,times=time)\n",
|
||
|
"print time\n",
|
||
|
"PRES_PARAMS = set([\"presWeather\"])\n",
|
||
|
"SKY_PARAMS = set([\"skyCover\", \"skyLayerBase\"])\n",
|
||
|
"# Build ordered arrays\n",
|
||
|
"wx,cvr,bas=[],[],[]\n",
|
||
|
"for ob in response:\n",
|
||
|
" #print ob.getParameters()\n",
|
||
|
" if set(ob.getParameters()) & PRES_PARAMS :\n",
|
||
|
" wx.append(ob.getString(\"presWeather\"))\n",
|
||
|
" continue\n",
|
||
|
" if set(ob.getParameters()) & SKY_PARAMS :\n",
|
||
|
" cvr.append(ob.getString(\"skyCover\"))\n",
|
||
|
" bas.append(ob.getNumber(\"skyLayerBase\"))\n",
|
||
|
" continue\n",
|
||
|
" latitude.append(float(ob.getString(\"latitude\")))\n",
|
||
|
" longitude.append(float(ob.getString(\"longitude\")))\n",
|
||
|
" #stationName.append(ob.getString(\"stationName\"))\n",
|
||
|
" temperature.append(float(ob.getString(\"temperature\")))\n",
|
||
|
" dewpoint.append(float(ob.getString(\"dewpoint\")))\n",
|
||
|
" seaLevelPress.append(float(ob.getString(\"seaLevelPress\")))\n",
|
||
|
" windDir.append(float(ob.getString(\"windDir\")))\n",
|
||
|
" windSpeed.append(float(ob.getString(\"windSpeed\")))\n",
|
||
|
" \n",
|
||
|
" \n",
|
||
|
"print len(wx)\n",
|
||
|
"print len(temperature)\n",
|
||
|
"\n",
|
||
|
"\n",
|
||
|
"# Convert\n",
|
||
|
"data = dict()\n",
|
||
|
"data['latitude'] = np.array(latitude)\n",
|
||
|
"data['longitude'] = np.array(longitude)\n",
|
||
|
"data['air_temperature'] = np.array(temperature)* units.degC\n",
|
||
|
"data['dew_point_temperature'] = np.array(dewpoint)* units.degC\n",
|
||
|
"#data['air_pressure_at_sea_level'] = np.array(seaLevelPress)* units('mbar')\n",
|
||
|
"u, v = get_wind_components(np.array(windSpeed) * units('knots'),\n",
|
||
|
" np.array(windDir) * units.degree)\n",
|
||
|
"data['eastward_wind'], data['northward_wind'] = u, v\n",
|
||
|
"\n",
|
||
|
"# Convert the fraction value into a code of 0-8, which can be used to pull out\n",
|
||
|
"# the appropriate symbol\n",
|
||
|
"#data['cloud_coverage'] = (8 * data_arr['cloud_fraction']).astype(int)\n",
|
||
|
"\n",
|
||
|
"# Map weather strings to WMO codes, which we can use to convert to symbols\n",
|
||
|
"# Only use the first symbol if there are multiple\n",
|
||
|
"#wx_text = make_string_list(data_arr['weather'])\n",
|
||
|
"#wx_codes = {'':0, 'HZ':5, 'BR':10, '-DZ':51, 'DZ':53, '+DZ':55,\n",
|
||
|
"# '-RA':61, 'RA':63, '+RA':65, '-SN':71, 'SN':73, '+SN':75}\n",
|
||
|
"#data['present_weather'] = [wx_codes[s.split()[0] if ' ' in s else s] for s in wx]\n",
|
||
|
"\n",
|
||
|
"# Set up the map projection\n",
|
||
|
"import cartopy.crs as ccrs\n",
|
||
|
"import cartopy.feature as feat\n",
|
||
|
"from matplotlib import rcParams\n",
|
||
|
"rcParams['savefig.dpi'] = 255\n",
|
||
|
"proj = ccrs.LambertConformal(central_longitude=-95, central_latitude=35,\n",
|
||
|
" standard_parallels=[35])\n",
|
||
|
"state_boundaries = feat.NaturalEarthFeature(category='cultural',\n",
|
||
|
" name='admin_1_states_provinces_lines',\n",
|
||
|
" scale='110m', facecolor='none')\n",
|
||
|
"# Create the figure\n",
|
||
|
"fig = plt.figure(figsize=(20, 10))\n",
|
||
|
"ax = fig.add_subplot(1, 1, 1, projection=proj)\n",
|
||
|
"\n",
|
||
|
"# Add map elements \n",
|
||
|
"ax.add_feature(feat.LAND, zorder=-1)\n",
|
||
|
"ax.add_feature(feat.OCEAN, zorder=-1)\n",
|
||
|
"ax.add_feature(feat.LAKES, zorder=-1)\n",
|
||
|
"ax.coastlines(resolution='110m', zorder=2, color='black')\n",
|
||
|
"ax.add_feature(state_boundaries)\n",
|
||
|
"ax.add_feature(feat.BORDERS, linewidth='2', edgecolor='black')\n",
|
||
|
"ax.set_extent((-118, -73, 23, 50))\n",
|
||
|
"\n",
|
||
|
"# Start the station plot by specifying the axes to draw on, as well as the\n",
|
||
|
"# lon/lat of the stations (with transform). We also the fontsize to 12 pt.\n",
|
||
|
"stationplot = StationPlot(ax, data['longitude'], data['latitude'],\n",
|
||
|
" transform=ccrs.PlateCarree(), fontsize=12)\n",
|
||
|
"\n",
|
||
|
"# The layout knows where everything should go, and things are standardized using\n",
|
||
|
"# the names of variables. So the layout pulls arrays out of `data` and plots them\n",
|
||
|
"# using `stationplot`.\n",
|
||
|
"simple_layout.plot(stationplot, data)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": null,
|
||
|
"metadata": {
|
||
|
"collapsed": true
|
||
|
},
|
||
|
"outputs": [],
|
||
|
"source": []
|
||
|
}
|
||
|
],
|
||
|
"metadata": {
|
||
|
"kernelspec": {
|
||
|
"display_name": "Python 2",
|
||
|
"language": "python",
|
||
|
"name": "python2"
|
||
|
},
|
||
|
"language_info": {
|
||
|
"codemirror_mode": {
|
||
|
"name": "ipython",
|
||
|
"version": 2
|
||
|
},
|
||
|
"file_extension": ".py",
|
||
|
"mimetype": "text/x-python",
|
||
|
"name": "python",
|
||
|
"nbconvert_exporter": "python",
|
||
|
"pygments_lexer": "ipython2",
|
||
|
"version": "2.7.9"
|
||
|
}
|
||
|
},
|
||
|
"nbformat": 4,
|
||
|
"nbformat_minor": 0
|
||
|
}
|