forked from 3rdparty/wrf-python
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							823 lines
						
					
					
						
							30 KiB
						
					
					
				
			
		
		
	
	
							823 lines
						
					
					
						
							30 KiB
						
					
					
				Plotting Examples | 
						|
================= | 
						|
 | 
						|
The examples below show how wrf-python can be used to make plots with  | 
						|
matplotlib (with basemap and cartopy) and PyNGL.  None of these examples  | 
						|
make use of xarray's builtin plotting functions, since additional work is most | 
						|
likely needed to extend xarray in order to work correctly.  This is planned  | 
						|
for a future release. | 
						|
 | 
						|
A subset of the wrfout file used in these examples can be downloaded `here <https://doi.org/10.5065/yd8c-hm41>`_. | 
						|
 | 
						|
Matplotlib With Cartopy | 
						|
------------------------- | 
						|
 | 
						|
Cartopy is becoming the main tool for base mapping with matplotlib, but you  | 
						|
should  be aware of a few shortcomings when working with WRF data. | 
						|
 | 
						|
- The builtin transformations of coordinates when calling the contouring  | 
						|
  functions do not work correctly with the rotated pole projection.  The  | 
						|
  transform_points method needs to be called manually on the latitude and  | 
						|
  longitude arrays. | 
						|
   | 
						|
- The rotated pole projection requires the x and y limits to be set manually | 
						|
  using set_xlim and set_ylim. | 
						|
 | 
						|
- You can't place latitude and longitude labels on the axes when using  | 
						|
  any projection other than Mercator or LatLon. | 
						|
 | 
						|
 | 
						|
Plotting a Two-dimensional Field | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
.. image:: _static/images/cartopy_slp.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
    | 
						|
.. code-block:: python | 
						|
     | 
						|
    from netCDF4 import Dataset    | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    import cartopy.crs as crs | 
						|
    from cartopy.feature import NaturalEarthFeature | 
						|
     | 
						|
    from wrf import (to_np, getvar, smooth2d, get_cartopy, cartopy_xlim,  | 
						|
                     cartopy_ylim, latlon_coords) | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Get the sea level pressure | 
						|
    slp = getvar(ncfile, "slp") | 
						|
     | 
						|
    # Smooth the sea level pressure since it tends to be noisy near the  | 
						|
    # mountains | 
						|
    smooth_slp = smooth2d(slp, 3, cenweight=4) | 
						|
     | 
						|
    # Get the latitude and longitude points | 
						|
    lats, lons = latlon_coords(slp) | 
						|
     | 
						|
    # Get the cartopy mapping object | 
						|
    cart_proj = get_cartopy(slp) | 
						|
     | 
						|
    # Create a figure | 
						|
    fig = plt.figure(figsize=(12,6)) | 
						|
    # Set the GeoAxes to the projection used by WRF | 
						|
    ax = plt.axes(projection=cart_proj) | 
						|
     | 
						|
    # Download and add the states and coastlines | 
						|
    states = NaturalEarthFeature(category="cultural", scale="50m",  | 
						|
                                 facecolor="none", | 
						|
                                 name="admin_1_states_provinces_shp") | 
						|
    ax.add_feature(states, linewidth=.5, edgecolor="black") | 
						|
    ax.coastlines('50m', linewidth=0.8) | 
						|
     | 
						|
    # Make the contour outlines and filled contours for the smoothed sea level  | 
						|
    # pressure. | 
						|
    plt.contour(to_np(lons), to_np(lats), to_np(smooth_slp), 10, colors="black",  | 
						|
                transform=crs.PlateCarree()) | 
						|
    plt.contourf(to_np(lons), to_np(lats), to_np(smooth_slp), 10,  | 
						|
                 transform=crs.PlateCarree(),  | 
						|
                 cmap=get_cmap("jet")) | 
						|
     | 
						|
    # Add a color bar | 
						|
    plt.colorbar(ax=ax, shrink=.98) | 
						|
     | 
						|
    # Set the map bounds | 
						|
    ax.set_xlim(cartopy_xlim(smooth_slp)) | 
						|
    ax.set_ylim(cartopy_ylim(smooth_slp)) | 
						|
     | 
						|
    # Add the gridlines | 
						|
    ax.gridlines(color="black", linestyle="dotted") | 
						|
 | 
						|
    plt.title("Sea Level Pressure (hPa)") | 
						|
 | 
						|
    plt.show() | 
						|
 | 
						|
 | 
						|
Horizontal Interpolation to a Pressure Level | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
.. image:: _static/images/cartopy_500.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
     | 
						|
