def plot_annloss_deagg_distmag(data, momag_labels, range_bins, pct_limits=None, output_file=None, title=None, show_graph=False, grid=False, colormap=None, annotate=[]): """Plot annualised loss deaggregated distance/magnitude data. Inputs: data an MxN array containing % annualised loss values with axes of moment/magnitude data (M) versus distance (N) momag_labels an iterable containing the y-axis labels for each row of 'data' range_bins an iterable of range values for each column of 'data' pct_limits a tuple (min_pct, max_pct) for % range to plot output_file path to required output plot file title string used to title graph show_graph if True shows graph in window on screen grid if True puts a grid in the graph colormap name of the colormap to use annotate an iterable like [(x, y, str, dict), ...] where x is X screen coordinate y is Y screen coordinate str is the annotation string to display at (x, y) dict is a dictionary of key/value pairs as documented at http://matplotlib.sourceforge.net/api/pyplot_api.html (this is optional) NOTE: if annotate=None is used, no automatic annotation occurs. if annotate=[] is used, auto annotation is generated: timestamp clipping max input data value """ # decide if we have a 'gui-less' plot or not. import matplotlib if output_file and not show_graph: # no plot to be shown - no gui matplotlib.use('Agg', warn=False) elif show_graph: # decide if we *can* show the plot - error if not if sys.platform != 'win32': try: display = os.environ['DISPLAY'] except KeyError: msg = ("No DISPLAY variable set. " "Did you do 'ssh -X <machine>'?") raise RuntimeError(msg) # go ahead with the plot import matplotlib.pyplot as plt import matplotlib.colors as mcolors # decide if we are going to plot if output_file or show_graph: # get colormap to use (cmap_name, my_cmap) = uc.get_colormap(colormap) # get maximum data value #max_pct = scipy.max(data) max_pct = num.max(data) # limit values to within pct_limits here if pct_limits: (floor, ceil) = pct_limits plot_data = scipy.clip(data, floor, ceil) else: plot_data = data # drop last range bin row from data plot_data = plot_data[:,:-1] # Get data X and Y limits max_x = range_bins[-1] min_x = range_bins[0] max_y = momag_labels[-1] min_y = momag_labels[0] max_z = num.max(plot_data) min_z = num.min(plot_data) # calculate required aspect ration (the *2 is a fudge) (y_size, x_size) = scipy.shape(plot_data) ratio = float(x_size/y_size) * 2 # start plot fig = plt.figure() ax = fig.add_subplot(111) im = plt.imshow(plot_data, interpolation='nearest', cmap=my_cmap, origin='lower', extent=[min_x,max_x,min_y,max_y]) # add color bar for step in (1, 2, 5, 10, 20, 50, 100): cb_ticks = [x for x in range(int(min_z), int(max_z+1), step)] if len(cb_ticks) <= 12: break cb = plt.colorbar(orientation='horizontal', ticks=cb_ticks) cb.set_label('% of annual loss') # label axes plt.xlabel('Distance (km)') plt.ylabel('Moment Magnitude') # set main plot aspect ratio plt.axes().set_aspect(ratio) # add graph 'furniture' if title: plt.title(title) plt.grid(grid) # add system annotations: the clipping in effect, time generated, etc if isinstance(annotate, list): pts.plot_timestamp(fig) if pct_limits: clip_str = 'Data values clipped to [%.1f,%.1f]' % (floor, ceil) plt.text(0.98, 0.02, clip_str, fontsize=6, transform=fig.transFigure, horizontalalignment='right') pct_str = '%.2f%%' % max_pct plt.text(0.91, 0.185, pct_str, horizontalalignment='left', fontsize=8, transform=fig.transFigure, ) # add user annotations, if any pua.plot_user_annotation(fig, annotate) # show or save graph (or both?) if output_file: plt.savefig(output_file) if show_graph: plt.show() plt.close()
def plot_hexbin_map(map_data, bins=100, title='', output_file=None, cblabel='', cbformat='%.1f', show_graph=False, grid=True, colormap=None, annotate=[], scale=None, np_posn=None, hexbin_args=None, map_extent=None): """Plot data into a hexgrid with an underlay map. Inputs: map_data (nx3) array containing the data to plot. The first column contains the latitude of a point, the second column contains the longitude and the third column is the value to bin&plot. bins Either a scalar (# bins in X and Y directions) or (nx, ny). title the graph title string output_file path of file to save plot picture in cblabel label to display on the colorbar cbformat format string used to show colormap values show_graph show graph on screen if True grid draw a grid on graph if True colormap if supplied, the colormap name to use (string) annotate an iterable like [(x, y, ann, dict), ...] where x is X screen coordinate y is Y screen coordinate ann is the annotation string to display at (x, y) dict is a dictionary of key/value pairs as documented at http://matplotlib.sourceforge.net/api/pyplot_api.html (this is optional) NOTE: if annotate=None is used, no automatic annotation occurs. if annotate=[] is used, auto annotation is generated: timestamp scale a tuple containing data used to draw a scale: (posn, length, scale_args) where 'posn' is where to place scale, one of: 'NW', 'NE', 'SW', 'SE' (case-insensitive) and 'scale_args' is an optional kwargs dictionary see drawmapscale() function at http://matplotlib.sourceforge.net/basemap/doc/html/api/basemap_api.html#mpl_toolkits.basemap.Basemap.drawmapscale to see values in scale_args np_posn position tuple or a string describing pointer position: 'NW', 'NE', 'SW' or 'SE' (case-insensitive) hexbin_args is a dictionary of hexbin() parameters if not supplied, assume {'gridsize': 100, 'reduce_C_function': scipy.sum } Note: if hexbin_args is supplied but key 'reduce_C_function' isn't supplied in dictionary, insert 'scipy.sum' function Note: allowed values are documented at: http://matplotlib.sourceforge.net/api/pyplot_api.html map_extent sets the extent of the displayed map if supplied (get extent from the data if not supplied) """ # decide if we have a 'gui-less' plot or not. import matplotlib if output_file and not show_graph: # no plot to be shown - no gui matplotlib.use('Agg', warn=False) elif show_graph: # decide if we *can* show the plot - error if not if sys.platform != 'win32': try: display = os.environ['DISPLAY'] except KeyError: msg = ("No DISPLAY variable set. " "Did you do 'ssh -X <machine>'?") raise RuntimeError(msg) # go ahead with the plot import matplotlib.pyplot as plt import matplotlib.colors as mcolors from mpl_toolkits.basemap import Basemap from matplotlib.mlab import griddata # create a 'binned' plot on a map if output_file or show_graph: # decide on the colormap to use (cmap_name, my_cmap) = uc.get_colormap(colormap) # set the hexbin params if hexbin_args is None: hexbin_args = {'gridsize': 100, 'reduce_C_function': scipy.sum, 'linewidth': DEFAULT_LINEWIDTH} try: _ = hexbin_args['reduce_C_function'] except KeyError: hexbin_args['reduce_C_function'] = scipy.sum # here we fiddle with 'linewidth' to get around a bug in plotting # if linewidth not set, hex bins overlap each other # force linewidth to a small value if not specified try: _ = hexbin_args['linewidth'] except KeyError: hexbin_args['linewidth'] = DEFAULT_LINEWIDTH # if user doesn't define 'edgecolors' at all, use default hexbin_args['edgecolors'] = hexbin_args.get('edgecolors', FILL_COLOUR) # get extent of point data if map_extent: extent = map_extent else: extent = gxe.get_extent(map_data, margin=5) (ll_lat, ll_lon, ur_lat, ur_lon) = extent # start the plot fig = plt.figure() ax = fig.add_subplot(111) # draw the map m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat, llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='h', suppress_ticks=False, area_thresh=0.5) # m = Basemap(projection='cass', llcrnrlat=ll_lat, urcrnrlat=ur_lat, # llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='h', # lat_0=(ll_lat+ur_lat)/2.0, lon_0=(ll_lon+ur_lon)/2.0, # suppress_ticks=False) #, area_thresh=0.5) # draw hexbin data on map plt.hexbin(map_data[:,0], map_data[:,1], map_data[:,2], cmap=my_cmap, zorder=4, **hexbin_args) # draw the other minor stuff m.fillcontinents(color=FILL_COLOUR, zorder=2) m.drawcoastlines(linewidth=0.25, color='k', zorder=5) m.drawmapboundary() cb = plt.colorbar(cmap=my_cmap, format=cbformat) cb.set_label(cblabel) plt.xlabel('longitude', fontsize=8) plt.ylabel('latitude', fontsize=8) # if user asked for a NORTH pointer if np_posn: unp.plot_northpointer(m, (ll_lat, ll_lon, ur_lat, ur_lon), np_posn) # add graph 'furniture' plt.title(title) plt.grid(grid, color='#C0C0C0', linestyle='-', linewidth=0.25) # add system annotations: time generated, etc if isinstance(annotate, list): pts.plot_timestamp(fig) # add user annotations, if any pua.plot_user_annotation(fig, annotate) # show or save graph (or both?) if output_file: plt.savefig(output_file, dpi=300) if show_graph: plt.show() plt.close()
def plot_hexbin_map(map_data, bins=100, title='', output_file=None, cblabel='', cbformat='%.1f', show_graph=False, grid=True, colormap=None, annotate=[], scale=None, np_posn=None, hexbin_args=None, map_extent=None): """Plot data into a hexgrid with an underlay map. Inputs: map_data (nx3) array containing the data to plot. The first column contains the latitude of a point, the second column contains the longitude and the third column is the value to bin&plot. bins Either a scalar (# bins in X and Y directions) or (nx, ny). title the graph title string output_file path of file to save plot picture in cblabel label to display on the colorbar cbformat format string used to show colormap values show_graph show graph on screen if True grid draw a grid on graph if True colormap if supplied, the colormap name to use (string) annotate an iterable like [(x, y, ann, dict), ...] where x is X screen coordinate y is Y screen coordinate ann is the annotation string to display at (x, y) dict is a dictionary of key/value pairs as documented at http://matplotlib.sourceforge.net/api/pyplot_api.html (this is optional) NOTE: if annotate=None is used, no automatic annotation occurs. if annotate=[] is used, auto annotation is generated: timestamp scale a tuple containing data used to draw a scale: (posn, length, scale_args) where 'posn' is where to place scale, one of: 'NW', 'NE', 'SW', 'SE' (case-insensitive) and 'scale_args' is an optional kwargs dictionary see drawmapscale() function at http://matplotlib.sourceforge.net/basemap/doc/html/api/basemap_api.html#mpl_toolkits.basemap.Basemap.drawmapscale to see values in scale_args np_posn position tuple or a string describing pointer position: 'NW', 'NE', 'SW' or 'SE' (case-insensitive) hexbin_args is a dictionary of hexbin() parameters if not supplied, assume {'gridsize': 100, 'reduce_C_function': scipy.sum } Note: if hexbin_args is supplied but key 'reduce_C_function' isn't supplied in dictionary, insert 'scipy.sum' function Note: allowed values are documented at: http://matplotlib.sourceforge.net/api/pyplot_api.html map_extent sets the extent of the displayed map if supplied (get extent from the data if not supplied) """ # decide if we have a 'gui-less' plot or not. import matplotlib if output_file and not show_graph: # no plot to be shown - no gui matplotlib.use('Agg', warn=False) elif show_graph: # decide if we *can* show the plot - error if not if sys.platform != 'win32': try: display = os.environ['DISPLAY'] except KeyError: msg = ("No DISPLAY variable set. " "Did you do 'ssh -X <machine>'?") raise RuntimeError(msg) # go ahead with the plot import matplotlib.pyplot as plt import matplotlib.colors as mcolors from mpl_toolkits.basemap import Basemap from matplotlib.mlab import griddata # create a 'binned' plot on a map if output_file or show_graph: # decide on the colormap to use (cmap_name, my_cmap) = uc.get_colormap(colormap) # set the hexbin params if hexbin_args is None: hexbin_args = { 'gridsize': 100, 'reduce_C_function': scipy.sum, 'linewidth': DEFAULT_LINEWIDTH } try: _ = hexbin_args['reduce_C_function'] except KeyError: hexbin_args['reduce_C_function'] = scipy.sum # here we fiddle with 'linewidth' to get around a bug in plotting # if linewidth not set, hex bins overlap each other # force linewidth to a small value if not specified try: _ = hexbin_args['linewidth'] except KeyError: hexbin_args['linewidth'] = DEFAULT_LINEWIDTH # if user doesn't define 'edgecolors' at all, use default hexbin_args['edgecolors'] = hexbin_args.get('edgecolors', FILL_COLOUR) # get extent of point data if map_extent: extent = map_extent else: extent = gxe.get_extent(map_data, margin=5) (ll_lat, ll_lon, ur_lat, ur_lon) = extent # start the plot fig = plt.figure() ax = fig.add_subplot(111) # draw the map m = Basemap(projection='cyl', llcrnrlat=ll_lat, urcrnrlat=ur_lat, llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='h', suppress_ticks=False, area_thresh=0.5) # m = Basemap(projection='cass', llcrnrlat=ll_lat, urcrnrlat=ur_lat, # llcrnrlon=ll_lon, urcrnrlon=ur_lon, resolution='h', # lat_0=(ll_lat+ur_lat)/2.0, lon_0=(ll_lon+ur_lon)/2.0, # suppress_ticks=False) #, area_thresh=0.5) # draw hexbin data on map plt.hexbin(map_data[:, 0], map_data[:, 1], map_data[:, 2], cmap=my_cmap, zorder=4, **hexbin_args) # draw the other minor stuff m.fillcontinents(color=FILL_COLOUR, zorder=2) m.drawcoastlines(linewidth=0.25, color='k', zorder=5) m.drawmapboundary() cb = plt.colorbar(cmap=my_cmap, format=cbformat) cb.set_label(cblabel) plt.xlabel('longitude', fontsize=8) plt.ylabel('latitude', fontsize=8) # if user asked for a NORTH pointer if np_posn: unp.plot_northpointer(m, (ll_lat, ll_lon, ur_lat, ur_lon), np_posn) # add graph 'furniture' plt.title(title) plt.grid(grid, color='#C0C0C0', linestyle='-', linewidth=0.25) # add system annotations: time generated, etc if isinstance(annotate, list): pts.plot_timestamp(fig) # add user annotations, if any pua.plot_user_annotation(fig, annotate) # show or save graph (or both?) if output_file: plt.savefig(output_file, dpi=300) if show_graph: plt.show() plt.close()