Pablo Romero wrote:
Jeff,
Here's a link to the website that's creating the basemap plots with
the "H"'s and "L"'s:
http://magicseaweed.com/msw-surf-charts2.php?chart=64&res=750&type=pressure&starttime=
As you can see, this website's "pressure chart" interface is based on
creating individual images for each point in a time series. And, if
you click on any one of the "region" links below the plot, you'll be
presented with the same pressure plot for a sub-region; obviously,
this needs to be based on an automated process, since I seriously
doubt someone is manually creating each plot for each time step for
each "sub-region" in their catalog...bottom line, there MUST be a
systematic way to add those "H" and "L" characters to closed contours
that are local min/max AND that are LARGE enough to hold an "H" or "L"
character (as you mentioned, some of the smaller closed contours dont
display the 'H'/'L' characters).
So the big question is: how could one go about setting something like
this up???
Do you think it would be possible to accomplish this with the
function/tutorial you provided???
If so, could you please help me understand a little more how I would
go about using that function? (sorry, I wasnt very clear on how it
should be applied to this problem).
I know for a fact that this website is using matplotlib/basemap to
create these plots. Theyre using a python interface to
matplolib/basemap named 'pygrads'; it provides basemap/mpl plotting
capabilities to an existing application named GrADS. I just dont know
how the heck they got those "H/L" characters there....
Thanks again for the help,
Pablo
Pablo: I've added a script (attached to this email) called
"plothighsandlows.py" in the basemap examples directory that shows how
to do this. It uses scipy.ndimage.filters, so you'll need to have scipy
installed to run it.
-Jeff
----------------------------------------
Date: Fri, 6 Mar 2009 06:07:10 -0700
From: jsw...@fastmail.fm
To: romero...@hotmail.com
CC: matplotlib-users@lists.sourceforge.net
Subject: Re: [Matplotlib-users] plotting air pressure data with
contour() function
Jeff Whitaker wrote:
Pablo Romero wrote:
Hello,
I have a question about plotting pressure contours with matplotlib.
I've seen other applications using matplotlib where the pressure
contours are drawn with annoted text "H" and "L" characters being
drawn in the centers of closed contours...
i.e., if there is a closed contour line, and its value is over a
certain threshold value, plot an "H" to indicate a "high pressure
zone", else plot a "L" to indicate a "low pressure zone."
This is standard weather map plotting stuff, and Ive definitely
seen other plots produced using matplotlib that inlude these
annoted "H" and "L" characters. In the application Ive seen, the
process was most definitely automated, since it was applied to a
large number of plots (i.e., the "H"'s and "L"'s werent added
manually, since its not feasible). Unfortunately, the creators of
these plots are not willing to share their technique.
I dont know how to set this up with matplotlib.
Does anyone have any experience with this???
Is there any way to identify a "closed contour" & its value from a
"contour class" that is returned from matplotlib's contour()
function???
Pablo: There is no easy way to do this in matplotlib. I guess you
would try to find closed contours with no other contours inside them,
the place the label at the center of that region. This might end up
being quite tricky. I see from your example that there are many such
regions that are not labelled (some are, some aren't).
Or, you might just try to find local minima and maxima in your gridded
data and plot H's and L's there. This ought to be easier.
-Jeff
Pablo: Regarding the latter method, here's a relevant thread from the
scipy list:
http://www.nabble.com/Finding-local-minima-of-greater-than-a-given-depth-td18988309.html
-Jeff
_________________________________________________________________
Windows Live⢠Contacts: Organize your contact list.
http://windowslive.com/connect/post/marcusatmicrosoft.spaces.live.com-Blog-cns!503D1D86EBB2B53C!2285.entry?ocid=TXT_TAGLM_WL_UGC_Contacts_032009
"""
plot H's and L's on a sea-level pressure map
(uses scipy.ndimage.filters)
"""
import numpy as np
import matplotlib.pyplot as plt
import sys
from mpl_toolkits.basemap import Basemap, NetCDFFile, addcyclic
from scipy.ndimage.filters import minimum_filter, maximum_filter
def extrema(mat,mode='wrap',window=10):
mn = minimum_filter(mat, size=window, mode=mode)
mx = maximum_filter(mat, size=window, mode=mode)
# (mat == mx) true if pixel is equal to the local max
# The next computation suppresses responses where
# the function is flat.
local_maxima = ((mat == mx) & (mat != mn))
local_minima = ((mat == mn) & (mat != mx))
# Get the indices of the maxima, minima
return np.nonzero(local_minima), np.nonzero(local_maxima)
if len(sys.argv) < 2:
print 'enter date to plot (YYYYMMDDHH) on command line'
raise SystemExit
# get date from command line.
YYYYMMDDHH = sys.argv[1]
# open OpenDAP dataset.
try:
data=NetCDFFile("http://nomad1.ncep.noaa.gov:9090/dods/gdas/rotating/gdas"+YYYYMMDDHH)
except:
data=NetCDFFile("http://nomad1.ncep.noaa.gov:9090/dods/gdas/rotating/"+YYYYMMDDHH[0:6]+"/gdas"+YYYYMMDDHH)
# read lats,lons.
lats = data.variables['lat'][:]
lons1 = data.variables['lon'][:]
nlats = len(lats)
nlons = len(lons1)
# read prmsl, convert to hPa (mb).
prmsl = 0.01*data.variables['prmslmsl'][0]
# the window parameter controls the number of highs and lows detected.
# (higher value, fewer highs and lows)
local_min, local_max = extrema(prmsl, mode='wrap', window=25)
# create Basemap instance.
m =
Basemap(llcrnrlon=0,llcrnrlat=-65,urcrnrlon=360,urcrnrlat=65,projection='merc')
# add wrap-around point in longitude.
prmsl, lons = addcyclic(prmsl, lons1)
# contour levels
clevs = np.arange(900,1100.,5.)
# find x,y of map projection grid.
lons, lats = np.meshgrid(lons, lats)
x, y = m(lons, lats)
# create figure.
fig=plt.figure(figsize=(12,6))
cs = m.contour(x,y,prmsl,clevs,colors='k',linewidths=1.)
m.drawcoastlines(linewidth=1.25)
m.fillcontinents(color='0.8')
m.drawparallels(np.arange(-80,81,20))
m.drawmeridians(np.arange(0,360,60))
xlows = x[local_min]; xhighs = x[local_max]
ylows = y[local_min]; yhighs = y[local_max]
lowvals = prmsl[local_min]; highvals = prmsl[local_max]
# plot lows as blue L's, with min pressure value underneath.
xyplotted = []
# don't plot if there is already a L or H within dmin meters.
dmin = 500000
for x,y,p in zip(xlows, ylows, lowvals):
if x < m.xmax and x > m.xmin and y < m.ymax and y > m.ymin:
dist = [np.sqrt((x-x0)**2+(y-y0)**2) for x0,y0 in xyplotted]
if not dist or min(dist) > dmin:
plt.text(x,y,'L',fontsize=14,fontweight='bold',
horizontalalignment='center',
verticalalignment='center',color='blue')
plt.text(x,y-400000,repr(int(p)),fontsize=9,
horizontalalignment='center',
verticalalignment='top',color='blue')
xyplotted.append((x,y))
# plot highs as red H's, with max pressure value underneath.
xyplotted = []
for x,y,p in zip(xhighs, yhighs, highvals):
if x < m.xmax and x > m.xmin and y < m.ymax and y > m.ymin:
dist = [np.sqrt((x-x0)**2+(y-y0)**2) for x0,y0 in xyplotted]
if not dist or min(dist) > dmin:
plt.text(x,y,'H',fontsize=14,fontweight='bold',
horizontalalignment='center',
verticalalignment='center',color='red')
plt.text(x,y-400000,repr(int(p)),fontsize=9,
horizontalalignment='center',
verticalalignment='top',color='red')
xyplotted.append((x,y))
plt.title('Mean Sea-Level Pressure (with Highs and Lows) %s' % YYYYMMDDHH)
plt.show()
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users