.. code-block:: python | 
						|
 | 
						|
    from netCDF4 import Dataset  | 
						|
    import numpy as np | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    import cartopy.crs as crs | 
						|
    from cartopy.feature import NaturalEarthFeature | 
						|
     | 
						|
    from wrf import (getvar, interplevel, to_np, latlon_coords, get_cartopy,  | 
						|
                     cartopy_xlim, cartopy_ylim) | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Extract the pressure, geopotential height, and wind variables | 
						|
    p = getvar(ncfile, "pressure") | 
						|
    z = getvar(ncfile, "z", units="dm") | 
						|
    ua = getvar(ncfile, "ua", units="kt") | 
						|
    va = getvar(ncfile, "va", units="kt") | 
						|
    wspd = getvar(ncfile, "wspd_wdir", units="kts")[0,:] | 
						|
     | 
						|
    # Interpolate geopotential height, u, and v winds to 500 hPa  | 
						|
    ht_500 = interplevel(z, p, 500) | 
						|
    u_500 = interplevel(ua, p, 500) | 
						|
    v_500 = interplevel(va, p, 500) | 
						|
    wspd_500 = interplevel(wspd, p, 500) | 
						|
     | 
						|
    # Get the lat/lon coordinates | 
						|
    lats, lons = latlon_coords(ht_500) | 
						|
     | 
						|
    # Get the map projection information | 
						|
    cart_proj = get_cartopy(ht_500) | 
						|
     | 
						|
    # Create the figure | 
						|
    fig = plt.figure(figsize=(12,9)) | 
						|
    ax = plt.axes(projection=cart_proj) | 
						|
     | 
						|
    # Download and add the states and coastlines | 
						|
    states = NaturalEarthFeature(category="cultural", scale="50m",  | 
						|
                                 facecolor="none", | 
						|
                                 name="admin_1_states_provinces_shp") | 
						|
    ax.add_feature(states, linewidth=0.5, edgecolor="black") | 
						|
    ax.coastlines('50m', linewidth=0.8) | 
						|
     | 
						|
    # Add the 500 hPa geopotential height contours | 
						|
    levels = np.arange(520., 580., 6.) | 
						|
    contours = plt.contour(to_np(lons), to_np(lats), to_np(ht_500),  | 
						|
                           levels=levels, colors="black",  | 
						|
                           transform=crs.PlateCarree()) | 
						|
    plt.clabel(contours, inline=1, fontsize=10, fmt="%i") | 
						|
     | 
						|
    # Add the wind speed contours | 
						|
    levels = [25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 110, 120] | 
						|
    wspd_contours = plt.contourf(to_np(lons), to_np(lats), to_np(wspd_500),  | 
						|
                                 levels=levels, | 
						|
                                 cmap=get_cmap("rainbow"),  | 
						|
                                 transform=crs.PlateCarree()) | 
						|
    plt.colorbar(wspd_contours, ax=ax, orientation="horizontal", pad=.05) | 
						|
     | 
						|
    # Add the 500 hPa wind barbs, only plotting every 125th data point. | 
						|
    plt.barbs(to_np(lons[::125,::125]), to_np(lats[::125,::125]),  | 
						|
              to_np(u_500[::125, ::125]), to_np(v_500[::125, ::125]),  | 
						|
              transform=crs.PlateCarree(), length=6) | 
						|
     | 
						|
    # Set the map bounds | 
						|
    ax.set_xlim(cartopy_xlim(ht_500)) | 
						|
    ax.set_ylim(cartopy_ylim(ht_500)) | 
						|
     | 
						|
    ax.gridlines() | 
						|
     | 
						|
    plt.title("500 MB Height (dm), Wind Speed (kt), Barbs (kt)") | 
						|
     | 
						|
    plt.show() | 
						|
     | 
						|
 | 
						|
Panel Plots From Front Page | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
This lengthy example shows how to make the panel plots on the first page  | 
						|
of the documentation.  For a simpler example of how to make a cross section  | 
						|
plot, see :ref:`cross_example`. | 
						|
 | 
						|
