def plot_3D_alt(ax, x_data, alt_data, z_data, x_name, x_scale, x_units, alt_units, z_name, z_scale, z_units, xmin=None, xmax=None, amin=None, amax=None, zmin=None, zmax=None, xinc=6, ainc=6, zinc=6, cb=True, cloc="r", color=True, zcenter=False, title=None, tloc="t", xl=True, xt=True, yl=True, yt=True, plot_type="contour", *args, **kwargs): ''' Creates a single polar projection, with the latitude center and range determined by the input. Input: ax = axis handle x_data = 2D numpy array containing x-axis data alt_data = 2D numpy array containing y-axis altitude data z_data = 1D or 2D numpy array containing data to plot using a color scale x_name = Name of x-axis data x_scale = Plot x-axis data using a linear or exponetial scale? x_units = x-axis data units alt_units = y-axis altitude units (m or km) z_name = Name of z-axis data z_scale = Plot z-axis data using a linear or exponetial scale? z_units = z-axis data units xmin = minimum value for x variable (default=None) xmax = maximum value for x variable (default=None) amin = minimum value for altitude (default=None) amax = maximum value for altitude (default=None) zmin = minimum value for z variable (default=None) zmax = maximum value for z variable (default=None) xinc = number of tick incriments for x variable (default 6) ainc = number of tick incriments for altitude (default 6) zinc = number of tick incriments for z variable (default 6) cb = Add a colorbar (default is True) cloc = Colorbar location (t=top, r=right, l=left, b=bottom, default is right) color = Color plot or B&W (default is True for color) zcenter = Should the z range be centered about zero (default is False, for uncentered) title = plot title (default is none) tloc = title location (t=top, r=right, l=left, b=bottom, default is top) xl = Include x label (default is True) xt = Include x ticks (default is True) yl = Include y label. This defaults to placing an altitude label on the left axis. If a non-Boolian value is provided, it is assumed to be a string that will be used as a right axis label. (default is True) yt = Include y ticks (default is True) plot_type = Make a scatter or contour plot? (default=contour) ''' # Set the x, a, and z ranges if (xmin is None): xmin = np.nanmin(x_data) if (xmax is None): xmax = np.nanmax(x_data) arange = xmax - xmin xwidth = arange / xinc if (zmin is None): zmin = np.nanmin(z_data) if (zmax is None): zmax = np.nanmax(z_data) if zcenter and abs(zmin) != zmax: arange = max(abs(zmin), zmax) zmax = arange zmin = -1.0 * arange arange = zmax - zmin zwidth = arange / zinc if (amin is None): amin = np.nanmin(alt_data) if (amax is None): amax = np.nanmax(alt_data) arange = amax - amin awidth = arange / ainc # Determine the z scale if z_scale.find("exp") >= 0: v = np.logspace(math.log10(zmin), math.log10(zmax), zinc * 10, endpoint=True) norm = LogNorm(vmin=zmin, vmax=zmax) else: norm = None v = np.linspace(zmin, zmax, zinc * 10, endpoint=True) # Plot the data col = gpr.choose_contour_map(color, zcenter) if plot_type.find("scatter") >= 0: con = ax.scatter(x_data, alt_data, c=z_data, cmap=get_cmap(col), norm=norm, vmin=zmin, vmax=zmax, edgecolors="none", s=10) cax = con.axes else: con = ax.contourf(x_data, alt_data, z_data, v, cmap=get_cmap(col), norm=norm, vmin=zmin, vmax=zmax) cax = con.ax # Configure axis if yt: ytics = MultipleLocator(awidth) ax.yaxis.set_major_locator(ytics) else: ax.yaxis.set_major_formatter(FormatStrFormatter("")) if yl is True: ax.set_ylabel('Altitude ($km$)') elif yl is not False: ax.set_ylabel(yl) ax.yaxis.set_label_position("right") plt.ylim(amin, amax) if x_scale.find("exponential") >= 0: ax.set_xscale('log') elif xt: xtics = MultipleLocator(xwidth) ax.xaxis.set_major_locator(xtics) else: ax.xaxis.set_major_formatter(FormatStrFormatter("")) if xl: ax.set_xlabel(r'%s ($%s$)' % (x_name, x_units)) plt.xlim(xmin, xmax) # Set the title if title: rot = 'horizontal' yloc = 1.05 xloc = 0.5 if tloc == "b": yloc = -.1 elif tloc != "t": rot = 'vertical' yloc = 0.5 xloc = -.2 if tloc == "r": xloc = 1.1 title = ax.set_title(title, y=yloc, size='medium', x=xloc, rotation=rot) # Change the background color ax.patch.set_facecolor('#747679') # Add a colorbar if cb: orient = 'vertical' if (cloc == 't' or cloc == 'b'): orient = 'horizontal' cbar = gpr.add_colorbar(con, zmin, zmax, zinc, orient, z_scale, z_name, z_units) if (cloc == 'l' or cloc == 't'): bp = list(cbar.ax.get_position().bounds) cp = list(cax.get_position().bounds) if (cloc == 't'): cp[1] = bp[1] bp[1] = cp[1] + cp[3] + 0.085 else: bp[0] = 0.125 cp[0] = bp[0] + 0.1 + bp[2] cax.set_position(cp) cbar.ax.set_position(bp) return con
def plot_3D_alt(ax, x_data, alt_data, z_data, x_name, x_scale, x_units, alt_units, z_name, z_scale, z_units, xmin=None, xmax=None, amin=None, amax=None, zmin=None, zmax=None, xinc=6, ainc=6, zinc=6, cb=True, cloc="r", color=True, zcenter=False, title=None, tloc="t", xl=True, xt=True, yl=True, yt=True, plot_type="contour", *args, **kwargs): ''' Creates a single polar projection, with the latitude center and range determined by the input. Input: ax = axis handle x_data = 2D numpy array containing x-axis data alt_data = 2D numpy array containing y-axis altitude data z_data = 1D or 2D numpy array containing data to plot using a color scale x_name = Name of x-axis data x_scale = Plot x-axis data using a linear or exponetial scale? x_units = x-axis data units alt_units = y-axis altitude units (m or km) z_name = Name of z-axis data z_scale = Plot z-axis data using a linear or exponetial scale? z_units = z-axis data units xmin = minimum value for x variable (default=None) xmax = maximum value for x variable (default=None) amin = minimum value for altitude (default=None) amax = maximum value for altitude (default=None) zmin = minimum value for z variable (default=None) zmax = maximum value for z variable (default=None) xinc = number of tick incriments for x variable (default 6) ainc = number of tick incriments for altitude (default 6) zinc = number of tick incriments for z variable (default 6) cb = Add a colorbar (default is True) cloc = Colorbar location (t=top, r=right, l=left, b=bottom, default is right) color = Color plot or B&W (default is True for color) zcenter = Should the z range be centered about zero (default is False, for uncentered) title = plot title (default is none) tloc = title location (t=top, r=right, l=left, b=bottom, default is top) xl = Include x label (default is True) xt = Include x ticks (default is True) yl = Include y label. This defaults to placing an altitude label on the left axis. If a non-Boolian value is provided, it is assumed to be a string that will be used as a right axis label. (default is True) yt = Include y ticks (default is True) plot_type = Make a scatter or contour plot? (default=contour) ''' # Set the x, a, and z ranges if(xmin is None): xmin = np.nanmin(x_data) if(xmax is None): xmax = np.nanmax(x_data) arange = xmax - xmin xwidth = arange / xinc if(zmin is None): zmin = np.nanmin(z_data) if(zmax is None): zmax = np.nanmax(z_data) if zcenter and abs(zmin) != zmax: arange = max(abs(zmin), zmax) zmax = arange zmin = -1.0 * arange arange = zmax - zmin zwidth = arange / zinc if(amin is None): amin = np.nanmin(alt_data) if(amax is None): amax = np.nanmax(alt_data) arange = amax - amin awidth = arange / ainc # Determine the z scale if z_scale.find("exp") >= 0: v = np.logspace(math.log10(zmin), math.log10(zmax), zinc*10, endpoint=True) norm = LogNorm(vmin=zmin, vmax=zmax) else: norm = None v = np.linspace(zmin, zmax, zinc*10, endpoint=True) # Plot the data col = gpr.choose_contour_map(color, zcenter) if plot_type.find("scatter") >= 0: con = ax.scatter(x_data, alt_data, c=z_data, cmap=get_cmap(col), norm=norm, vmin=zmin, vmax=zmax, edgecolors="none", s=10) cax = con.axes else: con = ax.contourf(x_data, alt_data, z_data, v, cmap=get_cmap(col), norm=norm, vmin=zmin, vmax=zmax) cax = con.ax # Configure axis if yt: ytics = MultipleLocator(awidth) ax.yaxis.set_major_locator(ytics) else: ax.yaxis.set_major_formatter(FormatStrFormatter("")) if yl is True: ax.set_ylabel('Altitude ($km$)') elif yl is not False: ax.set_ylabel(yl) ax.yaxis.set_label_position("right") plt.ylim(amin, amax) if x_scale.find("exponential") >= 0: ax.set_xscale('log') elif xt: xtics = MultipleLocator(xwidth) ax.xaxis.set_major_locator(xtics) else: ax.xaxis.set_major_formatter(FormatStrFormatter("")) if xl: ax.set_xlabel(r'%s ($%s$)' % (x_name, x_units)) plt.xlim(xmin, xmax) # Set the title if title: rot = 'horizontal' yloc = 1.05 xloc = 0.5 if tloc == "b": yloc = -.1 elif tloc != "t": rot = 'vertical' yloc = 0.5 xloc = -.2 if tloc == "r": xloc = 1.1 title = ax.set_title(title,y=yloc,size='medium',x=xloc,rotation=rot) # Change the background color ax.patch.set_facecolor('#747679') # Add a colorbar if cb: orient = 'vertical' if(cloc == 't' or cloc == 'b'): orient = 'horizontal' cbar = gpr.add_colorbar(con, zmin, zmax, zinc, orient, z_scale, z_name, z_units) if(cloc == 'l' or cloc == 't'): bp = list(cbar.ax.get_position().bounds) cp = list(cax.get_position().bounds) if(cloc == 't'): cp[1] = bp[1] bp[1] = cp[1] + cp[3] + 0.085 else: bp[0] = 0.125 cp[0] = bp[0] + 0.1 + bp[2] cax.set_position(cp) cbar.ax.set_position(bp) return con
def plot_net_gitm_comp(plot_type, lon_data, lat_data, obs_data, obs_name, obs_scale, obs_units, diff_data, diff_name, diff_scale, diff_units, gitm_key, gitm_alt, gdata, gitm_name, diff_max=None, zmax=None, zmin=None, title=None, color=True, bcolor='#747679', data_coff=False, diff_coff=True, figname=None, draw=True, latlim1=90, latlim2=-90, linc=6, tlon=90, meq=False, earth=False, map_list=[], faspect=True, term_datetime=None, extra_lines=False, *args, **kwargs): ''' Creates three plots of a specified type, one showing the observations, one showing the GITM data, and one showing the difference between the two. Input: plot_type = key to determine plot type (rectangular, polar, nsglobal, or snapshot) lon_data = Numpy array with longitude data for matching model-obs points lat_data = Numpy array with latitude data for matching model-obs points obs_data = Numpy array with observational data for matching model-obs points obs_name = Name portion of the observational data label obs_scale = Scale (linear/exponential) for plotting obs. data obs_units = Unit portion of the observational data label diff_data = Numpy array with differences for matching model-obs points gitm_key = Key for the GITM data gitm_alt = Altitude in km to plot the GITM data at. For a 2D variable like hmF2 or TEC, use 0.0 km. gdata = GitmBin structure with model observations. gitm_name = Name portion of the GITM data label diff_max = Maximum value for the difference (absolute value), if None, will be determined in script (default=None) zmin = minimum value for z variable (default=None) zmax = maximum value for z variable (default=None) title = Plot title (default=None) color = Color (True, default) or black and white (False)? bcolor = Background color (default=) data_coff = Center the data color scale about zero (False, default)? diff_coff = Center the diff color scale about zero (True, default)? figname = Output figure name with a .png suffix (default=None) draw = Draw to screen? (default=True) latlim1 = First latitude limit (degrees North, default=90). Purpose varies depending on plot type. For rectangular, this is the northern latitude limit. For polar, this is the latitude at the center of the dial. For snapshot, this is the lower boundary of polar dials. It is not used for nsglobal. latlim2 = Second latitude limit (degrees North, default=-90). Purpose varies depending on plot type. For rectangular, this is the southern latitude limit. For polar, this is the latitude at the edge of the dial. This option is not used with the snapshot or nsglobal option. linc = Number of latitude tick incriments (default=6) tlon = Longitude on top of the polar dial (degrees East, default=90) meq = Add a line for the geomagnetic equator? (default=False) earth = Include continent outlines for Earth (default=False) map_list = List of map handles for the specified plot_type (default=empty list) faspect = Keep a true aspect ratio for maps? (default=True) term_datetime = Include the solar terminator by shading the night time regions? If so, include a datetime object with the UT for this map. Only used if earth=True. extra_lines = Plot a specified lines (good for showing regional boundaries) (default=False). Provide a list of lists which have the format shown: [x np.array, y np.array, style string (eg 'k-')] where x is in degrees longitude and y is in degrees latitude Output: f = handle to figure ''' rout_name = "plot_net_gitm_comp" # Get the desired color bars data_color = gpr.choose_contour_map(color, data_coff) diff_color = gpr.choose_contour_map(color, diff_coff) # Get the altitude index ialt = 0 if gitm_alt > 0.0: ialt = gpr.find_alt_index(gdata, 0, 0, alt, units="km") # Initialize the z variables, if desired. GITM and Observational data # should share the same scale. if(zmin is None): obsmin = np.nanmin(obs_data) gitmin = np.nanmin(gdata[gitm_key][:,:,ialt]) zmin = min(obsmin,gitmin) if(zmax is None): obsmax = np.nanmax(obs_data) gitmax = np.nanmax(gdata[gitm_key][:,:,ialt]) zmax = max(obsmax, gitmax) zran = round((zmax-zmin)/6.0) if(zran != 0.0): zmin = math.floor(float("{:.14f}".format(zmin / zran))) * zran zmax = math.ceil(float("{:.14f}".format(zmax / zran))) * zran # Set the difference max/min limits, if desired if diff_max is None: diff_max = max(np.nanmax(diff_data), abs(np.nanmin(diff_data))) diff_min = -1.0 * diff_max # Initialize the figure, setting the height for a 3 subfigure stack fwidth = 6 fheight = 12 if(plot_type.find("global") > 0): fwidth *= 1.5 if(plot_type.find("shot") > 0): fwidth *= 1.5 fheight *= 1.5 f = plt.figure(figsize=(fwidth,fheight)) # Plot the three datasets using the desired format if plot_type.find("shot") > 0: if len(map_list) == 3: ml = map_list[0] mn = map_list[1] ms = map_list[2] else: ml = None mn = None ms = None # Output the observations as a scatter plot axl,ml,axn,mn,axs,ms = p3g.plot_snapshot_subfigure(f, 3, 0, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmax, zmin, data_color, tlon=tlon, blat=latlim1, xl=False, yl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour after ensuring that the GITM array # isn't padded to include unrealistic latitudes (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 p3g.plot_snapshot_subfigure(f, 3, 1, np.array(gdata['dLat'][:,imin:imax,ialt]), np.array(gdata['dLon'][:,imin:imax,ialt]), np.array(gdata[gitm_key][:,imin:imax,ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmax, zmin, data_color, cb=True, cloc="r", tlon=tlon, blat=latlim1, title=False, xl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, data_type="contour", term_datetime=term_datetime) # Output the differences as a scatter plot p3g.plot_snapshot_subfigure(f, 3, 2, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_max, diff_min, diff_color, tlon=tlon, blat=latlim1, title=False, yl=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime) map_list = list([ml, mn, ms]) elif plot_type.find("nsglobal") >= 0: if len(map_list) == 2: mn = map_list[0] ms = map_list[1] else: mn = None ms = None # Check for boundary lines to plot eline_north = False eline_south = False if type(extra_lines) is list: if len(extra_lines) >= 1: eline_north = extra_lines[0] if len(extra_lines) >= 2: eline_south = extra_lines[1] else: print "Only one boundary provided, plotting in north" else: print "No boundaries provided, better to declare as False" # Output the observations as a scatter plot axn1,mn,axs1,ms = p3g.plot_nsglobal_subfigure(f, 3, 0, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmax, zmin, data_color, title=True, cb=True, elat=latlim1, tlon=tlon, rl=False, tl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) # Output the gitm data as a contour after ensuring that the GITM array # isn't padded to include unrealistic latitudes (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 axn2,mn,axs2,ms = p3g.plot_nsglobal_subfigure(f, 3, 1, np.array(gdata['dLat'][:,imin:imax,ialt]), np.array(gdata['dLon'][:,imin:imax,ialt]), np.array(gdata[gitm_key][:,imin:imax,ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmax, zmin, data_color, title=False, cb=True, elat=latlim1, tlon=tlon, tl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, data_type="contour", term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) # Output the differences as a scatter plot p3g.plot_nsglobal_subfigure(f, 3, 2, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_max, diff_min, diff_color, title=False, cb=True, elat=latlim1, tlon=tlon, rl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) map_list = list([mn, ms]) elif plot_type.find("rect") >= 0: if len(map_list) == 1: m = map_list[0] else: m = None # Output the observations as a scatter plot ax = f.add_subplot(3,1,1) con1, m = p3g.plot_rectangular_3D_global(ax, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmin, zmax, data_color, nlat=latlim1, slat=latlim2, linc=linc, cloc="r", xl=False, xt=False, yl=False, meq=meq, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour ax = f.add_subplot(3,1,2) con2, m = p3g.plot_rectangular_3D_global(ax, np.array(gdata['dLat'][:,:,ialt]), np.array(gdata['dLon'][:,:,ialt]), np.array(gdata[gitm_key][:,:,ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmin, zmax, data_color, nlat=latlim1, slat=latlim2, linc=linc, cb=True, cloc="r", xl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, m=m, faspect=faspect, data_type="contour", term_datetime=term_datetime) # Adjust plot dimensions if necessary if not earth: con1_dim = list(con1.axes.get_position().bounds) con2_dim = list(con2.ax.get_position().bounds) con2_dim[2] = con1_dim[2] con2.ax.set_position(con2_dim) # Output the differences as a scatter plot ax = f.add_subplot(3,1,3) p3g.plot_rectangular_3D_global(ax, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_min, diff_max, diff_color, nlat=latlim1, slat=latlim2, linc=linc, cloc="r", yl=False, bcolor=bcolor, meq=meq, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) map_list = list([m]) elif plot_type.find("polar") >= 0: if len(map_list) == 1: m = map_list[0] else: m = None pf = True if earth: pf = False # Output the observations as a scatter plot ax = f.add_subplot(3,1,1, polar=pf) con1,m = p3g.plot_polar_3D_global(ax, 3, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmin, zmax, data_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cloc="r", tl=False, rl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour after ensuring that the GITM # array isn't padded to include unrealistic latitudes ax = f.add_subplot(3,1,2, polar=pf) (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 con2,m = p3g.plot_polar_3D_global(ax, 3, np.array(gdata['dLat'][:,imin:imax,ialt]), np.array(gdata['dLon'][:,imin:imax,ialt]), np.array(gdata[gitm_key][:,imin:imax,ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmin, zmax, data_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cb=True, cloc="r", tl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, data_type="contour", term_datetime=term_datetime) con1_dim = list(con1.axes.get_position().bounds) con2_dim = list(con2.ax.get_position().bounds) con2_dim[0] = con2_dim[0] - 0.05 con2_dim[2] = con1_dim[2] con2.ax.set_position(con2_dim) # Output the differences as a scatter plot ax = f.add_subplot(3,1,3, polar=pf) p3g.plot_polar_3D_global(ax, 3, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_min, diff_max, diff_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cloc="r", rl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) map_list = list([m]) else: print rout_name, "ERROR: uknown plot type [", plot_type, "]" return if title: f.suptitle(title, size="medium") # Adjust subplot locations if plot_type.find("rect") >= 0 or plot_type.find("polar") >= 0: plt.subplots_adjust(left=.15) # Draw to screen if desired if draw: if plt.isinteractive(): plt.draw() #In interactive mode, you just "draw". else: # W/o interactive mode, "show" stops the user from typing more # at the terminal until plots are drawn. plt.show() # Save output file if figname is not None: plt.savefig(figname) return(f, map_list)
def plot_net_gitm_comp(plot_type, lon_data, lat_data, obs_data, obs_name, obs_scale, obs_units, diff_data, diff_name, diff_scale, diff_units, gitm_key, gitm_alt, gdata, gitm_name, diff_max=None, zmax=None, zmin=None, title=None, color=True, bcolor='#747679', data_coff=False, diff_coff=True, figname=None, draw=True, latlim1=90, latlim2=-90, linc=6, tlon=90, meq=False, earth=False, map_list=[], faspect=True, term_datetime=None, extra_lines=False, *args, **kwargs): ''' Creates three plots of a specified type, one showing the observations, one showing the GITM data, and one showing the difference between the two. Input: plot_type = key to determine plot type (rectangular, polar, nsglobal, or snapshot) lon_data = Numpy array with longitude data for matching model-obs points lat_data = Numpy array with latitude data for matching model-obs points obs_data = Numpy array with observational data for matching model-obs points obs_name = Name portion of the observational data label obs_scale = Scale (linear/exponential) for plotting obs. data obs_units = Unit portion of the observational data label diff_data = Numpy array with differences for matching model-obs points gitm_key = Key for the GITM data gitm_alt = Altitude in km to plot the GITM data at. For a 2D variable like hmF2 or TEC, use 0.0 km. gdata = GitmBin structure with model observations. gitm_name = Name portion of the GITM data label diff_max = Maximum value for the difference (absolute value), if None, will be determined in script (default=None) zmin = minimum value for z variable (default=None) zmax = maximum value for z variable (default=None) title = Plot title (default=None) color = Color (True, default) or black and white (False)? bcolor = Background color (default=) data_coff = Center the data color scale about zero (False, default)? diff_coff = Center the diff color scale about zero (True, default)? figname = Output figure name with a .png suffix (default=None) draw = Draw to screen? (default=True) latlim1 = First latitude limit (degrees North, default=90). Purpose varies depending on plot type. For rectangular, this is the northern latitude limit. For polar, this is the latitude at the center of the dial. For snapshot, this is the lower boundary of polar dials. It is not used for nsglobal. latlim2 = Second latitude limit (degrees North, default=-90). Purpose varies depending on plot type. For rectangular, this is the southern latitude limit. For polar, this is the latitude at the edge of the dial. This option is not used with the snapshot or nsglobal option. linc = Number of latitude tick incriments (default=6) tlon = Longitude on top of the polar dial (degrees East, default=90) meq = Add a line for the geomagnetic equator? (default=False) earth = Include continent outlines for Earth (default=False) map_list = List of map handles for the specified plot_type (default=empty list) faspect = Keep a true aspect ratio for maps? (default=True) term_datetime = Include the solar terminator by shading the night time regions? If so, include a datetime object with the UT for this map. Only used if earth=True. extra_lines = Plot a specified lines (good for showing regional boundaries) (default=False). Provide a list of lists which have the format shown: [x np.array, y np.array, style string (eg 'k-')] where x is in degrees longitude and y is in degrees latitude Output: f = handle to figure ''' rout_name = "plot_net_gitm_comp" # Get the desired color bars data_color = gpr.choose_contour_map(color, data_coff) diff_color = gpr.choose_contour_map(color, diff_coff) # Get the altitude index ialt = 0 if gitm_alt > 0.0: ialt = gpr.find_alt_index(gdata, 0, 0, alt, units="km") # Initialize the z variables, if desired. GITM and Observational data # should share the same scale. if (zmin is None): obsmin = np.nanmin(obs_data) gitmin = np.nanmin(gdata[gitm_key][:, :, ialt]) zmin = min(obsmin, gitmin) if (zmax is None): obsmax = np.nanmax(obs_data) gitmax = np.nanmax(gdata[gitm_key][:, :, ialt]) zmax = max(obsmax, gitmax) zran = round((zmax - zmin) / 6.0) if (zran != 0.0): zmin = math.floor(float("{:.14f}".format(zmin / zran))) * zran zmax = math.ceil(float("{:.14f}".format(zmax / zran))) * zran # Set the difference max/min limits, if desired if diff_max is None: diff_max = max(np.nanmax(diff_data), abs(np.nanmin(diff_data))) diff_min = -1.0 * diff_max # Initialize the figure, setting the height for a 3 subfigure stack fwidth = 6 fheight = 12 if (plot_type.find("global") > 0): fwidth *= 1.5 if (plot_type.find("shot") > 0): fwidth *= 1.5 fheight *= 1.5 f = plt.figure(figsize=(fwidth, fheight)) # Plot the three datasets using the desired format if plot_type.find("shot") > 0: if len(map_list) == 3: ml = map_list[0] mn = map_list[1] ms = map_list[2] else: ml = None mn = None ms = None # Output the observations as a scatter plot axl, ml, axn, mn, axs, ms = p3g.plot_snapshot_subfigure( f, 3, 0, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmax, zmin, data_color, tlon=tlon, blat=latlim1, xl=False, yl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour after ensuring that the GITM array # isn't padded to include unrealistic latitudes (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 p3g.plot_snapshot_subfigure(f, 3, 1, np.array(gdata['dLat'][:, imin:imax, ialt]), np.array(gdata['dLon'][:, imin:imax, ialt]), np.array(gdata[gitm_key][:, imin:imax, ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmax, zmin, data_color, cb=True, cloc="r", tlon=tlon, blat=latlim1, title=False, xl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, data_type="contour", term_datetime=term_datetime) # Output the differences as a scatter plot p3g.plot_snapshot_subfigure(f, 3, 2, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_max, diff_min, diff_color, tlon=tlon, blat=latlim1, title=False, yl=False, bcolor=bcolor, meq=meq, earth=earth, ml=ml, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime) map_list = list([ml, mn, ms]) elif plot_type.find("nsglobal") >= 0: if len(map_list) == 2: mn = map_list[0] ms = map_list[1] else: mn = None ms = None # Check for boundary lines to plot eline_north = False eline_south = False if type(extra_lines) is list: if len(extra_lines) >= 1: eline_north = extra_lines[0] if len(extra_lines) >= 2: eline_south = extra_lines[1] else: print "Only one boundary provided, plotting in north" else: print "No boundaries provided, better to declare as False" # Output the observations as a scatter plot axn1, mn, axs1, ms = p3g.plot_nsglobal_subfigure( f, 3, 0, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmax, zmin, data_color, title=True, cb=True, elat=latlim1, tlon=tlon, rl=False, tl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) # Output the gitm data as a contour after ensuring that the GITM array # isn't padded to include unrealistic latitudes (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 axn2, mn, axs2, ms = p3g.plot_nsglobal_subfigure( f, 3, 1, np.array(gdata['dLat'][:, imin:imax, ialt]), np.array(gdata['dLon'][:, imin:imax, ialt]), np.array(gdata[gitm_key][:, imin:imax, ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmax, zmin, data_color, title=False, cb=True, elat=latlim1, tlon=tlon, tl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, data_type="contour", term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) # Output the differences as a scatter plot p3g.plot_nsglobal_subfigure(f, 3, 2, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_max, diff_min, diff_color, title=False, cb=True, elat=latlim1, tlon=tlon, rl=False, bcolor=bcolor, earth=earth, mn=mn, ms=ms, faspect=faspect, term_datetime=term_datetime, extra_line_n=eline_north, extra_line_s=eline_south) map_list = list([mn, ms]) elif plot_type.find("rect") >= 0: if len(map_list) == 1: m = map_list[0] else: m = None # Output the observations as a scatter plot ax = f.add_subplot(3, 1, 1) con1, m = p3g.plot_rectangular_3D_global(ax, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmin, zmax, data_color, nlat=latlim1, slat=latlim2, linc=linc, cloc="r", xl=False, xt=False, yl=False, meq=meq, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour ax = f.add_subplot(3, 1, 2) con2, m = p3g.plot_rectangular_3D_global( ax, np.array(gdata['dLat'][:, :, ialt]), np.array(gdata['dLon'][:, :, ialt]), np.array(gdata[gitm_key][:, :, ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmin, zmax, data_color, nlat=latlim1, slat=latlim2, linc=linc, cb=True, cloc="r", xl=False, xt=False, bcolor=bcolor, meq=meq, earth=earth, m=m, faspect=faspect, data_type="contour", term_datetime=term_datetime) # Adjust plot dimensions if necessary if not earth: con1_dim = list(con1.axes.get_position().bounds) con2_dim = list(con2.ax.get_position().bounds) con2_dim[2] = con1_dim[2] con2.ax.set_position(con2_dim) # Output the differences as a scatter plot ax = f.add_subplot(3, 1, 3) p3g.plot_rectangular_3D_global(ax, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_min, diff_max, diff_color, nlat=latlim1, slat=latlim2, linc=linc, cloc="r", yl=False, bcolor=bcolor, meq=meq, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) map_list = list([m]) elif plot_type.find("polar") >= 0: if len(map_list) == 1: m = map_list[0] else: m = None pf = True if earth: pf = False # Output the observations as a scatter plot ax = f.add_subplot(3, 1, 1, polar=pf) con1, m = p3g.plot_polar_3D_global(ax, 3, lat_data, lon_data, obs_data, obs_name, obs_scale, obs_units, zmin, zmax, data_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cloc="r", tl=False, rl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) # Output the gitm data as a contour after ensuring that the GITM # array isn't padded to include unrealistic latitudes ax = f.add_subplot(3, 1, 2, polar=pf) (i, imin) = gpr.find_lon_lat_index(gdata, 0.0, -90.0, "degrees") (i, imax) = gpr.find_lon_lat_index(gdata, 0.0, 90.0, "degrees") imax += 1 con2, m = p3g.plot_polar_3D_global(ax, 3, np.array(gdata['dLat'][:, imin:imax, ialt]), np.array(gdata['dLon'][:, imin:imax, ialt]), np.array(gdata[gitm_key][:, imin:imax, ialt]), gitm_name, gdata[gitm_key].attrs["scale"], gdata[gitm_key].attrs["units"], zmin, zmax, data_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cb=True, cloc="r", tl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, data_type="contour", term_datetime=term_datetime) con1_dim = list(con1.axes.get_position().bounds) con2_dim = list(con2.ax.get_position().bounds) con2_dim[0] = con2_dim[0] - 0.05 con2_dim[2] = con1_dim[2] con2.ax.set_position(con2_dim) # Output the differences as a scatter plot ax = f.add_subplot(3, 1, 3, polar=pf) p3g.plot_polar_3D_global(ax, 3, lat_data, lon_data, diff_data, diff_name, diff_scale, diff_units, diff_min, diff_max, diff_color, center_lat=latlim1, edge_lat=latlim2, linc=linc, top_lon=tlon, cloc="r", rl=False, bcolor=bcolor, earth=earth, m=m, faspect=faspect, term_datetime=term_datetime) map_list = list([m]) else: print rout_name, "ERROR: uknown plot type [", plot_type, "]" return if title: f.suptitle(title, size="medium") # Adjust subplot locations if plot_type.find("rect") >= 0 or plot_type.find("polar") >= 0: plt.subplots_adjust(left=.15) # Draw to screen if desired if draw: if plt.isinteractive(): plt.draw() #In interactive mode, you just "draw". else: # W/o interactive mode, "show" stops the user from typing more # at the terminal until plots are drawn. plt.show() # Save output file if figname is not None: plt.savefig(figname) return (f, map_list)