def draw_graph_on_map(g, node2weight, node2pos, pic_title, pic_area=[-130,10,140,70], output_fname_prefix=None, need_draw_edge=0): """ 2007-09-13 identity_pair_ls is a list of pairs of strains (ecotype id as in table ecotype) 2007-10-08 correct a bug in 4*diameter_ls, diameter_ls has to be converted to array first. sqrt the node weight, 8 times the original weight """ import os, sys sys.stderr.write("Drawing graph on a map ...\n") import pylab, math from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05,0.05,0.9,0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill', ax=pylab.gca()) sys.stderr.write("\tDrawing nodes ...") euc_coord1_ls = [] euc_coord2_ls = [] diameter_ls = [] for n in g.nodes(): lat, lon = node2pos[n] euc_coord1, euc_coord2 = m(lon, lat) #longitude first, latitude 2nd euc_coord1_ls.append(euc_coord1) euc_coord2_ls.append(euc_coord2) diameter_ls.append(math.sqrt(node2weight[n])) import numpy diameter_ls = numpy.array(diameter_ls) m.scatter(euc_coord1_ls, euc_coord2_ls, 8*diameter_ls, marker='o', color='r', alpha=0.4, zorder=12, faceted=False) sys.stderr.write("Done.\n") if need_draw_edge: sys.stderr.write("\tDrawing edges ...") ax=pylab.gca() for popid1, popid2, no_of_connections in g.edges(): lat1, lon1 = node2pos[popid1] lat2, lon2 = node2pos[popid2] x1, y1 = m(lon1, lat1) x2, y2 = m(lon2, lat2) ax.plot([x1,x2],[y1,y2], 'g', linewidth=math.log(no_of_connections+1)/2, alpha=0.2, zorder=10) sys.stderr.write("Done.\n") #m.drawcoastlines() m.drawparallels(pylab.arange(-90,90,30), labels=[1,1,0,1]) m.drawmeridians(pylab.arange(-180,180,30), labels=[1,1,0,1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title(pic_title) if output_fname_prefix: pylab.savefig('%s.eps'%output_fname_prefix, dpi=600) pylab.savefig('%s.svg'%output_fname_prefix, dpi=600) pylab.savefig('%s.png'%output_fname_prefix, dpi=600) del fig, m, pylab sys.stderr.write("Done.\n")
def draw_clustered_strain_location(self, label_ls, weighted_pos_ls, diameter_ls, label_type, label_type2label_name, pic_area=[-180,-90,180,90], output_fname_prefix=None, label_name=None): """ 2007-07-11 draw populations derived from connected_components of the strain network #each pie denotes a population, with diameter proportional to the size of the population #each pie labeled with the number of strains in that population 2007-07-13 use popid as label 2007-07-17 no parallels, no meridians 2007-08-29 copied from CreatePopulation.py 2007-09-11 add label name 2007-10-14 correct a bug in 5*diameter_ls. diameter_ls has to an array """ sys.stderr.write("Drawing population map...") import pylab from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05,0.05,0.9,0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill') euc_coord1_ls = [] euc_coord2_ls = [] ax=pylab.gca() for i in range(len(weighted_pos_ls)): lat, lon = weighted_pos_ls[i] euc_coord1, euc_coord2 = m(lon, lat) #longitude first, latitude 2nd euc_coord1_ls.append(euc_coord1) euc_coord2_ls.append(euc_coord2) ax.text(euc_coord1, euc_coord2, str(label_ls[i]), size=5, alpha=0.5, horizontalalignment='center', verticalalignment='center', zorder=12) import numpy diameter_ls = numpy.array(diameter_ls) m.scatter(euc_coord1_ls, euc_coord2_ls, 5*diameter_ls, marker='o', color='r', alpha=0.3, zorder=10, faceted=False) #m.drawcoastlines() m.drawparallels(pylab.arange(-90,90,30), labels=[1,1,0,1]) #labels intersect the left, right, top bottom of the plot m.drawmeridians(pylab.arange(-180,180,30), labels=[1,1,0,1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title("worldwide distribution of %s populations, labeled by %s"%(len(weighted_pos_ls), label_type2label_name[label_type])) if output_fname_prefix: pylab.savefig('%s_pop_map.eps'%output_fname_prefix, dpi=300) pylab.savefig('%s_pop_map.svg'%output_fname_prefix, dpi=300) pylab.savefig('%s_pop_map.png'%output_fname_prefix, dpi=300) del m, pylab, Basemap sys.stderr.write("Done.\n")
def DrawSiteNetwork(self, g, node_label2pos_counts, pic_area=[-180, -90, 180, 90], output_fname_prefix=None): """ 2007-07-17 put ax.plot() right after Basemap() but after m.xxx() so that it'll zoom in use 'g' in ax.plot(), otherwise, ax.plot() alternates all colors. no parallels, no meridians 2007-08-29 copied from CreatePopulation.py and renamed from DrawStrainNetwork """ sys.stderr.write("Drawing Site Network...") import pylab from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05, 0.05, 0.9, 0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill') ax = pylab.gca() for e in g.edges(): lat1, lon1 = node_label2pos_counts[e[0]][0] lat2, lon2 = node_label2pos_counts[e[1]][0] x1, y1 = m(lon1, lat1) x2, y2 = m(lon2, lat2) ax.plot([x1, x2], [y1, y2], 'g', alpha=0.5, zorder=12) #m.drawcoastlines() m.drawparallels(pylab.arange(-90, 90, 30), labels=[1, 1, 0, 1]) m.drawmeridians(pylab.arange(-180, 180, 30), labels=[1, 1, 0, 1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title("Network of strains") if output_fname_prefix: pylab.savefig('%s_site_network.eps' % output_fname_prefix, dpi=300) pylab.savefig('%s_site_network.svg' % output_fname_prefix, dpi=300) pylab.savefig('%s_site_network.png' % output_fname_prefix, dpi=300) del m, pylab, Basemap sys.stderr.write("Done.\n")
def DrawSiteNetwork(self, g, node_label2pos_counts,pic_area=[-180,-90,180,90], output_fname_prefix=None): """ 2007-07-17 put ax.plot() right after Basemap() but after m.xxx() so that it'll zoom in use 'g' in ax.plot(), otherwise, ax.plot() alternates all colors. no parallels, no meridians 2007-08-29 copied from CreatePopulation.py and renamed from DrawStrainNetwork """ sys.stderr.write("Drawing Site Network...") import pylab from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05,0.05,0.9,0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill') ax=pylab.gca() for e in g.edges(): lat1, lon1 = node_label2pos_counts[e[0]][0] lat2, lon2 = node_label2pos_counts[e[1]][0] x1, y1 = m(lon1, lat1) x2, y2 = m(lon2, lat2) ax.plot([x1,x2],[y1,y2], 'g', alpha=0.5, zorder=12) #m.drawcoastlines() m.drawparallels(pylab.arange(-90,90,30), labels=[1,1,0,1]) m.drawmeridians(pylab.arange(-180,180,30), labels=[1,1,0,1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title("Network of strains") if output_fname_prefix: pylab.savefig('%s_site_network.eps'%output_fname_prefix, dpi=300) pylab.savefig('%s_site_network.svg'%output_fname_prefix, dpi=300) pylab.savefig('%s_site_network.png'%output_fname_prefix, dpi=300) del m, pylab, Basemap sys.stderr.write("Done.\n")
res = 'i' map = Basemap(projection=prj, llcrnrlon=lonmin, llcrnrlat=latmin, urcrnrlon=lonmax, urcrnrlat=latmax, resolution=res) map.plot(lon, lat, 'r-') map.plot(lon, lat, 'k+') fs = 10 pylab.text(115.9,-31.9, "Perth", fontsize=fs, ha='left', va='top') pylab.text(114.1,-21.9, "Exmouth", fontsize=fs, ha='left', va='top') pylab.text(118.5,-20.4, "Port Hedland", fontsize=fs, ha='left', va='top') pylab.text(130.8,-12.6, "Darwin", fontsize=fs, ha='left', va='top') pylab.text(145.75,-16.9, "Cairns", fontsize=fs, ha='right', va='top') pylab.text(149.2,-21.2, "Mackay", fontsize=fs, ha='right', va='top') pylab.text(153.0,-27.5, "Brisbane", fontsize=fs, ha='right', va='top') pylab.text(153.1,-30.25, "Coffs Harbour", fontsize=fs, ha='right', va='top') pylab.text(151.1,-33.9, "Sydney", fontsize=fs, ha='right', va='top') pylab.text(150.5,-35.3, "Ulladulla", fontsize=fs, ha='right', va='top') map.fillcontinents(color='0.9') map.drawcoastlines() map.drawparallels(parallel, label=[1,0,0,1], fontsize=8) map.drawmeridians(meridian, label=[1,0,0,1], fontsize=8) pylab.show() pylab.savefig("N:\\cyclone\\sandpits\\carthur\\landfall\\gates.v0.2.png")
# set size of plot to match aspect ratio of map. ax = gca() l,b,w,h = ax.get_position() b = 0.5 - 0.5*w*m.aspect; h = w*m.aspect #l = 0.5 - 0.5*h/m.aspect; w = h/m.aspect ax.set_position([l,b,w,h]) corners = ((m.xmin,m.ymin), (m.xmax,m.ymax)) ax.update_datalim( corners ) axis([m.xmin, m.xmax, m.ymin, m.ymax]) # draw map. if plot in ['pcolor','imshow']: m.drawcoastlines(ax) else: m.fillcontinents(ax,color='gray') # draw parallels delat = 30. delon = 30. circles = arange(0.,90.+delat,delat).tolist()+\ arange(-delat,-90.-delat,-delat).tolist() m.drawparallels(ax,circles) # draw meridians meridians = arange(0.,360.,delon) m.drawmeridians(ax,meridians) ax.set_xticks([]) # no ticks ax.set_yticks([]) title('500 hPa Height - '+plot)
nx = len(lons) ny = int(80. * len(lats) / 90.) lonsout, latsout = m.makegrid(nx, ny) topodat = interp(topoin, lons, lats, lonsout, latsout) xsize = rcParams['figure.figsize'][0] fig = figure(figsize=(xsize, m.aspect * xsize)) fig.add_axes([0.1, 0.1, 0.8, 0.8]) im = imshow(topodat, cm.jet, extent=(m.llcrnrx, m.urcrnrx, m.llcrnry, m.urcrnry), origin='lower') ax = gca() # get current axis instance m.drawcoastlines(ax) m.drawcountries(ax) m.drawstates(ax) m.fillcontinents(ax) # draw parallels m.drawparallels(ax, circles) # draw meridians m.drawmeridians(ax, meridians) ax.set_xticks([]) # no ticks ax.set_yticks([]) title('Mercator') print 'plotting Mercator example, close plot window to proceed ...' show() m = Basemap(-145.5,1.,-2.566,46.352,\ resolution='c',area_thresh=10000.,projection='lcc',\ lat_1=50.,lon_0=-107.) # define grid (nx x ny regularly spaced native projection grid) nx = int((m.xmax - m.xmin) / 40000.) + 1
m = Basemap(projection='lcc', resolution='i', llcrnrlon=5.0, llcrnrlat= 52., urcrnrlon=35.5, urcrnrlat=68.0, lat_0=15.00, lon_0=0.0, suppress_ticks=False) fig=pl.figure() # background color will be used for 'wet' areas. fig.add_axes([0.1,0.1,0.8,0.8],axisbg='azure') m.drawcoastlines(linewidth=0.25) m.fillcontinents(color='beige') x, y, beta = zip(*[(241782.65384467551, 1019981.3539730886, 1.0), (263546.12512432877, 686274.79435173667, 0), (452162.87621465814, 207478.42619936226, 1.0), (1431519.0837990609, 432367.62942244718, 1.0), (1409755.6125194072, 816855.62202965701, -1.0), (1612881.344462839, 816855.62202965701, 1.0), (1620135.83488939, 1194089.1242103155, -1.0), (2048150.7700559068, 1302906.4806085825, 1.0), (1982860.3562169466, 1520541.1934051164, 1.0), (1358974.1795335496, 1447996.2891396051, -1.0), (1344465.1986804469, 1716412.4349219969, 0), (1620135.83488939, 2318535.1403257404, 1.0), (1199375.3901494243, 2383825.5541647007, 1.0), (967231.6964997882, 1825229.7913202639, 0),
print shp_info # find names of storms that reached Cat 4. names = [] for shapedict in m.hurrtracks_info: cat = shapedict['CATEGORY'] name = shapedict['NAME'] if cat in ['H4', 'H5'] and name not in names: # only use named storms. if name != 'NOT NAMED': names.append(name) print names print len(names) # plot tracks of those storms. for shapedict, shape in zip(m.hurrtracks_info, m.hurrtracks): name = shapedict['NAME'] cat = shapedict['CATEGORY'] if name in names: xx, yy = zip(*shape) # show part of track where storm > Cat 4 as thick red. if cat in ['H4', 'H5']: p.plot(xx, yy, linewidth=1.5, color='r') elif cat in ['H1', 'H2', 'H3']: p.plot(xx, yy, color='k') # draw coastlines, meridians and parallels. m.drawcoastlines() m.drawcountries() m.fillcontinents(color='#cc9966') m.drawparallels(p.arange(10, 70, 20), labels=[1, 1, 0, 0]) m.drawmeridians(p.arange(-100, 0, 20), labels=[0, 0, 0, 1]) p.title('Atlantic Hurricane Tracks (Storms Reaching Category 4, 1851-2004)') p.show()
def draw_graph_on_map(g, node2weight, node2pos, pic_title, pic_area=[-130, 10, 140, 70], output_fname_prefix=None, need_draw_edge=0): """ 2007-09-13 identity_pair_ls is a list of pairs of strains (ecotype id as in table ecotype) 2007-10-08 correct a bug in 4*diameter_ls, diameter_ls has to be converted to array first. sqrt the node weight, 8 times the original weight """ import os, sys sys.stderr.write("Drawing graph on a map ...\n") import pylab, math from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05, 0.05, 0.9, 0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill', ax=pylab.gca()) sys.stderr.write("\tDrawing nodes ...") euc_coord1_ls = [] euc_coord2_ls = [] diameter_ls = [] for n in g.nodes(): lat, lon = node2pos[n] euc_coord1, euc_coord2 = m(lon, lat) #longitude first, latitude 2nd euc_coord1_ls.append(euc_coord1) euc_coord2_ls.append(euc_coord2) diameter_ls.append(math.sqrt(node2weight[n])) import numpy diameter_ls = numpy.array(diameter_ls) m.scatter(euc_coord1_ls, euc_coord2_ls, 8 * diameter_ls, marker='o', color='r', alpha=0.4, zorder=12, faceted=False) sys.stderr.write("Done.\n") if need_draw_edge: sys.stderr.write("\tDrawing edges ...") ax = pylab.gca() for popid1, popid2, no_of_connections in g.edges(): lat1, lon1 = node2pos[popid1] lat2, lon2 = node2pos[popid2] x1, y1 = m(lon1, lat1) x2, y2 = m(lon2, lat2) ax.plot([x1, x2], [y1, y2], 'g', linewidth=math.log(no_of_connections + 1) / 2, alpha=0.2, zorder=10) sys.stderr.write("Done.\n") #m.drawcoastlines() m.drawparallels(pylab.arange(-90, 90, 30), labels=[1, 1, 0, 1]) m.drawmeridians(pylab.arange(-180, 180, 30), labels=[1, 1, 0, 1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title(pic_title) if output_fname_prefix: pylab.savefig('%s.eps' % output_fname_prefix, dpi=600) pylab.savefig('%s.svg' % output_fname_prefix, dpi=600) pylab.savefig('%s.png' % output_fname_prefix, dpi=600) del fig, m, pylab sys.stderr.write("Done.\n")
m = Basemap(-180.,-80.,180.,80.,\ resolution='c',area_thresh=10000.,projection='merc',\ lon_0=0.5*(lons[0]+lons[-1]),lat_ts=20.) # transform to nx x ny regularly spaced native projection grid nx = len(lons); ny = int(80.*len(lats)/90.) topodat = m.transform_scalar(topoin,lons,lats,nx,ny) # setup figure with same aspect ratio as map. xsize = rcParams['figure.figsize'][0] fig=figure(figsize=(xsize,m.aspect*xsize)) fig.add_axes([0.1,0.1,0.75,0.75]) # plot image over map. im = m.imshow(topodat,cm.jet) m.drawcoastlines() m.drawcountries() m.drawstates() m.fillcontinents() # draw parallels m.drawparallels(circles,labels=[1,1,1,1]) # draw meridians m.drawmeridians(meridians,labels=[1,1,1,1]) title('Mercator',y=1.1) print 'plotting Mercator example, close plot window to proceed ...' show() # setup transverse mercator basemap. m = Basemap(170.,-45,10.,45.,\ resolution='c',area_thresh=10000.,projection='tmerc',\ lat_0=0.,lon_0=-90.) xsize = rcParams['figure.figsize'][0] fig=figure(figsize=(xsize/m.aspect,xsize)) fig.add_axes([0.125,0.2,0.6,0.6])
def makeFigure(self): """ :todo: Uses pylab so may not be threadsafe. """ lon = self.grid.lon0 + N.arrayrange(self.grid.nlon) * self.grid.dlon lat = self.grid.lat0 + N.arrayrange(self.grid.nlat) * self.grid.dlat ll_lon, ll_lat = lon[0], lat[0] ur_lon, ur_lat = lon[-1], lat[-1] # Account for variable lat/lon axis ordering #!TODO: Could we move this (along with the equivilent in render_imp.py into grid.py? if self.grid.ilat < self.grid.ilon: latLonOrdering = True else: latLonOrdering = False if latLonOrdering: var = self.grid.value else: var = MA.transpose(self.grid.value) fig = p.figure() map = Basemap(projection='cyl', llcrnrlon=ll_lon, llcrnrlat=ll_lat, urcrnrlon=ur_lon, urcrnrlat=ur_lat, resolution='l') ## if self.grid.units: ## p.title("%s\n(%s)" % (self.grid.long_name, self.grid.units)) ## else: ## p.title(self.grid.long_name) p.title(self.grid.long_name) if self.type == 'colour': # transform_scalar doesn't support masked arrays so we must fill then replace the mask. var_dat = map.transform_scalar(var.filled(1.0e20), lon, lat, len(lon), len(lat)) var = MA.masked_values(var_dat, 1.0e20) map.imshow(var, cmap=self.cmap, vmin=self.vmin, vmax=self.vmax, interpolation='nearest') cbar = p.colorbar(orientation='horizontal', format='%.2g') if self.grid.units: cbar.ax.set_xlabel(self.grid.units) else: x, y = map(*p.meshgrid(lon, lat)) c = map.contour(x, y, var, 12, colors='black') c.clabel(fontsize=8) map.fillcontinents(color='#e0e0e0') map.drawcoastlines(color='gray') map.drawmeridians(p.arange(-180, 180, 30), labels=[1, 0, 0, 1], color='gray') map.drawparallels(p.arange(-90, 90, 15), labels=[1, 0, 0, 1], color='gray') # Wrap the caption caption = word_wrap(self.caption, 80) fig.text(0.1, 0.08, caption, fontsize=10, horizontalalignment='left', verticalalignment='top', transform=fig.transFigure) return fig
def test_drawMap(self): sys.stderr.write("Drawing graph on a map ...\n") #import pdb #pdb.set_trace() import StockDB, Stock_250kDB #StockDB has to be setup otherwise, StockDB.Ecotype.table is None in getEcotypeInfo() hostname = 'papaya.usc.edu' dbname = 'stock_250k' db_user = '******' db_passwd = '' drivername = 'mysql' schema = None db = Stock_250kDB.Stock_250kDB(drivername=drivername, username=db_user, password=db_passwd, hostname=hostname, database=dbname, schema=schema) #doesn't matter which database to connect as far as StockDB is imported #db = StockDB.StockDB(drivername=drivername, username=db_user, # password=db_passwd, hostname=hostname, database=dbname, schema=schema) db.setup(create_tables=False) from common import getEcotypeInfo ecotype_info = getEcotypeInfo(db) from matplotlib.toolkits.basemap import Basemap #from mpl_toolkits.basemap import Basemap import pylab from matplotlib import rcParams rcParams['font.size'] = 6 rcParams['legend.fontsize'] = 6 #rcParams['text.fontsize'] = 6 #deprecated. use font.size instead rcParams['axes.labelsize'] = 4 rcParams['axes.titlesize'] = 8 rcParams['xtick.labelsize'] = 4 rcParams['ytick.labelsize'] = 4 pylab.clf() #fig = pylab.figure() #fig.add_axes([0.05,0.05,0.9,0.9]) #[left, bottom, width, height] axe_map = pylab.axes([0.5, 0.02, 0.4, 0.8], frameon=False) axe_map.set_title("Global Arabidopsis Ecotype Distribution") axe_map.set_xlabel('ecotype is drawn as circles.') axe_map.set_ylabel('strains') pic_area = [-140, -40, 140, 70] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill', ax=axe_map) """ llcrnrx = -self.rmajor llcrnry = -self.rmajor urcrnrx = -llcrnrx urcrnry = -llcrnry """ #m.drawcoastlines() #m.bluemarble() m.drawparallels(pylab.arange(-90, 90, 30), labels=[1, 1, 0, 1], size=4, linewidth=0.1) m.drawmeridians(pylab.arange(-180, 180, 30), labels=[1, 1, 0, 1], size=4, linewidth=0.1) m.fillcontinents() m.drawcountries(linewidth=0.1) #m.drawstates() #m.drawlsmask((0,255,0,255), (0,0,255,255), lakes=True) #m.drawlsmask('coral','aqua',lakes=True) print "xlim:", axe_map.get_xlim() print "ylim:", axe_map.get_ylim() xlim = axe_map.get_xlim() ylim = axe_map.get_ylim() """ for strain_id in StrainID2PCAPosInfo.strain_id_ls: img_y_pos = StrainID2PCAPosInfo.strain_id2img_y_pos[strain_id] phenotype_row_index = phenData.row_id2row_index[strain_id] phenotype = phenData.data_matrix[phenotype_row_index][phenotype_col_index] ecotype_id = int(strain_id) ecotype_obj = ecotype_info.ecotype_id2ecotype_obj.get(ecotype_id) if ecotype_obj: lat, lon = ecotype_obj.latitude, ecotype_obj.longitude else: sys.stderr.write("Warning: Ecotype %s not in ecotype_info (fetched from stock db).\n"%ecotype_id) continue if lat and lon: x, y = m(lon, lat) color = cmap(norm(phenotype)) ax.plot([0, x], [img_y_pos, y], linestyle='--', alpha=0.2, linewidth=0.2) ax.scatter([x],[y], s=10, linewidth=0, facecolor=color) #, zorder=10) """ #pylab.title("Global Arabidopsis Ecotype Distribution") output_fname_prefix = '/tmp/map' print "ylim:", axe_map.get_ylim() axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_chromosome = pylab.axes([0.05, 0.02, 0.8, 0.8], frameon=False) axe_chromosome.set_title("chromosome") #fix the two transformations before doing cross-axe drawings axe_map.transData.freeze() # eval the lazy objects axe_map.transAxes.freeze() axe_chromosome.transData.freeze() # eval the lazy objects axe_chromosome.transAxes.freeze() no_of_ecotypes = 200 ecotype_id_ls = ecotype_info.ecotype_id2ecotype_obj.keys( )[:no_of_ecotypes] no_of_ecotypes_drawn = 0 for i in range(no_of_ecotypes): ecotype_id = ecotype_id_ls[i] y_pos = i / float(no_of_ecotypes) #y_pos = i/float(no_of_ecotypes)*ylim[1] ecotype_obj = ecotype_info.ecotype_id2ecotype_obj.get(ecotype_id) if ecotype_obj: lat, lon = ecotype_obj.latitude, ecotype_obj.longitude else: sys.stderr.write( "Warning: Ecotype %s not in ecotype_info (fetched from stock db).\n" % ecotype_id) continue if lat and lon: x, y = m(lon, lat) #axe_map.plot([0, x], [y_pos, y], linestyle='--', alpha=0.2, linewidth=0.2) axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_map.scatter([x], [y], s=5, linewidth=0, facecolor='r', alpha=0.2, zorder=10) canvas_x, canvas_y = axe_map.transData.xy_tup((x, y)) axe_chromosome_xy = axe_chromosome.transData.inverse_xy_tup( (canvas_x, canvas_y)) axe_chromosome.plot([0, axe_chromosome_xy[0]], [y_pos, axe_chromosome_xy[1]], linestyle='--', alpha=0.2, linewidth=0.2) no_of_ecotypes_drawn += 1 #release two transformations axe_map.transData.thaw() # eval the lazy objects axe_map.transAxes.thaw() axe_chromosome.transData.thaw() # eval the lazy objects axe_chromosome.transAxes.thaw() #set to the same x/y_lim before cross-axe drawing axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_chromosome.set_xlim([0, 1]) axe_chromosome.set_ylim([0, 1]) if output_fname_prefix: pylab.savefig('%s.png' % output_fname_prefix, dpi=600) pylab.savefig('%s.svg' % output_fname_prefix) sys.stderr.write("%s ecotypes drawn. Done.\n" % (no_of_ecotypes_drawn))
# stack grids side-by-side (in longitiudinal direction), so # any range of longitudes may be plotted on a world map. tlon = N.concatenate((tlon, tlon + 360), 1) tlat = N.concatenate((tlat, tlat), 1) temp = MA.concatenate((temp, temp), 1) tlon = tlon - 360. pl.figure(figsize=(8.5, 11)) pl.subplot(2, 1, 1) # subplot 1 just shows POP grid cells. map = Basemap(projection='merc', lat_ts=20, llcrnrlon=-180, \ urcrnrlon=180, llcrnrlat=-84, urcrnrlat=84, resolution='c') map.drawcoastlines() map.fillcontinents(color='white') x, y = map(tlon, tlat) im = map.pcolor(x,y,MA.masked_array(N.zeros(temp.shape,'f'), temp.mask),\ shading='faceted',cmap=pl.cm.cool,vmin=0,vmax=0) # disclaimer: these are not really the grid cells because of the # way pcolor interprets the x and y args. pl.title('(A) CCSM POP Grid Cells') # subplot 2 is a contour plot of surface temperature from the # CCSM ocean model. pl.subplot(2, 1, 2) map.drawcoastlines() map.fillcontinents(color='white') CS1 = map.contourf(x, y, temp, 15)
def draw_clustered_strain_location(self, label_ls, weighted_pos_ls, diameter_ls, label_type, label_type2label_name, pic_area=[-180, -90, 180, 90], output_fname_prefix=None, label_name=None): """ 2007-07-11 draw populations derived from connected_components of the strain network #each pie denotes a population, with diameter proportional to the size of the population #each pie labeled with the number of strains in that population 2007-07-13 use popid as label 2007-07-17 no parallels, no meridians 2007-08-29 copied from CreatePopulation.py 2007-09-11 add label name 2007-10-14 correct a bug in 5*diameter_ls. diameter_ls has to an array """ sys.stderr.write("Drawing population map...") import pylab from matplotlib.toolkits.basemap import Basemap pylab.clf() fig = pylab.figure() fig.add_axes([0.05, 0.05, 0.9, 0.9]) #[left, bottom, width, height] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill') euc_coord1_ls = [] euc_coord2_ls = [] ax = pylab.gca() for i in range(len(weighted_pos_ls)): lat, lon = weighted_pos_ls[i] euc_coord1, euc_coord2 = m(lon, lat) #longitude first, latitude 2nd euc_coord1_ls.append(euc_coord1) euc_coord2_ls.append(euc_coord2) ax.text(euc_coord1, euc_coord2, str(label_ls[i]), size=5, alpha=0.5, horizontalalignment='center', verticalalignment='center', zorder=12) import numpy diameter_ls = numpy.array(diameter_ls) m.scatter(euc_coord1_ls, euc_coord2_ls, 5 * diameter_ls, marker='o', color='r', alpha=0.3, zorder=10, faceted=False) #m.drawcoastlines() m.drawparallels(pylab.arange(-90, 90, 30), labels=[ 1, 1, 0, 1 ]) #labels intersect the left, right, top bottom of the plot m.drawmeridians(pylab.arange(-180, 180, 30), labels=[1, 1, 0, 1]) m.fillcontinents() m.drawcountries() m.drawstates() pylab.title("worldwide distribution of %s populations, labeled by %s" % (len(weighted_pos_ls), label_type2label_name[label_type])) if output_fname_prefix: pylab.savefig('%s_pop_map.eps' % output_fname_prefix, dpi=300) pylab.savefig('%s_pop_map.svg' % output_fname_prefix, dpi=300) pylab.savefig('%s_pop_map.png' % output_fname_prefix, dpi=300) del m, pylab, Basemap sys.stderr.write("Done.\n")
# stack grids side-by-side (in longitiudinal direction), so # any range of longitudes may be plotted on a world map. tlon = N.concatenate((tlon,tlon+360),1) tlat = N.concatenate((tlat,tlat),1) temp = MA.concatenate((temp,temp),1) tlon = tlon-360. pl.figure(figsize=(8.5,11)) pl.subplot(2,1,1) # subplot 1 just shows POP grid cells. map = Basemap(projection='merc', lat_ts=20, llcrnrlon=-180, \ urcrnrlon=180, llcrnrlat=-84, urcrnrlat=84, resolution='c') map.drawcoastlines() map.fillcontinents(color='white') x, y = map(tlon,tlat) im = map.pcolor(x,y,MA.masked_array(N.zeros(temp.shape,'f'), temp.mask),\ shading='faceted',cmap=pl.cm.cool,vmin=0,vmax=0) # disclaimer: these are not really the grid cells because of the # way pcolor interprets the x and y args. pl.title('(A) CCSM POP Grid Cells') # subplot 2 is a contour plot of surface temperature from the # CCSM ocean model. pl.subplot(2,1,2) map.drawcoastlines() map.fillcontinents(color='white') CS1 = map.contourf(x,y,temp,15)
fig=figure() # setup of sinusoidal basemap m = Basemap(resolution='c',projection='sinu',lon_0=0) ax = fig.add_axes([0.1,0.1,0.7,0.7]) # make a filled contour plot. x, y = m(lons, lats) CS = m.contour(x,y,hgt,15,linewidths=0.5,colors='k') CS = m.contourf(x,y,hgt,15,cmap=cm.jet) l,b,w,h=ax.get_position() cax = axes([l+w+0.075, b, 0.05, h]) # setup colorbar axes colorbar(drawedges=True, cax=cax) # draw colorbar axes(ax) # make the original axes current again # draw coastlines and political boundaries. m.drawcoastlines() m.drawmapboundary() m.fillcontinents() # draw parallels and meridians. parallels = arange(-60.,90,30.) m.drawparallels(parallels,labels=[1,0,0,0]) meridians = arange(-360.,360.,30.) m.drawmeridians(meridians) title('Sinusoidal Filled Contour Demo') print 'plotting with sinusoidal basemap ...' # create new figure fig=figure() # setup of mollweide basemap m = Basemap(resolution='c',projection='moll',lon_0=0) ax = fig.add_axes([0.1,0.1,0.7,0.7]) # make a filled contour plot. x, y = m(lons, lats)
fig = figure(figsize=(xsize, m.aspect * xsize)) fig.add_axes([0.1, 0.1, 0.8, 0.8]) # nylat, nylon are lat/lon of New York nylat = 40.78 nylon = -73.98 # lonlat, lonlon are lat/lon of London. lonlat = 51.53 lonlon = 0.08 # find 1000 points along the great circle. #x,y = m.gcpoints(nylon,nylat,lonlon,lonlat,1000) # draw the great circle. #m.plot(x,y,linewidth=2) # drawgreatcircle performs the previous 2 steps in one call. m.drawgreatcircle(nylon, nylat, lonlon, lonlat, linewidth=2, color='b') m.drawcoastlines() m.fillcontinents() # draw parallels circles = arange(10, 90, 20) m.drawparallels(circles, labels=[1, 1, 0, 1]) # draw meridians meridians = arange(-180, 180, 30) m.drawmeridians(meridians, labels=[1, 1, 0, 1]) title('Great Circle from New York to London (Mercator)') show() # setup a gnomonic projection. m = Basemap(llcrnrlon=-100.,llcrnrlat=20.,urcrnrlon=20.,urcrnrlat=60.,\ resolution='c',area_thresh=10000.,projection='gnom',\ lat_0=40.,lon_0=-45.) # make figure with aspect ratio that matches map region. xsize = rcParams['figure.figsize'][0]
resolution='c',area_thresh=10000.,projection='merc',\ lon_0=0.5*(lons[0]+lons[-1]),lat_ts=20.) # transform to nx x ny regularly spaced native projection grid nx = len(lons) ny = int(80. * len(lats) / 90.) topodat = m.transform_scalar(topoin, lons, lats, nx, ny) # setup figure with same aspect ratio as map. xsize = rcParams['figure.figsize'][0] fig = figure(figsize=(xsize, m.aspect * xsize)) fig.add_axes([0.1, 0.1, 0.75, 0.75]) # plot image over map. im = m.imshow(topodat, cm.jet) m.drawcoastlines() m.drawcountries() m.drawstates() m.fillcontinents() # draw parallels m.drawparallels(circles, labels=[1, 1, 1, 1]) # draw meridians m.drawmeridians(meridians, labels=[1, 1, 1, 1]) title('Mercator', y=1.1) print 'plotting Mercator example, close plot window to proceed ...' show() # setup transverse mercator basemap. m = Basemap(170.,-45,10.,45.,\ resolution='c',area_thresh=10000.,projection='tmerc',\ lat_0=0.,lon_0=-90.) xsize = rcParams['figure.figsize'][0] fig = figure(figsize=(xsize / m.aspect, xsize)) fig.add_axes([0.125, 0.2, 0.6, 0.6])
def test_drawMap(self): sys.stderr.write("Drawing graph on a map ...\n") #import pdb #pdb.set_trace() import StockDB, Stock_250kDB #StockDB has to be setup otherwise, StockDB.Ecotype.table is None in getEcotypeInfo() hostname='papaya.usc.edu' dbname='stock_250k' db_user='******' db_passwd = '' drivername='mysql' schema = None db = Stock_250kDB.Stock_250kDB(drivername=drivername, username=db_user, password=db_passwd, hostname=hostname, database=dbname, schema=schema) #doesn't matter which database to connect as far as StockDB is imported #db = StockDB.StockDB(drivername=drivername, username=db_user, # password=db_passwd, hostname=hostname, database=dbname, schema=schema) db.setup(create_tables=False) from common import getEcotypeInfo ecotype_info = getEcotypeInfo(db) from matplotlib.toolkits.basemap import Basemap #from mpl_toolkits.basemap import Basemap import pylab from matplotlib import rcParams rcParams['font.size'] = 6 rcParams['legend.fontsize'] = 6 #rcParams['text.fontsize'] = 6 #deprecated. use font.size instead rcParams['axes.labelsize'] = 4 rcParams['axes.titlesize'] = 8 rcParams['xtick.labelsize'] = 4 rcParams['ytick.labelsize'] = 4 pylab.clf() #fig = pylab.figure() #fig.add_axes([0.05,0.05,0.9,0.9]) #[left, bottom, width, height] axe_map = pylab.axes([0.5, 0.02, 0.4, 0.8], frameon=False) axe_map.set_title("Global Arabidopsis Ecotype Distribution") axe_map.set_xlabel('ecotype is drawn as circles.') axe_map.set_ylabel('strains') pic_area=[-140,-40,140,70] m = Basemap(llcrnrlon=pic_area[0],llcrnrlat=pic_area[1],urcrnrlon=pic_area[2],urcrnrlat=pic_area[3],\ resolution='l',projection='mill', ax=axe_map) """ llcrnrx = -self.rmajor llcrnry = -self.rmajor urcrnrx = -llcrnrx urcrnry = -llcrnry """ #m.drawcoastlines() #m.bluemarble() m.drawparallels(pylab.arange(-90,90,30), labels=[1,1,0,1], size=4, linewidth=0.1) m.drawmeridians(pylab.arange(-180,180,30), labels=[1,1,0,1], size=4, linewidth=0.1) m.fillcontinents() m.drawcountries(linewidth=0.1) #m.drawstates() #m.drawlsmask((0,255,0,255), (0,0,255,255), lakes=True) #m.drawlsmask('coral','aqua',lakes=True) print "xlim:", axe_map.get_xlim() print "ylim:", axe_map.get_ylim() xlim = axe_map.get_xlim() ylim = axe_map.get_ylim() """ for strain_id in StrainID2PCAPosInfo.strain_id_ls: img_y_pos = StrainID2PCAPosInfo.strain_id2img_y_pos[strain_id] phenotype_row_index = phenData.row_id2row_index[strain_id] phenotype = phenData.data_matrix[phenotype_row_index][phenotype_col_index] ecotype_id = int(strain_id) ecotype_obj = ecotype_info.ecotype_id2ecotype_obj.get(ecotype_id) if ecotype_obj: lat, lon = ecotype_obj.latitude, ecotype_obj.longitude else: sys.stderr.write("Warning: Ecotype %s not in ecotype_info (fetched from stock db).\n"%ecotype_id) continue if lat and lon: x, y = m(lon, lat) color = cmap(norm(phenotype)) ax.plot([0, x], [img_y_pos, y], linestyle='--', alpha=0.2, linewidth=0.2) ax.scatter([x],[y], s=10, linewidth=0, facecolor=color) #, zorder=10) """ #pylab.title("Global Arabidopsis Ecotype Distribution") output_fname_prefix = '/tmp/map' print "ylim:", axe_map.get_ylim() axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_chromosome = pylab.axes([0.05, 0.02, 0.8, 0.8], frameon=False) axe_chromosome.set_title("chromosome") #fix the two transformations before doing cross-axe drawings axe_map.transData.freeze() # eval the lazy objects axe_map.transAxes.freeze() axe_chromosome.transData.freeze() # eval the lazy objects axe_chromosome.transAxes.freeze() no_of_ecotypes = 200 ecotype_id_ls = ecotype_info.ecotype_id2ecotype_obj.keys()[:no_of_ecotypes] no_of_ecotypes_drawn = 0 for i in range(no_of_ecotypes): ecotype_id = ecotype_id_ls[i] y_pos = i/float(no_of_ecotypes) #y_pos = i/float(no_of_ecotypes)*ylim[1] ecotype_obj = ecotype_info.ecotype_id2ecotype_obj.get(ecotype_id) if ecotype_obj: lat, lon = ecotype_obj.latitude, ecotype_obj.longitude else: sys.stderr.write("Warning: Ecotype %s not in ecotype_info (fetched from stock db).\n"%ecotype_id) continue if lat and lon: x, y = m(lon, lat) #axe_map.plot([0, x], [y_pos, y], linestyle='--', alpha=0.2, linewidth=0.2) axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_map.scatter([x],[y], s=5, linewidth=0, facecolor='r', alpha=0.2, zorder=10) canvas_x, canvas_y = axe_map.transData.xy_tup((x,y)) axe_chromosome_xy = axe_chromosome.transData.inverse_xy_tup((canvas_x,canvas_y)) axe_chromosome.plot([0,axe_chromosome_xy[0]], [y_pos, axe_chromosome_xy[1]], linestyle='--', alpha=0.2, linewidth=0.2) no_of_ecotypes_drawn += 1 #release two transformations axe_map.transData.thaw() # eval the lazy objects axe_map.transAxes.thaw() axe_chromosome.transData.thaw() # eval the lazy objects axe_chromosome.transAxes.thaw() #set to the same x/y_lim before cross-axe drawing axe_map.set_xlim(xlim) axe_map.set_ylim(ylim) axe_chromosome.set_xlim([0,1]) axe_chromosome.set_ylim([0,1]) if output_fname_prefix: pylab.savefig('%s.png'%output_fname_prefix, dpi=600) pylab.savefig('%s.svg'%output_fname_prefix) sys.stderr.write("%s ecotypes drawn. Done.\n"%(no_of_ecotypes_drawn))
# transform lons and lats to map coordinates. x,y = m(array(lons_out)/d2r, array(lats_out)/d2r) # find just those points in map region. xx=[] yy=[] for xi,yi in zip(x,y): if (xi>m.llcrnrx and xi<m.urcrnrx) and (yi>m.llcrnry and yi<m.urcrnry): xx.append(xi) yy.append(yi) # plot them as filled circles on the map. # first, create figure with same aspect ratio as map. fig=m.createfigure() # background color will be used for 'wet' areas. fig.add_axes([0.1,0.1,0.8,0.8],axisbg='aqua') # use zorder=10 to make sure markers are drawn last. # (otherwise they are covered up when continents are filled) m.scatter(xx,yy,marker='o',c='k',s=25,zorder=10) # draw coasts and fill continents. m.drawcoastlines(linewidth=0.5) m.fillcontinents(color='coral') # draw parallels and meridians. delat = 20. circles = arange(0.,90.,delat).tolist()+\ arange(-delat,-90,-delat).tolist() m.drawparallels(circles) delon = 45. meridians = arange(0,360,delon) m.drawmeridians(meridians,labels=[1,1,1,1]) title('Randomly Spaced Locations (Min Dist = %g km, %g points)'% (rcrit,len(lons_out)),y=1.075) show()
# set size of plot to match aspect ratio of map. ax = gca() l, b, w, h = ax.get_position() b = 0.5 - 0.5 * w * m.aspect h = w * m.aspect #l = 0.5 - 0.5*h/m.aspect; w = h/m.aspect ax.set_position([l, b, w, h]) corners = ((m.xmin, m.ymin), (m.xmax, m.ymax)) ax.update_datalim(corners) axis([m.xmin, m.xmax, m.ymin, m.ymax]) # draw map. if plot in ['pcolor', 'imshow']: m.drawcoastlines(ax) else: m.fillcontinents(ax, color='gray') # draw parallels delat = 30. delon = 30. circles = arange(0.,90.+delat,delat).tolist()+\ arange(-delat,-90.-delat,-delat).tolist() m.drawparallels(ax, circles) # draw meridians meridians = arange(0., 360., delon) m.drawmeridians(ax, meridians) ax.set_xticks([]) # no ticks ax.set_yticks([]) title('500 hPa Height - ' + plot)
from matplotlib.toolkits.basemap import Basemap from pylab import * # setup a mercator projection. m = Basemap(-90.,30.,30.,60.,\ resolution='c',area_thresh=10000.,projection='merc',\ lat_ts=20.) xsize = rcParams['figure.figsize'][0] fig=figure(figsize=(xsize,m.aspect*xsize)) fig.add_axes([0.1,0.1,0.8,0.8]) ax = gca() # get current axis instance ax.update_datalim(((m.llcrnrx, m.llcrnry),(m.urcrnrx,m.urcrnry))) ax.set_xlim((m.llcrnrx, m.urcrnrx)) ax.set_ylim((m.llcrnry, m.urcrnry)) m.drawcoastlines(ax) m.fillcontinents(ax) # draw parallels circles = [35,45,55] m.drawparallels(ax,circles,labels=[1,1,0,1]) # draw meridians meridians = [-90,-60,-30,0,30] m.drawmeridians(ax,meridians,labels=[1,1,0,1]) # nylat, nylon are lat/lon of New York nylat = 40.78 nylon = -73.98 # lonlat, lonlon are lat/lon of London. lonlat = 51.53 lonlon = 0.08 # draw the great circle. m.drawgreatcircle(ax,nylon,nylat,lonlon,lonlat,linewidth=2,color='b') title('Great Circle from New York to London')
v = uniform(0.0, 1.0, size=npts) z = uniform(0.0, 1.0, size=npts) except: # this works for Numeric/numarray u = uniform(0.0, 1.0, shape=npts) v = uniform(0.0, 1.0, shape=npts) z = uniform(0.0, 1.0, shape=npts) lons = 360.0 * u lats = (180.0 / math.pi) * arccos(2 * v - 1) - 90.0 # transform lons and lats to map coordinates. x, y = m(lons, lats) # plot them as filled circles on the map. # first, create a figure. fig = figure() # background color will be used for 'wet' areas. fig.add_axes([0.1, 0.1, 0.8, 0.8], axisbg="aqua") # use zorder=10 to make sure markers are drawn last. # (otherwise they are covered up when continents are filled) m.scatter(x, y, 25, z, cmap=cm.jet, marker="o", faceted=False, zorder=10) # draw coasts and fill continents. m.drawcoastlines(linewidth=0.5) m.fillcontinents(color="coral") # draw parallels and meridians. delat = 20.0 circles = arange(0.0, 90.0, delat).tolist() + arange(-delat, -90, -delat).tolist() m.drawparallels(circles) delon = 45.0 meridians = arange(0, 360, delon) m.drawmeridians(meridians, labels=[1, 1, 1, 1]) title("Random Points", y=1.075) show()
xx = [] yy = [] for xi, yi in zip(x, y): if (xi > m.llcrnrx and xi < m.urcrnrx) and (yi > m.llcrnry and yi < m.urcrnry): xx.append(xi) yy.append(yi) # plot them as filled circles on the map. # first, create figure with same aspect ratio as map. fig = m.createfigure() # background color will be used for 'wet' areas. fig.add_axes([0.1, 0.1, 0.8, 0.8], axisbg='aqua') # use zorder=10 to make sure markers are drawn last. # (otherwise they are covered up when continents are filled) m.scatter(xx, yy, marker='o', c='k', s=25, zorder=10) # draw coasts and fill continents. m.drawcoastlines(linewidth=0.5) m.fillcontinents(color='coral') # draw parallels and meridians. delat = 20. circles = arange(0.,90.,delat).tolist()+\ arange(-delat,-90,-delat).tolist() m.drawparallels(circles) delon = 45. meridians = arange(0, 360, delon) m.drawmeridians(meridians, labels=[1, 1, 1, 1]) title('Randomly Spaced Locations (Min Dist = %g km, %g points)' % (rcrit, len(lons_out)), y=1.075) show()
print shp_info # find names of storms that reached Cat 4. names = [] for shapedict in m.hurrtracks_info: cat = shapedict['CATEGORY'] name = shapedict['NAME'] if cat in ['H4','H5'] and name not in names: # only use named storms. if name != 'NOT NAMED': names.append(name) print names print len(names) # plot tracks of those storms. for shapedict,shape in zip(m.hurrtracks_info,m.hurrtracks): name = shapedict['NAME'] cat = shapedict['CATEGORY'] if name in names: xx,yy = zip(*shape) # show part of track where storm > Cat 4 as thick red. if cat in ['H4','H5']: p.plot(xx,yy,linewidth=1.5,color='r') elif cat in ['H1','H2','H3']: p.plot(xx,yy,color='k') # draw coastlines, meridians and parallels. m.drawcoastlines() m.drawcountries() m.fillcontinents(color='#cc9966') m.drawparallels(p.arange(10,70,20),labels=[1,1,0,0]) m.drawmeridians(p.arange(-100,0,20),labels=[0,0,0,1]) p.title('Atlantic Hurricane Tracks (Storms Reaching Category 4, 1851-2003)') p.show()