.. image:: _static/images/matthew.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
 | 
						|
    import numpy as np | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    import cartopy.crs as crs | 
						|
    import cartopy.feature as cfeature | 
						|
    from netCDF4 import Dataset | 
						|
     | 
						|
    from wrf import (getvar, to_np, vertcross, smooth2d, CoordPair, GeoBounds,  | 
						|
                     get_cartopy, latlon_coords, cartopy_xlim, cartopy_ylim) | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Get the WRF variables | 
						|
    slp = getvar(ncfile, "slp") | 
						|
    smooth_slp = smooth2d(slp, 3) | 
						|
    ctt = getvar(ncfile, "ctt") | 
						|
    z = getvar(ncfile, "z") | 
						|
    dbz = getvar(ncfile, "dbz") | 
						|
    Z = 10**(dbz/10.) | 
						|
    wspd =  getvar(ncfile, "wspd_wdir", units="kt")[0,:] | 
						|
     | 
						|
    # Set the start point and end point for the cross section | 
						|
    start_point = CoordPair(lat=26.76, lon=-80.0) | 
						|
    end_point = CoordPair(lat=26.76, lon=-77.8) | 
						|
     | 
						|
    # Compute the vertical cross-section interpolation.  Also, include the  | 
						|
    # lat/lon points along the cross-section in the metadata by setting latlon  | 
						|
    # to True. | 
						|
    z_cross = vertcross(Z, z, wrfin=ncfile, start_point=start_point,  | 
						|
                        end_point=end_point, latlon=True, meta=True) | 
						|
    wspd_cross = vertcross(wspd, z, wrfin=ncfile, start_point=start_point,  | 
						|
                           end_point=end_point, latlon=True, meta=True) | 
						|
    dbz_cross = 10.0 * np.log10(z_cross) | 
						|
     | 
						|
    # Get the lat/lon points | 
						|
    lats, lons = latlon_coords(slp) | 
						|
     | 
						|
    # Get the cartopy projection object | 
						|
    cart_proj = get_cartopy(slp) | 
						|
     | 
						|
    # Create a figure that will have 3 subplots | 
						|
    fig = plt.figure(figsize=(12,9)) | 
						|
    ax_ctt = fig.add_subplot(1,2,1,projection=cart_proj) | 
						|
    ax_wspd = fig.add_subplot(2,2,2) | 
						|
    ax_dbz = fig.add_subplot(2,2,4) | 
						|
     | 
						|
    # Download and create the states, land, and oceans using cartopy features | 
						|
    states = cfeature.NaturalEarthFeature(category='cultural', scale='50m',  | 
						|
                                          facecolor='none', | 
						|
                                          name='admin_1_states_provinces_shp') | 
						|
    land = cfeature.NaturalEarthFeature(category='physical', name='land',  | 
						|
                                        scale='50m',  | 
						|
                                        facecolor=cfeature.COLORS['land']) | 
						|
    ocean = cfeature.NaturalEarthFeature(category='physical', name='ocean',  | 
						|
                                         scale='50m',  | 
						|
                                         facecolor=cfeature.COLORS['water']) | 
						|
     | 
						|
    # Make the pressure contours | 
						|
    contour_levels = [960, 965, 970, 975, 980, 990] | 
						|
    c1 = ax_ctt.contour(lons, lats, to_np(smooth_slp), levels=contour_levels,  | 
						|
                        colors="white", transform=crs.PlateCarree(), zorder=3,  | 
						|
                        linewidths=1.0) | 
						|
     | 
						|
    # Create the filled cloud top temperature contours | 
						|
    contour_levels = [-80.0, -70.0, -60, -50, -40, -30, -20, -10, 0, 10] | 
						|
    ctt_contours = ax_ctt.contourf(to_np(lons), to_np(lats), to_np(ctt),  | 
						|
                                   contour_levels, cmap=get_cmap("Greys"),  | 
						|
                                   transform=crs.PlateCarree(), zorder=2) | 
						|
     | 
						|
    ax_ctt.plot([start_point.lon, end_point.lon],  | 
						|
                [start_point.lat, end_point.lat], color="yellow", marker="o",  | 
						|
                transform=crs.PlateCarree(), zorder=3) | 
						|
     | 
						|
    # Create the color bar for cloud top temperature | 
						|
    cb_ctt = fig.colorbar(ctt_contours, ax=ax_ctt, shrink=.60) | 
						|
    cb_ctt.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Draw the oceans, land, and states | 
						|
    ax_ctt.add_feature(ocean) | 
						|
    ax_ctt.add_feature(land) | 
						|
    ax_ctt.add_feature(states, linewidth=.5, edgecolor="black") | 
						|
     | 
						|
    # Crop the domain to the region around the hurricane | 
						|
    hur_bounds = GeoBounds(CoordPair(lat=np.amin(to_np(lats)), lon=-85.0), | 
						|
                           CoordPair(lat=30.0, lon=-72.0)) | 
						|
    ax_ctt.set_xlim(cartopy_xlim(ctt, geobounds=hur_bounds)) | 
						|
    ax_ctt.set_ylim(cartopy_ylim(ctt, geobounds=hur_bounds)) | 
						|
    ax_ctt.gridlines(color="white", linestyle="dotted") | 
						|
     | 
						|
    # Make the contour plot for wind speed | 
						|
    wspd_contours = ax_wspd.contourf(to_np(wspd_cross), cmap=get_cmap("jet")) | 
						|
    # Add the color bar | 
						|
    cb_wspd = fig.colorbar(wspd_contours, ax=ax_wspd) | 
						|
    cb_wspd.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Make the contour plot for dbz | 
						|
    levels = [5 + 5*n for n in range(15)] | 
						|
    dbz_contours = ax_dbz.contourf(to_np(dbz_cross), levels=levels,  | 
						|
                                   cmap=get_cmap("jet")) | 
						|
    cb_dbz = fig.colorbar(dbz_contours, ax=ax_dbz) | 
						|
    cb_dbz.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Set the x-ticks to use latitude and longitude labels | 
						|
    coord_pairs = to_np(dbz_cross.coords["xy_loc"]) | 
						|
    x_ticks = np.arange(coord_pairs.shape[0]) | 
						|
    x_labels = [pair.latlon_str() for pair in to_np(coord_pairs)] | 
						|
    ax_wspd.set_xticks(x_ticks[::20]) | 
						|
    ax_wspd.set_xticklabels([], rotation=45) | 
						|
    ax_dbz.set_xticks(x_ticks[::20]) | 
						|
    ax_dbz.set_xticklabels(x_labels[::20], rotation=45, fontsize=4)  | 
						|
     | 
						|
    # Set the y-ticks to be height | 
						|
    vert_vals = to_np(dbz_cross.coords["vertical"]) | 
						|
    v_ticks = np.arange(vert_vals.shape[0]) | 
						|
    ax_wspd.set_yticks(v_ticks[::20]) | 
						|
    ax_wspd.set_yticklabels(vert_vals[::20], fontsize=4)  | 
						|
    ax_dbz.set_yticks(v_ticks[::20]) | 
						|
    ax_dbz.set_yticklabels(vert_vals[::20], fontsize=4)  | 
						|
     | 
						|
    # Set the x-axis and  y-axis labels | 
						|
    ax_dbz.set_xlabel("Latitude, Longitude", fontsize=5) | 
						|
    ax_wspd.set_ylabel("Height (m)", fontsize=5) | 
						|
    ax_dbz.set_ylabel("Height (m)", fontsize=5) | 
						|
     | 
						|
    # Add a title | 
						|
    ax_ctt.set_title("Cloud Top Temperature (degC)", {"fontsize" : 7}) | 
						|
    ax_wspd.set_title("Cross-Section of Wind Speed (kt)", {"fontsize" : 7}) | 
						|
    ax_dbz.set_title("Cross-Section of Reflectivity (dBZ)", {"fontsize" : 7}) | 
						|
     | 
						|
    plt.show() | 
						|
 | 
						|
 | 
						|
