def plot_ima_mass_matrix(start, finish, product=None, colorbar=True, ax=None, blocks=None, **kwargs): """ Integrate to produce a mass-matrix from start-finish, processing azimuths""" if (finish - start) < aspera_scan_time: raise ValueError("Duration too short: %d" % (finish - start)) if not blocks: blocks = read_ima(start, finish, **kwargs) if ax is None: ax = plt.gca() plt.sca(ax) products_to_process = ("CO2", "H", "O", "Hsp", "alpha", "O2", "He") if product: if not hasattr(product, "__iter__"): products_to_process = [product] else: products_to_process = product img = np.zeros_like(blocks[0]["sumions"]) for b in blocks: inx, = np.where((b["tmptime"] > start) & (b["tmptime"] < finish)) if inx.shape[0]: for p in products_to_process: img += np.sum(b[p][:, :, inx], 2) plt.imshow(img, origin="lower") if colorbar: plt.colorbar(cax=celsius.make_colorbar_cax()) return img
def plot_timeseries(self, ax=None, vmin=None, vmax=None, colorbar=False, label=True): if vmin is None: vmin = self.vmin if vmax is None: vmax = self.vmax if ax is None: ax = plt.gca() plt.sca(ax) plt.cla() plt.imshow(self.tser_arr[::-1,:], vmin=vmin, vmax=vmax, interpolation='Nearest', extent=self.extent, origin='upper',aspect='auto') plt.xlim(self.extent[0], self.extent[1]) plt.ylim(self.extent[2], self.extent[3]) # plt.vlines(self.ionogram_list[0].time, self.extent[2], self.extent[3], 'r') if label: celsius.ylabel('f / MHz') if colorbar: old_ax = plt.gca() plt.colorbar( cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks ).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$") plt.sca(old_ax)
def plot_frequency_altitude(self, f=2.0, ax=None, median_filter=False, vmin=None, vmax=None, altitude_range=(-99.9, 399.9), colorbar=False, return_image=False, annotate=True): if vmin is None: vmin = self.vmin if vmax is None: vmax = self.vmax if ax is None: ax = plt.gca() plt.sca(ax) plt.cla() freq_extent = (self.extent[0], self.extent[1], altitude_range[1], altitude_range[0]) i = self.ionogram_list[0] inx = 1.0E6* (i.frequencies.shape[0] * f) / (i.frequencies[-1] - i.frequencies[0]) img = self.tser_arr_all[:,int(inx),:] new_altitudes = np.arange(altitude_range[0], altitude_range[1], 14.) new_img = np.zeros((new_altitudes.shape[0], img.shape[1])) + np.nan for i in self.ionogram_list: e = int( round((i.time - self.extent[0]) / ais_code.ais_spacing_seconds )) pos = mex.iau_r_lat_lon_position(float(i.time)) altitudes = pos[0] - ais_code.speed_of_light_kms * ais_code.ais_delays * 0.5 - mex.mars_mean_radius_km s = np.argsort(altitudes) new_img[:, e] = np.interp(new_altitudes, altitudes[s], img[s,e], left=np.nan, right=np.nan) plt.imshow(new_img, vmin=vmin, vmax=vmax, interpolation='Nearest', extent=freq_extent, origin='upper', aspect='auto') plt.xlim(freq_extent[0], freq_extent[1]) plt.ylim(*altitude_range) ax.set_xlim(self.extent[0], self.extent[1]) ax.xaxis.set_major_locator(celsius.SpiceetLocator()) celsius.ylabel(r'Alt./km') if annotate: plt.annotate('f = %.1f MHz' % f, (0.02, 0.9), xycoords='axes fraction', color='cyan', verticalalignment='top', fontsize='small') if colorbar: old_ax = plt.gca() plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$") plt.sca(old_ax) if return_image: return new_img, freq_extent, new_altitudes
def plot_profiles(self, ax=None, vmin=4., vmax=5.5, cmap=None, cmticks=None, log=True, substitute_fp=None, **kwargs): """ Inverts the profiles, plots them versus time and altitude, color coded to density Does not show the 'first step' between the S/C plasma density and the first reflection """ if ax is None: ax = plt.gca() plt.sca(ax) ax.set_axis_bgcolor("gray") if cmap is None: cmap = matplotlib.cm.hot if cmticks is None: cmticks = [3, 4, 5, 6] n_profiles = int((self.extent[1] - self.extent[0]) / ais_code.ais_spacing_seconds) + 1 ranges = np.arange(80., 350., 1.) times = np.arange(self.extent[0], self.extent[1], ais_code.ais_spacing_seconds) img = np.zeros((len(times), len(ranges))) + np.nan label = r'$n_e$ / cm$^{-3}$' if log: f = np.log10 label = r'log ' + label else: f = lambda x: x if substitute_fp is None: subf = lambda t: 0. else: if hasattr(substitute_fp, '__call__'): subf = lambda t: substitute_fp(t) else: subf = lambda t: substitute_fp for i, d in enumerate(self.digitization_list): if d.is_invertible(): d.invert(substitute_fp=subf(d.time)) if d.altitude.size: ii = round((float(d.time) - times[0]) / ais_code.ais_spacing_seconds) img[ii,:] = np.interp(ranges, d.altitude[-1:0:-1], f(d.density[-1:0:-1]), right=np.nan, left=np.nan)[::-1] extent = (self.extent[0], self.extent[1], np.nanmin(ranges), np.nanmax(ranges)) plt.imshow(img.T, interpolation='Nearest', extent=extent, origin='upper',aspect='auto', vmin=vmin, vmax=vmax, cmap=cmap) celsius.ylabel("alt / km") old_ax = plt.gca() plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=cmticks, **kwargs).set_label(label) plt.sca(old_ax)
def plot_field_topology(description, ax=None, colorbar=True, fname=None, limits=True, circ_axis=True, vmin=0., vmax=100., labels=True, full_range=True, **kwargs): """ Brain field topology maps. Ammended/edited by Rob as well, so include him. """ if not description in ALL_DESCRIPTIONS: raise KeyError("%s not one of accepted descriptions: %s" % (description, str(ALL_DESCRIPTIONS))) if ax is None: ax = plt.gca() plt.sca(ax) if fname is None: fname = get_file() data = readsav(fname, verbose=False) img = data[description] if full_range: img2 = np.hstack((img, img, img)) out = plt.imshow(img2, origin='lower', extent=(-360., 720., -90., 90.), interpolation='nearest', vmin=vmin, vmax=vmax, **kwargs) else: out = plt.imshow(img, origin='lower', extent=(0., 360., -90., 90.), interpolation='nearest', vmin=vmin, vmax=vmax, **kwargs) if limits: plt.xlim(0., 360.) plt.ylim(-90., 90) if circ_axis: ax.xaxis.set_major_locator(celsius.CircularLocator()) ax.yaxis.set_major_locator(celsius.CircularLocator()) if labels: plt.ylabel("Latitude / deg") plt.xlabel("Longitude / deg") if colorbar: c = plt.colorbar(cax=celsius.make_colorbar_cax()) if labels: c.set_label(description.replace('_', ' ')) out = (out, c) return out
def plot_swea_l2_summary(swea_data, max_times=4096, cmap=None, norm=None, labels=True, ax=None, colorbar=True): energy_range = (2, 4000.) def_range = (1e6, 1e9) if ax is None: ax = plt.gca() else: plt.sca(ax) if cmap is None: cmap = 'Spectral_r' if norm is None: norm = LogNorm(def_range[0], def_range[1]) if not 'def' in swea_data: print('Data is empty?') # extent = (t[0], t[-1], swea_data['energy'][0], swea_data['energy'][-1]) d = np.empty(4).reshape((2,2)) + np.nan t = plt.xlim() else: d = swea_data['def'] t = swea_data['time'] if d.shape[1] > max_times: n = int(np.floor(d.shape[1] / max_times)) d = d[:,::n] t = t[::n] energy_range = (swea_data['energy'][0], swea_data['energy'][-1]) extent = (t[0], t[-1], energy_range[0], energy_range[1]) img = plt.imshow( d, extent=extent, interpolation='nearest', origin='lower', norm=norm, cmap=cmap ) plt.xlim(t[0], t[-1]) plt.yscale('log') plt.ylim(energy_range[0], energy_range[1]) if labels: plt.ylabel("E / eV") if colorbar: plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('SWEA D.E.F.') return img
def plot_frequency_range(self, f_min=0., f_max=0.2, ax=None, median=False, vmin=None, vmax=None, colorbar=False, max_value=False): if vmin is None: vmin = self.vmin if vmax is None: vmax = self.vmax if ax is None: ax = plt.gca() plt.sca(ax) plt.cla() freq_extent = (self.extent[0], self.extent[1], ais_code.ais_max_delay*1E3, ais_code.ais_min_delay*1E3) i = self.ionogram_list[0] inx, = np.where((i.frequencies > f_min*1E6) & (i.frequencies < f_max*1E6)) if inx.shape[0] < 2: raise ValueError("Only %d frequency bins selected." % inx.shape[0]) print("Averaging over %d frequency bins" % inx.shape[0]) if median: if inx.shape[0] < 3: raise ValueError("Median here only really makes sense for 3 or more bins") img = np.median(self.tser_arr_all[:,inx,:],1) elif max_value: img = np.max(self.tser_arr_all[:,inx,:],1) else: img = np.mean(self.tser_arr_all[:,inx,:],1) plt.imshow(img, vmin=vmin, vmax=vmax, interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto') plt.xlim(freq_extent[0], freq_extent[1]) plt.ylim(freq_extent[2], freq_extent[3]) # plt.vlines(i.time,freq_extent[2],freq_extent[3], 'r') celsius.ylabel(r'$\tau_D / ms$' '\n' '%.1f-%.1f MHz' % (f_min, f_max)) # plt.annotate('f = %.1f - %.1f MHz' % (f_min, f_max), (0.02, 0.9), xycoords='axes fraction', # color='grey', verticalalignment='top', fontsize='small') if colorbar: old_ax = plt.gca() plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks).set_label(r"$Log_{10} V^2 m^{-2} Hz^{-1}$") plt.sca(old_ax)
def plot_static_l2_summary(static_data, plot_type='Energy', max_times=4096, cmap=None, norm=None, labels=True, ax=None, colorbar=True): if not 'static_kind' in static_data: raise ValueError("Data supplied not from static?") if not static_data['static_kind'] == 'c0': raise ValueError("I only know about C0, for now") if cmap is None: cmap = 'Spectral_r' if norm is None: norm = LogNorm(1e3, 1e9) if ax is None: ax = plt.gca() else: plt.sca(ax) imgs = [] x0, x1 = plt.xlim() for extent, data in static_data['blocks']: if extent[1] < x0: continue if extent[0] > x1: continue img = plt.imshow( data, extent=extent, interpolation='nearest', origin='lower', norm=norm, cmap=cmap ) imgs.append(img) plt.yscale('log') # plt.xlim(t0, t1) plt.ylim(extent[2], extent[3]) if labels: plt.ylabel("E / eV") if colorbar: plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('static D.E.F.') return imgs
def plot_swia_l2_summary(swia_data, max_times=4096, cmap=None, norm=None, labels=True, ax=None, colorbar=True): if not 'def' in swia_data: print('No data given?') return d = swia_data['def'] t = swia_data['time'] if d.shape[1] > max_times: n = int(np.floor(d.shape[1] / max_times)) d = d[:,::n] t = t[::n] extent = (t[0], t[-1], swia_data['energy'][0], swia_data['energy'][-1]) if cmap is None: cmap = 'Spectral_r' if norm is None: norm = LogNorm(1e6, 1e8) if ax is None: ax = plt.gca() else: plt.sca(ax) img = plt.imshow( d, extent=extent, interpolation='nearest', origin='lower', norm=norm, cmap=cmap ) plt.yscale('log') # plt.xlim(t0, t1) plt.ylim(swia_data['energy'][0], swia_data['energy'][-1]) if labels: plt.ylabel("E / eV") if colorbar: plt.colorbar(cax=celsius.make_colorbar_cax()).set_label('SWIA D.E.F.') return img
def plot_frequency(self, f=2.0, ax=None, median_filter=False, vmin=None, vmax=None, colorbar=False): if vmin is None: vmin = self.vmin if vmax is None: vmax = self.vmax if ax is None: ax = plt.gca() plt.sca(ax) plt.cla() freq_extent = (self.extent[0], self.extent[1], ais_code.ais_max_delay*1E3, ais_code.ais_min_delay*1E3) i = self.ionogram_list[0] inx = 1.0E6* (i.frequencies.shape[0] * f) / (i.frequencies[-1] - i.frequencies[0]) img = self.tser_arr_all[:,int(inx),:] # img -= np.mean(img, 0) plt.imshow(img, vmin=vmin, vmax=vmax, interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto') # plt.imshow(img, interpolation='Nearest', extent=freq_extent, origin='upper',aspect='auto') plt.xlim(freq_extent[0], freq_extent[1]) plt.ylim(freq_extent[2], freq_extent[3]) # plt.vlines(i.time,freq_extent[2],freq_extent[3], 'r') celsius.ylabel(r'$\tau_D / ms$' '\n' '%.1f MHz' % f) # plt.annotate('f = %.1f MHz' % f, (0.02, 0.9), xycoords='axes fraction', # color='grey', verticalalignment='top', fontsize='small') if colorbar: old_ax = plt.gca() plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=self.cbar_ticks).set_label( r"$Log_{10} V^2 m^{-2} Hz^{-1}$") plt.sca(old_ax)
def plot_surface_map(orbits, ax=None, param="time", cmap=None, norm=None, **kwargs): import mars.field_models import pickle from matplotlib.cm import summer if ax is None: ax = plt.gca() else: plt.sca(ax) if cmap is None: cmap = summer setup_lat_lon_ax(ax=ax) try: mars.field_models.plot_lat_lon_field(value="|B|", cax=celsius.make_colorbar_cax(half=True, upper=True)) except NotImplementedError as e: pass if not "ais_index" in celsius.datastore: celsius.datastore["ais_index"] = mex.ais.get_ais_index() g = celsius.datastore["ais_index"] g = [v for k, v in g.items() if k in orbits] if not g: raise ValueError("No data?") for gg in g: gg["iau_pos"][2, :] = celsius.deg_unwrap(gg["iau_pos"][2, :]) if param is None: for gg in g: for i in (-1, 0, 1): plt.plot(gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], **kwargs) if param == "sza": if norm is None: norm = plt.Normalize(vmin=0.0, vmax=180.0) title = "SZA / deg" elif param == "time": if norm is None: norm = plt.Normalize(vmin=mex.orbits[min(orbits)].start, vmax=mex.orbits[max(orbits)].finish) title = "Time / ET" elif param == "alt": if norm is None: norm = plt.Normalize(vmin=0.0, vmax=mex.mars_mean_radius_km) title = "Alt. / km" else: raise ValueError("Unrecognised parameter % s" % param) cmap = summer lc = None lc_kw = dict(cmap=cmap, norm=norm, linewidths=4, max_step=10.0) for gg in g: for i in (-1.0, 0.0, 1.0): if param == "sza": lc = celsius.map_along_line( gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["sza"], time=gg["time"], **lc_kw ) if param == "time": lc = celsius.map_along_line( gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["time"], time=gg["time"], **lc_kw ) if param == "alt": lc = celsius.map_along_line( gg["iau_pos"][2, :] + i * 360.0, gg["iau_pos"][1, :], gg["iau_pos"][0, :], time=gg["time"], **lc_kw ) # plt.scatter(gg['iau_pos[2,:], gg['iau_pos[1,:], c=gg['sza, # s=10., vmin=30, vmax=150, edgecolor='none') if lc: c = plt.colorbar(lc, cax=celsius.make_colorbar_cax(half=True, upper=False)) c.set_label(title) else: raise ValueError("Nothing mapped :(") plt.sca(ax) return lc
def plot_aspera_els(start, finish=None, verbose=False, ax=None, colorbar=True, vmin=None, vmax=None, cmap=None, safe=True): """docstring for plot_aspera_els""" if cmap is None: cmap = plt.cm.Spectral_r if ax is None: ax = plt.gca() plt.sca(ax) if finish is None: finish = start + 86400. if vmin is None: vmin = 5. if vmax is None: vmax = 9. no_days = (finish - start) / 86400. if verbose: print('Plotting ASPERA/ELS between %s and %s...' % (celsius.utcstr(start, 'ISOC'), celsius.utcstr(finish, 'ISOC'))) directory = mex.data_directory + 'aspera/els/' all_files_to_read = [] for et in np.arange(start - 10., finish + 10., 86400.): dt = celsius.spiceet_to_datetime(et) f_name = directory + 'MEX_ELS_EFLUX_%4d%02d%02d_*.cef' % (dt.year, dt.month, dt.day) all_day_files = glob.glob(f_name) if not all_day_files: if verbose: print("No files matched %s" % f_name) else: all_files_to_read.extend(all_day_files) success = False all_extents = [] for f_name in all_files_to_read: try: # Find energy bins: with open(f_name, 'r') as f: line_no = 0 while line_no < 43: line_no += 1 line = f.readline() if 'DATA = ' in line: energy_bins = np.fromstring(line[7:], sep=',') energy_bins.sort() break else: raise IOError("No ENERGY_BINS info found in header") data = np.loadtxt(f_name, skiprows = 43, converters={1:lambda x: celsius.utcstr_to_spiceet(x[:-1])}) if data.shape[1] != (energy_bins.shape[0] + 2): raise ValueError("Size of ENERGY_BINS and DATA doesn't match") # Check timing: dt = np.diff(data[:,1]) spacing = np.median(dt) # checks = abs(dt - spacing) > (spacing/100.) # if np.any(checks): # # raise ValueError("Spacing is not constant: %d differ by more than 1%% of %f:" % (np.sum(checks), spacing)) # print "Spacing is not constant: %d differ by more than 1%% of %f (Maximum = %f):" % (np.sum(checks), spacing, max(abs(dt - spacing))) # # if safe and (max(abs(dt - spacing)) > 10.): # print '-- To big spacing - dumping' # continue # Interpolate to constant spacing: n_records = int((data[-1,1] - data[0,1]) / spacing) new_data = np.empty((n_records, data.shape[1])) + np.nan new_data[:,1] = np.linspace(data[0,1], data[-1,1], n_records) for i in range(3, data.shape[1]): new_data[:,i] = np.interp(new_data[:,1],data[:,1], data[:,i], left=np.nan, right=np.nan) data = new_data extent = (data[0,1], data[-1,1], energy_bins[0], energy_bins[-1]) if (extent[0] > finish) or (extent[1] < start): if verbose: print("This block not within plot range - dumping") continue all_extents.append(extent) if verbose: print('Plotting ASPERA ELS block, Time: %s - %s, Energy: %f - %f' % ( celsius.utcstr(extent[0],'ISOC'), celsius.utcstr(extent[1],'ISOC'), extent[2], extent[3])) print('Shape = ', data.shape) plt.imshow(np.log10(data[:,3:].T), interpolation="nearest", aspect='auto', extent=extent, vmin=vmin, vmax=vmax, cmap=cmap) success = True except IOError as e: if verbose: print('Error reading %f' % f_name) print('--', e) continue if success and colorbar: plt.xlim(start, finish) plt.ylim(max([e[2] for e in all_extents]), min([e[3] for e in all_extents])) celsius.ylabel('E / eV') plt.yscale('log') cmap.set_under('w') old_ax = plt.gca() plt.colorbar(cax=celsius.make_colorbar_cax(), cmap=cmap, ticks=[5,6,7,8,9]) plt.ylabel(r'log$_{10}$ D.E.F.') plt.sca(old_ax)
def plot_ima_spectra( start, finish, species=["H", "O", "O2"], colorbar=True, ax=None, blocks=None, check_times=True, return_val=None, verbose=False, check_overlap=True, vmin=2, vmax=7.0, raise_all_errors=False, cmap=None, norm=None, die_on_empty_blocks=False, accept_new_tables=True, inverted=True, **kwargs ): """ Plot IMA spectra from start - finish, . blocks is a list of data blocks to work from, if this is not specified then we'll read them species names: [only those with x will function] heavy (16, 85, 272) x sumions (85, 32) CO2 (16, 85, 272) x E (96, 1) Horig (16, 85, 272) x tmptime (1, 272) H (16, 85, 272) dE (1, 85) sumorigions (85, 32) O (16, 85, 272) x Hsp (16, 85, 272) x mass (50, 272) alpha (16, 85, 272) x O2 (16, 85, 272) x He (16, 85, 272) x for blocks read with dataset='fion', we'll add an 'f' before CO2, O2, O2plus, O, Horig, He, H automagically """ if not blocks: blocks = read_ima(start, finish, verbose=verbose, **kwargs) if ax is None: ax = plt.gca() plt.sca(ax) ax.set_axis_bgcolor("lightgrey") if not cmap: cmap = matplotlib.cm.Greys_r # cmap.set_under('white') if not norm: norm = plt.Normalize(vmin, vmax, clip=True) ims = [] last_finish = -9e99 if blocks: if "fH" in list(blocks[0].keys()): # blocks were read with dataset='fion' if isinstance(species, str): if species in ("O", "H", "He", "alpha", "Horig", "O2", "O2plus", "CO2"): species = "f" + species else: new_species = [] for s in species: if s in ("O", "H", "He", "alpha", "Horig", "O2", "O2plus", "CO2"): new_species.append("f" + s) species = new_species # if isinstance(species, basestring): # if species[0] == 'f': # label = species[1:] + r' flux \n / $cm^{-2}s^{-1}$' # else: # label = species + '****' # else: # label = '' # for s in species: # if s[0] == 'f': # label += s[1:] + ', ' # else: # label += s # label += r' flux \n/ $cm^{-2}s^{-1}$' label = r"Flux / $cm^{-2}s^{-1}$" # Make sure we set the ylimits correctly by tracking min and max energies min_energy = 60000.0 max_energy = -10.0 for b in blocks: # min(abs()) to account for negative values in E table extent = [ celsius.matlabtime_to_spiceet(b["tmptime"][0]), celsius.matlabtime_to_spiceet(b["tmptime"][-1]), min(abs(b["E"])), max(b["E"]), ] # Account for the varying size of the Energy table: if b["sumions"].shape[0] == 96: extent[2] = b["E"][-1] extent[3] = b["E"][0] elif b["sumions"].shape[0] == 85: # revised energy table extent[2] = b["E"][-11] extent[3] = b["E"][0] if extent[2] < 0.0: raise ValueError("Energies should be positive - unrecognised energy table?") else: if accept_new_tables: extent[2] = np.min(np.abs(b["E"])) extent[3] = b["E"][0] print("New table:", extent[2], extent[3], b["E"][-1], b["E"][0], b["sumions"].shape[0]) else: raise ValueError( "Unrecognised energy table: E: %e - %e in %d steps?" % (b["E"][-1], b["E"][-1], b["sumions"].shape[0]) ) if extent[2] < min_energy: min_energy = extent[2] if extent[3] > max_energy: max_energy = extent[3] if check_times: spacing = 86400.0 * np.mean(np.diff(b["tmptime"])) if spacing > 15.0: if raise_all_errors: raise ValueError("Resolution not good? Mean spacing = %fs " % spacing) else: plt.annotate( "Resolution warning:\nmean spacing = %.2fs @ %s " % (spacing, celsius.utcstr(np.median(b["tmptime"]))), (0.5, 0.5), xycoords="axes fraction", color="red", ha="center", ) if not isinstance(species, str): # produce the MxNx3 array for to up 3 values of species (in R, G, B) img = np.zeros((b[species[0]].shape[1], b[species[0]].shape[2], 3)) + 1.0 for i, s in enumerate(species): im = np.sum(b[s], 0).astype(np.float64) # im[im < 0.01] += 0.1e-10 if inverted: im = 1.0 - norm(np.log10(im)) for j in (0, 1, 2): if j != i: img[..., j] *= im tot = np.sum(1.0 - img) else: img[..., i] *= norm(np.log10(im)) tot = np.sum(img) else: img = np.sum(b[species], 0) img[img < 0.01] += 0.1e-10 img = np.log10(img) tot = np.sum(img) if verbose: print("Total scaled: %e" % tot) # print 'Fraction good = %2.0f%%' % (np.float(np.sum(np.isfinite(img))) / (img.size) * 100.) # print 'Min, mean, max = ', np.min(img), np.mean(img), np.max(img) if check_overlap and (extent[0] < last_finish): raise ValueError("Blocks overlap: Last finish = %f, this start = %f" % (last_finish, extent[0])) if FUDGE_FIX_HANS_IMA_TIME_BUG: # print extent, last_finish if abs(extent[0] - last_finish) < 20.0: # if there's 20s or less between blocks if verbose: print("\tFudging extent: Adjusting start by %fs" % (extent[0] - last_finish)) extent[0] = last_finish # squeeze them together if inverted: name = cmap.name if name[-2:] == "_r": name = name[:-2] else: name = name + "_r" cmap = getattr(plt.cm, name) if extent[1] < start: # if verbose: print("Dumping block (B)", start - extent[1]) continue if extent[0] > finish: print("Dumping block (A)", extent[0] - finish) continue ims.append(plt.imshow(img, extent=extent, origin="upper", interpolation="nearest", cmap=cmap, norm=norm)) last_finish = extent[1] if ims: plt.xlim(start, finish) plt.ylim(min_energy, max_energy) cbar_im = ims[0] else: plt.ylim(10.0, 60000) # guess # invisible image for using with colorbar cbar_im = plt.imshow(np.zeros((1, 1)), cmap=cmap, norm=norm, visible=False) plt.yscale("log") celsius.ylabel("E / eV") if colorbar: ## make_colorbar_cax is doing something weird to following colorbars... # if not isinstance(species, basestring): # img = np.zeros((64,len(species),3)) + 1. # cax = celsius.make_colorbar_cax(width=0.03) # for i, s in enumerate(species): # for j in (0,1,2): # if j != i: # img[:,i,j] = np.linspace(0., 1., 64) # # plt.sca(cax) # plt.imshow(img, extent=(0, 3, vmin, vmax), interpolation='nearest', aspect='auto') # plt.xticks([0.5, 1.5, 2.5], label.split(', ')) # plt.xlim(0., 3.) # cax.yaxis.tick_right() # cax.xaxis.tick_top() # plt.yticks = [2,3,4,5,6] # cax.yaxis.set_label_position('right') # plt.ylabel(r'$Flux / cm^{-2}s^{-1}$') # # plt.sca(ax) # else: ticks = np.arange(int(vmin), int(vmax) + 1, dtype=int) plt.colorbar(cbar_im, cax=celsius.make_colorbar_cax(), ticks=ticks).set_label(label) if return_val: if return_val == "IMAGES": del blocks return ims elif return_val == "BLOCKS": return blocks else: print("Unrecognised return_value = " + str(return_value)) del blocks del ims return
def lpw_plot_iv(s, boom=1, ax=None, cmap=None, norm=None, start=None, finish=None, voltage=None, max_times=8912, imin=None, imax=None, labels=True, colorbar=True, full_resolution=False, log_abs=True): """Plot LP IV sweeps as a time series. Interpolation to regular voltage and time axis as appropriate for presentation purposes, but don't do science with the results.""" if ax is None: ax = plt.gca() else: plt.sca(ax) if cmap is None: plt.set_cmap('Spectral_r') cmap = plt.get_cmap() cmap.set_bad('grey') t0 = s['time'][0] t1 = s['time'][-1] if voltage is None: voltage = np.linspace(-20., 20., 512) if full_resolution: voltage = np.arange(-20., 20., 0.01) n_times = np.floor((t1 - t0) / 4.) if (n_times > 4096) and full_resolution: print('You are attempting to create a very, very large image...') if (n_times < max_times) or full_resolution: dt = 4. else: dt = (t1 - t0) / max_times tnew = np.arange(t0, t1, dt) if not norm: norm = LogNorm(1e-9, 1e-3) if not log_abs: norm = plt.Normalize(1e-3, 1e-3) extent = (t0, t1, voltage[0], voltage[-1]) # Compute expansion of frequency axis # freq_inx = [] # fnext = s['freq'][1] # f_inx = 0 # i = 0 # while True: # if fnext > fnew[i]: # freq_inx.append(f_inx) # i+=1 # if i == max_frequencies: break # else: # f_inx += 1 # fnext = s['freq'][f_inx] # freq_inx = np.array(freq_inx) # Interpolate voltages tmp = [] t = t0 img = np.empty((voltage.shape[0], tnew.shape[0])) + np.nan inx_new = 0 inx_old = boom for current, old_voltage in zip(s['current'], s['volt']): i = boom while i < current.shape[1]: while tnew[inx_new] < s['time'][inx_old]: img[:, inx_new] = np.interp(voltage, old_voltage[:,i], current[:, i], left=np.nan, right=np.nan) inx_new += 1 if inx_new >= tnew.shape[0]: break i += 2 inx_old += 2 if inx_new >= tnew.shape[0]: break # raise RuntimeError() # print(img.shape) print(extent) if log_abs: img = np.abs(img) img_obj = plt.imshow(img, cmap=cmap, norm=norm, extent=extent, origin='lower', interpolation='nearest') # plt.yscale('log') plt.ylim(voltage[0], voltage[-1]) plt.xlim(t0, t1) if labels: plt.ylabel(r'U$_{Bias}$ / V') if colorbar: cbar = plt.colorbar(cax=celsius.make_colorbar_cax()) cbar.set_label(r'i / A') else: cbar = None return img, img_obj, cbar
def lpw_plot_spec(s, ax=None, cmap=None, norm=None, max_frequencies=512, max_times=2048, fmin=None, fmax=None, labels=True, colorbar=True, full_resolution=False): """Transform and plot a spectra dictionary generated by lpw_load. Doesn't interpolate linearly, but just rebins data. Appropriate for presentation purposes, but don't do science with the results.""" if ax is None: ax = plt.gca() else: plt.sca(ax) if cmap is None: cmap = 'Spectral_r' if norm is None: norm = LogNorm(1e-16, 1e-8) t0 = s['time'][0] t1 = s['time'][-1] f0 = s['freq'][0] f1 = s['freq'][-1] n_times = np.floor((t1 - t0) / 4.) if (n_times > 4096) and full_resolution: print('You are attempting to create a very, very large image...') if (n_times < max_times) or full_resolution: dt = 4. else: dt = (t1 - t0) / max_times tnew = np.arange(t0, t1, dt) minf = np.min(np.diff(s['freq'])) if fmin is not None: f0 = fmin # Hz if fmax is not None: f1 = fmax extent = (t0, t1, f0, f1) if full_resolution: fnew = 10.**np.arange(np.log10(f0), np.log10(f1), 0.01) # Approximate max_frequencies = fnew.shape[0] else: fnew = 10.**np.linspace(np.log10(f0), np.log10(f1-1.), max_frequencies) # Compute expansion of frequency axis freq_inx = [] fnext = s['freq'][1] f_inx = 0 i = 0 while True: if fnext > fnew[i]: freq_inx.append(f_inx) i+=1 if i == max_frequencies: break else: f_inx += 1 fnext = s['freq'][f_inx] freq_inx = np.array(freq_inx) # Compute expansion of time axis t_inx = [] tnext = s['time'][1] time_inx = 0 i = 0 while True: if tnext > tnew[i]: t_inx.append(time_inx) i+=1 if i == tnew.shape[0]: break else: time_inx += 1 tnext = s['time'][time_inx] t_inx = np.array(t_inx) img = s['spec'][...,t_inx][freq_inx] img_obj = plt.imshow(img, cmap=cmap, norm=norm, extent=extent, origin='lower', interpolation='nearest') plt.yscale('log') plt.ylim(f0, f1) plt.xlim(t0, t1) if labels: plt.ylabel('f / Hz') if colorbar: cbar = plt.colorbar(cax=celsius.make_colorbar_cax()) cbar.set_label(r'V$^2$ m$^{-2}$ Hz$^{-1}$') else: cbar = None return img, img_obj, cbar
def modb_along_orbit(self, ax=None, annotate=True, bg_color='dimgrey', cmap=None, vmin=0., vmax=20.): if ax is None: ax = plt.gca() if cmap is None: cmap = plt.cm.autumn cmap.set_bad('dimgrey',0.) cmap.set_under('dimgrey',0.) td_cyclotron_list = [d for d in self.digitization_list if np.isfinite(d.td_cyclotron)] plt.sca(ax) mex.plot_planet(lw=3.) mex.plot_bs(lw=1., ls='dashed', color='k') mex.plot_mpb(lw=1., ls='dotted', color='k') ax.set_aspect('equal','box') plt.xlim(2,-2) plt.autoscale(False,tight=True) plt.ylim(0., 1.999) if annotate: plt.annotate('%d' % self.orbit, (0.05, 0.85), xycoords='axes fraction', va='top') def f_x(pos): return pos[0] / mex.mars_mean_radius_km def f_y(pos): return np.sqrt(pos[1]**2. + pos[2]**2.) / mex.mars_mean_radius_km # def f_y(pos): # return pos[2] / mex.mars_mean_radius_km plt.plot( f_x(self.mso_pos), f_y(self.mso_pos), color=bg_color, lw=2., zorder=-10) inx = np.interp(np.array([d.time for d in self.ionogram_list]), self.t, np.arange(self.t.shape[0])) inx = inx.astype(int) plt.plot(f_x(self.mso_pos[:,inx]), f_y(self.mso_pos[:,inx]), color=bg_color, ls='None',marker='o', ms=8., mew=0., mec=bg_color, zorder=-9) if td_cyclotron_list: val = np.empty_like(self.t) + np.nan for t, v in [(float(f.time), 1E9 * ais_code.td_to_modb(f.td_cyclotron)) for f in td_cyclotron_list]: val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v points = np.array([f_x(self.mso_pos), f_y(self.mso_pos)]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) lc = LineCollection(segments, cmap=cmap, norm=plt.Normalize(vmin=vmin, vmax=vmax, clip=True)) lc.set_array(val) lc.set_linewidth(5) plt.gca().add_collection(lc) else: lc = None plt.ylabel(r'$\rho / R_M$') # plt.ylabel(r'$z / R_M$') plt.xlabel(r'$x / R_M$') if lc: old_ax = plt.gca() plt.colorbar(lc, cax = celsius.make_colorbar_cax(offset=0.001, height=0.8) ).set_label(r'$|B| / nT$') plt.sca(old_ax)
def density_along_orbit(self, ax=None, annotate=True, min_fp_local_length=0, bg_color='dimgrey', cmap=None, vmin=1., vmax=3.): if cmap is None: cmap = plt.cm.autumn cmap.set_bad('dimgrey',0.) cmap.set_under('dimgrey',0.) if ax is None: ax = plt.gca() fp_local_list = [d for d in self.digitization_list if np.isfinite(d.fp_local)] plt.sca(ax) mex.plot_planet(lw=3.) mex.plot_bs(lw=1., ls='dashed', color='k') mex.plot_mpb(lw=1., ls='dotted', color='k') ax.set_aspect('equal', 'box') plt.xlim(2,-2) plt.autoscale(False,tight=True) plt.ylim(0,1.9999) if annotate: plt.annotate('%d' % self.orbit, (0.05, 0.85), xycoords='axes fraction', va='top') def f_x(pos): return pos[0] / mex.mars_mean_radius_km def f_y(pos): return np.sqrt(pos[1]**2. + pos[2]**2.) / mex.mars_mean_radius_km # def f_y(pos): # return pos[2] / mex.mars_mean_radius_km plt.plot( f_x(self.mso_pos), f_y(self.mso_pos), color=bg_color, lw=1., zorder=-10) inx = np.interp(np.array([d.time for d in self.ionogram_list]), self.t, np.arange(self.t.shape[0])) inx = inx.astype(int) plt.plot( f_x(self.mso_pos[:,inx]), f_y(self.mso_pos[:,inx]), color=bg_color, ls='None',marker='o', ms=8.,mew=0., mec=bg_color, zorder=-9) if fp_local_list: val = np.empty_like(self.t) + np.nan # for t, v in [(float(f.time), np.log10(ais_code.fp_to_ne(f.maximum_fp_local))) for f in fp_local_list]: # val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v for f in fp_local_list: t = float(f.time) # if (f.fp_local_error / f.fp_local) > 0.3: # v = np.log10(20.) # else: v = np.log10(ais_code.fp_to_ne(f.fp_local)) # print t, ais_code.fp_to_ne(f.fp_local), f.fp_local_error/f.fp_local > 0.3 val[np.abs(self.t - t) < ais_code.ais_spacing_seconds] = v points = np.array([f_x(self.mso_pos), f_y(self.mso_pos)]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) lc = LineCollection(segments, cmap=cmap, norm=plt.Normalize(vmin=vmin, vmax=vmax, clip=True)) lc.set_array(val) lc.set_linewidth(5) plt.gca().add_collection(lc) else: lc = None plt.ylabel(r'$\rho / R_M$') # plt.ylabel(r'$z / R_M$') plt.xlabel(r'$x / R_M$') if lc: ticks = [i for i in range(10) if ((float(i)+0.1) > vmin) & ((float(i)-0.1) < vmax)] old_ax = plt.gca() plt.colorbar(lc, cax = celsius.make_colorbar_cax(offset=0.001, height=0.8), ticks=ticks).set_label(r'$log_{10}\;n_e / cm^{-3}$') plt.sca(old_ax)
def plot_profiles_delta(self, ax=None): if ax is None: ax = plt.gca() plt.sca(ax) ax.set_axis_bgcolor("gray") n_profiles = int((self.extent[1] - self.extent[0]) / ais_code.ais_spacing_seconds) + 1 ranges = np.arange(80., 300., 1.) times = np.arange(self.extent[0], self.extent[1], ais_code.ais_spacing_seconds) img = np.zeros((len(times), len(ranges))) + np.nan for i, d in enumerate(self.digitization_list): if d.is_invertible(): d.invert(substitute_fp=ais_code.ne_to_fp(4.)) if d.altitude.size: # as it comes from invert, local values are first, peaks are last ii = round((float(d.time) - times[0]) / ais_code.ais_spacing_seconds) img[ii,:] = np.interp(ranges, d.altitude[::-1], np.log10(d.density[::-1]), right=np.nan, left=np.nan)[::-1] # This gives departures from the curve defined by the extrapolation to the first reflection point # h = -1. * (d.altitude[0] - d.altitude[1]) / (np.log(d.density[0]/d.density[1])) # img[ii, :] = np.log10(10.**img[ii,:] - d.density[1] * np.exp(-1. * (ranges - d.altitude[1]) / h)) # This gives departures from the Morgan et al model sza = np.interp(d.time, self.t, self.sza) # if sza < 90.: # chap = mars.ChapmanLayer() # # inx, = np.where(np.isfinite(img[ii,:])) # # chap.fit(ranges[inx], 10**img[ii,inx[::-1]], sza) # try: # chap.fit(d.altitude[::-1], d.density[::-1], np.deg2rad(sza)) # model_densities = chap(ranges, np.deg2rad(sza)) # print chap # print 'peak:', d.altitude[-1], d.density[-1], sza # except ValueError, e: # print e # continue model_densities = self.ionosphere_model(ranges, np.deg2rad(sza)) # img[ii, :] = np.log10(10.**img[ii,:] - model_densities) img[ii, :] = 10.**img[ii,:] - model_densities[::-1] # if True: # ax = plt.gca() # plt.figure() # plt.plot(np.log10(d.density), d.altitude,'k-') # if sza < 90.: # plt.plot(np.log10(model_densities), ranges,'r-') # # plt.plot(np.log10(chap(ranges)), ranges, 'r', ls='dotted') # # plt.plot(np.log10(self.ionosphere_model(ranges, np.deg2rad(sza))), ranges, 'b-') # # plt.plot(np.log10(self.ionosphere_model(ranges)), ranges, 'b', ls='dotted') # plt.xlim(2,6) # plt.sca(ax) extent = (self.extent[0], self.extent[1], np.nanmin(ranges), np.nanmax(ranges)) plt.imshow(img.T, interpolation='Nearest', extent=extent, origin='upper',aspect='auto', cmap=matplotlib.cm.RdBu_r, vmin=-1E5,vmax=1E5) celsius.ylabel("alt. / km") old_ax = plt.gca() plt.colorbar(cax = celsius.make_colorbar_cax(), ticks=[-1E5,0,1E5],format='%.1G') plt.ylabel(r"log $\Delta n_e$ / cm$^{-3}$") plt.sca(old_ax)
def plot_els_spectra( start, finish, sector="SUM", colorbar=True, ax=None, blocks=None, return_val=None, verbose=False, check_times=True, vmin=None, vmax=None, cmap=None, norm=None, die_on_empty_blocks=False, **kwargs ): """ Plot ASPERA/ELS spectra from start - finish. sector = int from 0 - 15 to select single sector to plot. sector = 'SUM' to integrate over all sector = 'MEAN' to average over all Shapes of the stuff in each block (215 = time!) altElec (1, 215) latElec (1, 215) zmsoElec (1, 215) dEElec (128, 1) ymsoElec (1, 215) xmsoElec (1, 215) tElec (1, 215) fElec (16, 128, 215) longElec (1, 215) EElec (128, 1) New versions: elslevels (128, 112) elsmatrix (128, 16, 783) elstimes (1, 783) elssectors (1, 16) elsleveltimes (1, 112) elsdeltatimes (128, 112) """ if not blocks: blocks = read_els(start, finish, verbose=verbose, **kwargs) if ax is None: ax = plt.gca() plt.sca(ax) ax.set_axis_bgcolor("lightgrey") if not cmap: cmap = Spectral_r cmap.set_bad("white") ims = [] last_finish = -9e99 # label = r'Flux / $cm^{-2}s^{-1}$' label = "Counts" # Make sure we set the ylimits correctly by tracking min and max energies min_energy = 1e99 max_energy = -1e99 cbar_ticks = np.array((7, 8, 9, 10, 11)) # Establish function to handle the data if isinstance(sector, str): if sector.lower() == "mean": process = lambda x: np.nanmean(x, 1) # if vmin is None: # vmin = 7. # if vmax is None: # vmax = 11. elif sector.lower() == "sum": process = lambda x: np.nansum(x, 1) # if vmin is None: # vmin = 7. + 1. # if vmax is None: # vmax = 11. + 1. # cbar_ticks += 1 else: raise ValueError("Unrecognized argument for sector: %s" % sector) else: process = lambda x: x[:, sector, :] # if vmin is None: # vmin = 7. # if vmax is None: # vmax = 11. if vmin is None: vmin = 0 if vmax is None: vmax = 4 if not norm: norm = plt.Normalize(vmin, vmax, clip=False) norm = None for b in blocks: # min(abs()) to account for negative values in E table extent = [ celsius.matlabtime_to_spiceet(np.min(b["elstimes"])), celsius.matlabtime_to_spiceet(np.max(b["elstimes"])), np.min(np.abs(b["elslevels"])), np.max(b["elslevels"]), ] if extent[2] < min_energy: min_energy = extent[2] if extent[3] > max_energy: max_energy = extent[3] print(extent) # if check_times: # spacing = 86400.*np.mean(np.diff(b['tElec'])) # if spacing > 15.: # raise ValueError("Resolution not good? Mean spacing = %fs " % spacing ) img = process(b["elsmatrix"]) # img[img < 10.] = np.min(img) img = np.log10(img) if verbose: print( "Fraction good = %2.0f%%" % (np.float(np.sum(np.isfinite(img))) / (img.shape[0] * img.shape[1]) * 100.0) ) # print 'Min, mean, max = ', np.nanmin(img), np.nanmean(img), np.nanmax(img) if extent[0] < last_finish: s = "Blocks overlap: Last finish = %f, this start = %f" % (last_finish, extent[0]) if check_times: raise ValueError(s) else: print(s) # e = extent[2] # extent[2] = extent[3] # extent[3] = e ims.append(plt.imshow(img, extent=extent, origin="upper", interpolation="nearest", cmap=cmap, norm=norm)) last_finish = extent[1] number_of_blocks = len(blocks) if blocks: plt.xlim(start, finish) plt.ylim(min_energy, max_energy) cbar_im = ims[0] else: plt.ylim(1e0, 1e4) # need to create an empty image so that colorbar functions cbar_im = plt.imshow(np.zeros((1, 1)), cmap=cmap, norm=norm, visible=False) plt.ylim(min_energy, max_energy) plt.yscale("log") # plt.ylabel('E / eV') print("ELS PLOT: Time is not accurate to more than ~+/- 4s for now.") if colorbar: if ims: plt.colorbar(cbar_im, cax=celsius.make_colorbar_cax(), ticks=cbar_ticks).set_label(label) if return_val: if return_val.upper() == "IMAGES": del blocks return ims elif return_val.upper() == "BLOCKS": del ims return blocks else: print("Unrecognised return_value = " + str(return_value)) del blocks del ims return number_of_blocks
def plot_lat_lon_field(name=None, value='|B|', zorder=0, cmap=None, vmin=None, vmax=None, colorbar=True, cax=None, ax=None, labels=True, lims=True, return_data=False, label_str=None, full_range=False, inclination_min_b=None, inclination_draped_imf=0., inclination_draped_imf_orient=0., snapshot_kwargs={}, data_only=False, **kwargs): """Plot `value` in Latitude / East Longitude. snapshot_kwargs go to create_snapshot if it's called. extra args go to imshow.""" if name is None: name = mex.data_directory + 'saved_field_models/Cain_400km1deg.pck' if isinstance(name, str): print('Loading field model from %s' % name) with open(name, 'rb') as f: field_data = pickle.load(f) else: field_data = create_snapshot(name, **snapshot_kwargs) if ax is None: ax = plt.gca() else: plt.sca(ax) q_abs = False units = 'nT' _vmin, _vmax = 0., 50. if field_data['altitude'] < 200.: _vmax = 500. # TeX labels: label_dict = {'|B|':r'|\mathbf{B}_c|', 'Br':r'B_r', 'Bt':r'B_\theta', 'Bp':r'B_\varphi', 'Bh':r'B_H', 'AbsInclination':r'|\delta|', 'Inclination':r'\delta'} if label_str is None: label_str = label_dict[value] l_mesh_shp = field_data['longitude_mesh'].shape fd = field_data['field'] if (value == '|B|'): q = np.sqrt((fd[0,:].reshape(l_mesh_shp).T)**2. + (fd[1,:].reshape(l_mesh_shp).T)**2. + (fd[2,:].reshape(l_mesh_shp).T)**2.) q_abs = True elif value == 'Br': q = fd[0,:].reshape(l_mesh_shp).T elif value == 'Bt': q = fd[1,:].reshape(l_mesh_shp).T elif value == 'Bp': q = fd[2,:].reshape(l_mesh_shp).T elif value == 'Bh': q = np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2. + (fd[2,:].reshape(l_mesh_shp).T)**2.) q_abs = True elif value == 'Inclination': # atan ( br, b_horizontal ) fd[1,:] += inclination_draped_imf * np.cos(np.deg2rad(inclination_draped_imf_orient)) fd[2,:] += inclination_draped_imf * np.sin(np.deg2rad(inclination_draped_imf_orient)) q = np.rad2deg(np.arctan2(fd[0,:].reshape(l_mesh_shp).T, np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2. + (fd[2,:].reshape(l_mesh_shp).T)**2.))) _vmax = 90 units = 'deg.' elif value == 'AbsInclination': # atan ( br, b_horizontal ) fd[1,:] += inclination_draped_imf * np.cos(np.deg2rad(inclination_draped_imf_orient)) fd[2,:] += inclination_draped_imf * np.sin(np.deg2rad(inclination_draped_imf_orient)) q = np.rad2deg(np.arctan2(fd[0,:].reshape(l_mesh_shp).T, np.sqrt((fd[1,:].reshape(l_mesh_shp).T)**2. + (fd[2,:].reshape(l_mesh_shp).T)**2.))) q = np.abs(q) _vmin = 0 _vmax = 90 q_abs = True units = 'deg.' else: raise ValueError('value "%s" not recognized' % str(value)) if ('Inclination' in value) and (inclination_min_b is not None): b = np.sqrt((fd[0,:].reshape(l_mesh_shp).T)**2. + (fd[1,:].reshape(l_mesh_shp).T)**2. + (fd[2,:].reshape(l_mesh_shp).T)**2.) q[b < inclination_min_b] = np.nan if not q_abs: _vmin = - _vmax if not vmin: vmin = _vmin if not vmax: vmax = _vmax extent = (0., 360., -90, 90) if not cmap: cmap = plt.cm.RdBu_r if q_abs: cmap = plt.cm.Reds if data_only: if full_range: q2 = np.hstack((q, q, q)) return q2 return q if full_range: q2 = np.hstack((q, q, q)) extent2 = (-360, 720., -90, 90) out = plt.imshow(q2, vmin=vmin, vmax=vmax, cmap=cmap, extent=extent2, **kwargs) else: out = plt.imshow(q, vmin=vmin, vmax=vmax, cmap=cmap, extent=extent, **kwargs) if labels: plt.xlabel('Longitude / deg') plt.ylabel('Latitude / deg') if lims: plt.xlim(0., 360.) plt.ylim(-90, 90) ax.yaxis.set_major_locator(celsius.CircularLocator()) ax.xaxis.set_major_locator(celsius.CircularLocator()) if colorbar: if not cax: cax = celsius.make_colorbar_cax() if value == 'Inclination': c = plt.colorbar(cax=cax, ticks=[-90, -45, 0, 45, 90]) elif value == 'AbsInclination': c = plt.colorbar(cax=cax, ticks=[0, 45, 90]) else: c = plt.colorbar(cax=cax) c.set_label(r'$%s / %s$' % (label_str, units)) plt.sca(ax) if return_data: return q