Matplotlib with Basemap | 
						|
----------------------- | 
						|
 | 
						|
Although basemap is in maintenance mode only and becoming deprecated, it is  | 
						|
still widely used by many programmers.  Cartopy is becoming the preferred  | 
						|
package for mapping, however it suffers from growing pains in some areas  | 
						|
(can't use latitude/longitude labels for many map projections).  If you  | 
						|
run in to these issues, basemap is likely to accomplish what you need. | 
						|
 | 
						|
 | 
						|
Plotting a Two-Dimensional Field | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
.. image:: _static/images/basemap_slp.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
     | 
						|
    from netCDF4 import Dataset    | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    from mpl_toolkits.basemap import Basemap | 
						|
     | 
						|
    from wrf import to_np, getvar, smooth2d, get_basemap, latlon_coords | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Get the sea level pressure | 
						|
    slp = getvar(ncfile, "slp") | 
						|
     | 
						|
    # Smooth the sea level pressure since it tends to be noisy near the  | 
						|
    # mountains | 
						|
    smooth_slp = smooth2d(slp, 3, cenweight=4) | 
						|
     | 
						|
    # Get the latitude and longitude points | 
						|
    lats, lons = latlon_coords(slp) | 
						|
     | 
						|
    # Get the basemap object | 
						|
    bm = get_basemap(slp) | 
						|
     | 
						|
    # Create a figure | 
						|
    fig = plt.figure(figsize=(12,9)) | 
						|
     | 
						|
    # Add geographic outlines | 
						|
    bm.drawcoastlines(linewidth=0.25) | 
						|
    bm.drawstates(linewidth=0.25) | 
						|
    bm.drawcountries(linewidth=0.25) | 
						|
     | 
						|
    # Convert the lats and lons to x and y.  Make sure you convert the lats and  | 
						|
    # lons to numpy arrays via to_np, or basemap crashes with an undefined  | 
						|
    # RuntimeError. | 
						|
    x, y = bm(to_np(lons), to_np(lats)) | 
						|
     | 
						|
    # Draw the contours and filled contours | 
						|
    bm.contour(x, y, to_np(smooth_slp), 10, colors="black") | 
						|
    bm.contourf(x, y, to_np(smooth_slp), 10, cmap=get_cmap("jet")) | 
						|
     | 
						|
    # Add a color bar | 
						|
    plt.colorbar(shrink=.62) | 
						|
     | 
						|
    plt.title("Sea Level Pressure (hPa)") | 
						|
     | 
						|
    plt.show() | 
						|
     | 
						|
 | 
						|
Horizontal Interpolation to a Pressure Level | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
.. image:: _static/images/basemap_500.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
 | 
						|
    from netCDF4 import Dataset  | 
						|
    import numpy as np | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
     | 
						|
    from wrf import getvar, interplevel, to_np, get_basemap, latlon_coords | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Extract the pressure, geopotential height, and wind variables | 
						|
    p = getvar(ncfile, "pressure") | 
						|
    z = getvar(ncfile, "z", units="dm") | 
						|
    ua = getvar(ncfile, "ua", units="kt") | 
						|
    va = getvar(ncfile, "va", units="kt") | 
						|
    wspd = getvar(ncfile, "wspd_wdir", units="kts")[0,:] | 
						|
     | 
						|
    # Interpolate geopotential height, u, and v winds to 500 hPa  | 
						|
    ht_500 = interplevel(z, p, 500) | 
						|
    u_500 = interplevel(ua, p, 500) | 
						|
    v_500 = interplevel(va, p, 500) | 
						|
    wspd_500 = interplevel(wspd, p, 500) | 
						|
     | 
						|
    # Get the lat/lon coordinates | 
						|
    lats, lons = latlon_coords(ht_500) | 
						|
     | 
						|
    # Get the basemap object | 
						|
    bm = get_basemap(ht_500) | 
						|
     | 
						|
    # Create the figure | 
						|
    fig = plt.figure(figsize=(12,9)) | 
						|
    ax = plt.axes() | 
						|
     | 
						|
    # Convert the lat/lon coordinates to x/y coordinates in the projection space | 
						|
    x, y = bm(to_np(lons), to_np(lats)) | 
						|
     | 
						|
    # Add the 500 hPa geopotential height contours | 
						|
    levels = np.arange(520., 580., 6.) | 
						|
    contours = bm.contour(x, y, to_np(ht_500), levels=levels, colors="black") | 
						|
    plt.clabel(contours, inline=1, fontsize=10, fmt="%i") | 
						|
     | 
						|
    # Add the wind speed contours | 
						|
    levels = [25, 30, 35, 40, 50, 60, 70, 80, 90, 100, 110, 120] | 
						|
    wspd_contours = bm.contourf(x, y, to_np(wspd_500), levels=levels, | 
						|
                                cmap=get_cmap("rainbow")) | 
						|
    plt.colorbar(wspd_contours, ax=ax, orientation="horizontal", pad=.05) | 
						|
     | 
						|
    # Add the geographic boundaries | 
						|
    bm.drawcoastlines(linewidth=0.25) | 
						|
    bm.drawstates(linewidth=0.25) | 
						|
    bm.drawcountries(linewidth=0.25) | 
						|
     | 
						|
    # Add the 500 hPa wind barbs, only plotting every 125th data point. | 
						|
    bm.barbs(x[::125,::125], y[::125,::125], to_np(u_500[::125, ::125]),  | 
						|
             to_np(v_500[::125, ::125]), length=6) | 
						|
     | 
						|
    plt.title("500 MB Height (dm), Wind Speed (kt), Barbs (kt)") | 
						|
     | 
						|
    plt.show() | 
						|
     | 
						|
     | 
						|
Panel Plots from the Front Page | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
This lengthy example shows how to make the panel plots on the first page  | 
						|
of the documentation.  For a simpler example of how to make a cross section  | 
						|
plot, see :ref:`cross_example`. | 
						|
 | 
						|
.. image:: _static/images/basemap_front.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
 | 
						|
    import numpy as np | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    from netCDF4 import Dataset | 
						|
     | 
						|
    from wrf import (getvar, to_np, vertcross, smooth2d, CoordPair,  | 
						|
                     get_basemap, latlon_coords) | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    ncfile = Dataset("wrfout_d01_2016-10-07_00_00_00") | 
						|
     | 
						|
    # Get the WRF variables | 
						|
    slp = getvar(ncfile, "slp") | 
						|
    smooth_slp = smooth2d(slp, 3) | 
						|
    ctt = getvar(ncfile, "ctt") | 
						|
    z = getvar(ncfile, "z") | 
						|
    dbz = getvar(ncfile, "dbz") | 
						|
    Z = 10**(dbz/10.) | 
						|
    wspd =  getvar(ncfile, "wspd_wdir", units="kt")[0,:] | 
						|
     | 
						|
    # Set the start point and end point for the cross section | 
						|
    start_point = CoordPair(lat=26.76, lon=-80.0) | 
						|
    end_point = CoordPair(lat=26.76, lon=-77.8) | 
						|
     | 
						|
    # Compute the vertical cross-section interpolation.  Also, include the  | 
						|
    # lat/lon points along the cross-section in the metadata by setting latlon  | 
						|
    # to True. | 
						|
    z_cross = vertcross(Z, z, wrfin=ncfile, start_point=start_point,  | 
						|
                        end_point=end_point, latlon=True, meta=True) | 
						|
    wspd_cross = vertcross(wspd, z, wrfin=ncfile, start_point=start_point,  | 
						|
                           end_point=end_point, latlon=True, meta=True) | 
						|
    dbz_cross = 10.0 * np.log10(z_cross) | 
						|
     | 
						|
    # Get the latitude and longitude points | 
						|
    lats, lons = latlon_coords(slp) | 
						|
     | 
						|
    # Create the figure that will have 3 subplots | 
						|
    fig = plt.figure(figsize=(12,9)) | 
						|
    ax_ctt = fig.add_subplot(1,2,1) | 
						|
    ax_wspd = fig.add_subplot(2,2,2) | 
						|
    ax_dbz = fig.add_subplot(2,2,4) | 
						|
     | 
						|
    # Get the basemap object | 
						|
    bm = get_basemap(slp) | 
						|
     | 
						|
    # Convert the lat/lon points in to x/y points in the projection space | 
						|
    x, y = bm(to_np(lons), to_np(lats)) | 
						|
     | 
						|
    # Make the pressure contours | 
						|
    contour_levels = [960, 965, 970, 975, 980, 990] | 
						|
    c1 = bm.contour(x, y, to_np(smooth_slp), levels=contour_levels,  | 
						|
                    colors="white", zorder=3, linewidths=1.0, ax=ax_ctt) | 
						|
     | 
						|
    # Create the filled cloud top temperature contours | 
						|
    contour_levels = [-80.0, -70.0, -60, -50, -40, -30, -20, -10, 0, 10] | 
						|
    ctt_contours = bm.contourf(x, y, to_np(ctt), contour_levels,  | 
						|
                               cmap=get_cmap("Greys"), zorder=2, ax=ax_ctt) | 
						|
     | 
						|
    point_x, point_y = bm([start_point.lon, end_point.lon],  | 
						|
                          [start_point.lat, end_point.lat]) | 
						|
    bm.plot([point_x[0], point_x[1]], [point_y[0], point_y[1]], color="yellow",  | 
						|
            marker="o", zorder=3, ax=ax_ctt) | 
						|
     | 
						|
    # Create the color bar for cloud top temperature | 
						|
    cb_ctt = fig.colorbar(ctt_contours, ax=ax_ctt, shrink=.60) | 
						|
    cb_ctt.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Draw the oceans, land, and states | 
						|
    bm.drawcoastlines(linewidth=0.25, ax=ax_ctt) | 
						|
    bm.drawstates(linewidth=0.25, ax=ax_ctt) | 
						|
    bm.drawcountries(linewidth=0.25, ax=ax_ctt) | 
						|
    bm.fillcontinents(color=np.array([ 0.9375 , 0.9375 , 0.859375]),  | 
						|
                                     ax=ax_ctt,  | 
						|
                                     lake_color=np.array([0.59375 ,  | 
						|
                                                          0.71484375,  | 
						|
                                                          0.8828125 ])) | 
						|
    bm.drawmapboundary(fill_color=np.array([ 0.59375 , 0.71484375, 0.8828125 ]),  | 
						|
                       ax=ax_ctt) | 
						|
     | 
						|
    # Draw Parallels | 
						|
    parallels = np.arange(np.amin(lats), 30., 2.5) | 
						|
    bm.drawparallels(parallels, ax=ax_ctt, color="white") | 
						|
     | 
						|
    merids = np.arange(-85.0, -72.0, 2.5) | 
						|
    bm.drawmeridians(merids, ax=ax_ctt, color="white") | 
						|
     | 
						|
    # Crop the image to the hurricane region | 
						|
    x_start, y_start = bm(-85.0, np.amin(lats)) | 
						|
    x_end, y_end = bm(-72.0, 30.0) | 
						|
     | 
						|
    ax_ctt.set_xlim([x_start, x_end]) | 
						|
    ax_ctt.set_ylim([y_start, y_end]) | 
						|
     | 
						|
    # Make the contour plot for wspd | 
						|
    wspd_contours = ax_wspd.contourf(to_np(wspd_cross), cmap=get_cmap("jet")) | 
						|
    # Add the color bar | 
						|
    cb_wspd = fig.colorbar(wspd_contours, ax=ax_wspd) | 
						|
    cb_wspd.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Make the contour plot for dbz | 
						|
    levels = [5 + 5*n for n in range(15)] | 
						|
    dbz_contours = ax_dbz.contourf(to_np(dbz_cross), levels=levels,  | 
						|
                                   cmap=get_cmap("jet")) | 
						|
    cb_dbz = fig.colorbar(dbz_contours, ax=ax_dbz) | 
						|
    cb_dbz.ax.tick_params(labelsize=5) | 
						|
     | 
						|
    # Set the x-ticks to use latitude and longitude labels. | 
						|
    coord_pairs = to_np(dbz_cross.coords["xy_loc"]) | 
						|
    x_ticks = np.arange(coord_pairs.shape[0]) | 
						|
    x_labels = [pair.latlon_str() for pair in to_np(coord_pairs)] | 
						|
    ax_wspd.set_xticks(x_ticks[::20]) | 
						|
    ax_wspd.set_xticklabels([], rotation=45) | 
						|
    ax_dbz.set_xticks(x_ticks[::20]) | 
						|
    ax_dbz.set_xticklabels(x_labels[::20], rotation=45, fontsize=4)  | 
						|
     | 
						|
    # Set the y-ticks to be height. | 
						|
    vert_vals = to_np(dbz_cross.coords["vertical"]) | 
						|
    v_ticks = np.arange(vert_vals.shape[0]) | 
						|
    ax_wspd.set_yticks(v_ticks[::20]) | 
						|
    ax_wspd.set_yticklabels(vert_vals[::20], fontsize=4)  | 
						|
    ax_dbz.set_yticks(v_ticks[::20]) | 
						|
    ax_dbz.set_yticklabels(vert_vals[::20], fontsize=4)  | 
						|
     | 
						|
    # Set the x-axis and  y-axis labels | 
						|
    ax_dbz.set_xlabel("Latitude, Longitude", fontsize=5) | 
						|
    ax_wspd.set_ylabel("Height (m)", fontsize=5) | 
						|
    ax_dbz.set_ylabel("Height (m)", fontsize=5) | 
						|
     | 
						|
    # Add titles | 
						|
    ax_ctt.set_title("Cloud Top Temperature (degC)", {"fontsize" : 7}) | 
						|
    ax_wspd.set_title("Cross-Section of Wind Speed (kt)", {"fontsize" : 7}) | 
						|
    ax_dbz.set_title("Cross-Section of Reflectivity (dBZ)", {"fontsize" : 7}) | 
						|
     | 
						|
    plt.show() | 
						|
     | 
						|
     | 
						|
.. _cross_example: | 
						|
 | 
						|
 | 
						|
Vertical Cross Section | 
						|
------------------------------- | 
						|
 | 
						|
Vertical cross sections require no mapping software package and can be  | 
						|
plotted using the standard matplotlib API. | 
						|
 | 
						|
.. image:: _static/images/cartopy_cross.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
 | 
						|
    import numpy as np | 
						|
    import matplotlib.pyplot as plt | 
						|
    from matplotlib.cm import get_cmap | 
						|
    import cartopy.crs as crs | 
						|
    from cartopy.feature import NaturalEarthFeature | 
						|
    from netCDF4 import Dataset | 
						|
     | 
						|
    from wrf import to_np, getvar, CoordPair, vertcross | 
						|
     | 
						|
    # Open the NetCDF file | 
						|
    filename = "wrfout_d01_2016-10-07_00_00_00" | 
						|
    ncfile = Dataset(filename) | 
						|
     | 
						|
    # Extract the model height and wind speed | 
						|
    z = getvar(ncfile, "z") | 
						|
    wspd =  getvar(ncfile, "uvmet_wspd_wdir", units="kt")[0,:] | 
						|
     | 
						|
    # Create the start point and end point for the cross section | 
						|
    start_point = CoordPair(lat=26.76, lon=-80.0) | 
						|
    end_point = CoordPair(lat=26.76, lon=-77.8) | 
						|
     | 
						|
    # Compute the vertical cross-section interpolation.  Also, include the  | 
						|
    # lat/lon points along the cross-section. | 
						|
    wspd_cross = vertcross(wspd, z, wrfin=ncfile, start_point=start_point,  | 
						|
                           end_point=end_point, latlon=True, meta=True) | 
						|
     | 
						|
    # Create the figure | 
						|
    fig = plt.figure(figsize=(12,6)) | 
						|
    ax = plt.axes() | 
						|
     | 
						|
    # Make the contour plot | 
						|
    wspd_contours = ax.contourf(to_np(wspd_cross), cmap=get_cmap("jet")) | 
						|
     | 
						|
    # Add the color bar | 
						|
    plt.colorbar(wspd_contours, ax=ax) | 
						|
     | 
						|
    # Set the x-ticks to use latitude and longitude labels. | 
						|
    coord_pairs = to_np(wspd_cross.coords["xy_loc"]) | 
						|
    x_ticks = np.arange(coord_pairs.shape[0]) | 
						|
    x_labels = [pair.latlon_str(fmt="{:.2f}, {:.2f}")  | 
						|
                for pair in to_np(coord_pairs)] | 
						|
    ax.set_xticks(x_ticks[::20]) | 
						|
    ax.set_xticklabels(x_labels[::20], rotation=45, fontsize=8)  | 
						|
     | 
						|
    # Set the y-ticks to be height. | 
						|
    vert_vals = to_np(wspd_cross.coords["vertical"]) | 
						|
    v_ticks = np.arange(vert_vals.shape[0]) | 
						|
    ax.set_yticks(v_ticks[::20]) | 
						|
    ax.set_yticklabels(vert_vals[::20], fontsize=8)  | 
						|
     | 
						|
    # Set the x-axis and  y-axis labels | 
						|
    ax.set_xlabel("Latitude, Longitude", fontsize=12) | 
						|
    ax.set_ylabel("Height (m)", fontsize=12) | 
						|
     | 
						|
    plt.title("Vertical Cross Section of Wind Speed (kt)") | 
						|
     | 
						|
    plt.show() | 
						|
     | 
						|
 | 
						|
Cross Section with Mountains | 
						|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 
						|
 | 
						|
The example below shows how to make a cross section with the mountainous  | 
						|
terrain filled.  | 
						|
 | 
						|
.. image:: _static/images/cross_mtns.png     | 
						|
   :scale: 100% | 
						|
   :align: center | 
						|
 | 
						|
.. code-block:: python | 
						|
     | 
						|
    import numpy as np | 
						|
    from matplotlib import pyplot | 
						|
    from matplotlib.cm import get_cmap | 
						|
    from matplotlib.colors import from_levels_and_colors | 
						|
    from cartopy import crs | 
						|
    from cartopy.feature import NaturalEarthFeature, COLORS | 
						|
    from netCDF4 import Dataset | 
						|
    from wrf import (getvar, to_np, get_cartopy, latlon_coords, vertcross, | 
						|
                     cartopy_xlim, cartopy_ylim, interpline, CoordPair) | 
						|
     | 
						|
    wrf_file = Dataset("wrfout_d01_2010-06-04_00:00:00") | 
						|
     | 
						|
    # Define the cross section start and end points | 
						|
    cross_start = CoordPair(lat=43.5, lon=-116.5) | 
						|
    cross_end = CoordPair(lat=43.5, lon=-114) | 
						|
     | 
						|
    # Get the WRF variables | 
						|
    ht = getvar(wrf_file, "z", timeidx=-1) | 
						|
    ter = getvar(wrf_file, "ter", timeidx=-1) | 
						|
    dbz = getvar(wrf_file, "dbz", timeidx=-1) | 
						|
    max_dbz = getvar(wrf_file, "mdbz", timeidx=-1) | 
						|
    Z = 10**(dbz/10.) # Use linear Z for interpolation | 
						|
     | 
						|
    # Compute the vertical cross-section interpolation.  Also, include the  | 
						|
    # lat/lon points along the cross-section in the metadata by setting latlon  | 
						|
    # to True. | 
						|
    z_cross = vertcross(Z, ht, wrfin=wrf_file,  | 
						|
                        start_point=cross_start,  | 
						|
                        end_point=cross_end, | 
						|
                        latlon=True, meta=True) | 
						|
     | 
						|
    # Convert back to dBz after interpolation | 
						|
    dbz_cross = 10.0 * np.log10(z_cross) | 
						|
     | 
						|
    # Add back the attributes that xarray dropped from the operations above | 
						|
    dbz_cross.attrs.update(z_cross.attrs) | 
						|
    dbz_cross.attrs["description"] = "radar reflectivity cross section" | 
						|
    dbz_cross.attrs["units"] = "dBZ" | 
						|
     | 
						|
    # To remove the slight gap between the dbz contours and terrain due to the   | 
						|
    # contouring of gridded data, a new vertical grid spacing, and model grid  | 
						|
    # staggering, fill in the lower grid cells with the first non-missing value  | 
						|
    # for each column. | 
						|
     | 
						|
    # Make a copy of the z cross data. Let's use regular numpy arrays for this. | 
						|
    dbz_cross_filled = np.ma.copy(to_np(dbz_cross)) | 
						|
     | 
						|
    # For each cross section column, find the first index with non-missing  | 
						|
    # values and copy these to the missing elements below. | 
						|
    for i in range(dbz_cross_filled.shape[-1]): | 
						|
        column_vals = dbz_cross_filled[:,i] | 
						|
        # Let's find the lowest index that isn't filled. The nonzero function  | 
						|
        # finds all unmasked values greater than 0. Since 0 is a valid value | 
						|
        # for dBZ, let's change that threshold to be -200 dBZ instead.  | 
						|
        first_idx = int(np.transpose((column_vals > -200).nonzero())[0]) | 
						|
        dbz_cross_filled[0:first_idx, i] = dbz_cross_filled[first_idx, i] | 
						|
                 | 
						|
    # Get the terrain heights along the cross section line | 
						|
    ter_line = interpline(ter, wrfin=wrf_file, start_point=cross_start,  | 
						|
                          end_point=cross_end) | 
						|
     | 
						|
    # Get the lat/lon points | 
						|
    lats, lons = latlon_coords(dbz) | 
						|
     | 
						|
    # Get the cartopy projection object | 
						|
    cart_proj = get_cartopy(dbz) | 
						|
     | 
						|
    # Create the figure | 
						|
    fig = pyplot.figure(figsize=(8,6)) | 
						|
    ax_cross = pyplot.axes() | 
						|
     | 
						|
    dbz_levels = np.arange(5., 75., 5.) | 
						|
     | 
						|
    # Create the color table found on NWS pages. | 
						|
    dbz_rgb = np.array([[4,233,231], | 
						|
                        [1,159,244], [3,0,244], | 
						|
                        [2,253,2], [1,197,1], | 
						|
                        [0,142,0], [253,248,2], | 
						|
                        [229,188,0], [253,149,0], | 
						|
                        [253,0,0], [212,0,0], | 
						|
                        [188,0,0],[248,0,253], | 
						|
                        [152,84,198]], np.float32) / 255.0 | 
						|
         | 
						|
    dbz_map, dbz_norm = from_levels_and_colors(dbz_levels, dbz_rgb,  | 
						|
                                               extend="max") | 
						|
     | 
						|
    # Make the cross section plot for dbz | 
						|
    dbz_levels = np.arange(5.,75.,5.) | 
						|
    xs = np.arange(0, dbz_cross.shape[-1], 1) | 
						|
    ys = to_np(dbz_cross.coords["vertical"]) | 
						|
    dbz_contours = ax_cross.contourf(xs,  | 
						|
                                     ys,  | 
						|
                                     to_np(dbz_cross_filled),  | 
						|
                                     levels=dbz_levels, | 
						|
                                     cmap=dbz_map,  | 
						|
                                     norm=dbz_norm,  | 
						|
                                     extend="max") | 
						|
    # Add the color bar | 
						|
    cb_dbz = fig.colorbar(dbz_contours, ax=ax_cross) | 
						|
    cb_dbz.ax.tick_params(labelsize=8) | 
						|
     | 
						|
    # Fill in the mountain area | 
						|
    ht_fill = ax_cross.fill_between(xs, 0, to_np(ter_line),  | 
						|
                                    facecolor="saddlebrown") | 
						|
     | 
						|
    # Set the x-ticks to use latitude and longitude labels | 
						|
    coord_pairs = to_np(dbz_cross.coords["xy_loc"]) | 
						|
    x_ticks = np.arange(coord_pairs.shape[0]) | 
						|
    x_labels = [pair.latlon_str() for pair in to_np(coord_pairs)] | 
						|
     | 
						|
    # Set the desired number of x ticks below | 
						|
    num_ticks = 5 | 
						|
    thin = int((len(x_ticks) / num_ticks) + .5) | 
						|
    ax_cross.set_xticks(x_ticks[::thin]) | 
						|
    ax_cross.set_xticklabels(x_labels[::thin], rotation=45, fontsize=8) | 
						|
     | 
						|
    # Set the x-axis and  y-axis labels | 
						|
    ax_cross.set_xlabel("Latitude, Longitude", fontsize=12) | 
						|
    ax_cross.set_ylabel("Height (m)", fontsize=12) | 
						|
     | 
						|
    # Add a title | 
						|
    ax_cross.set_title("Cross-Section of Reflectivity (dBZ)", {"fontsize" : 14}) | 
						|
     | 
						|
    pyplot.show()
 | 
						|
 |