def __init__(self, title, liste, alpha, unit, opt): self.title = title self.dirs = liste N = len(self.dirs) self.rows = math.ceil(N/4) self.columns = 4 self.cbunit = units.get_label(unit) self.load_grid(alpha) self.create_figure(opt) self.cm(unit)
def plot_data(self, ov_plot, opt, i, j): self.ax = ov_plot.axs[i, j] # add data to plotman if opt.cmaglin and self.type == 'mag': self.cid = self.plotman.parman.add_data(np.power(10, self.data)) ov_plot.cbunit = 'rho' else: self.cid = self.plotman.parman.add_data(self.data) # handle options cblabel = units.get_label(ov_plot.cbunit) zlabel = 'z [' + opt.xunit + ']' xlabel = 'x [' + opt.xunit + ']' if self.type == 'mag': vmin = opt.mag_vmin vmax = opt.mag_vmax elif self.type == 'pha': vmin = opt.pha_vmin vmax = opt.pha_vmax elif self.type == 'imag': vmin = opt.imag_vmin vmax = opt.imag_vmax else: vmin = opt.real_vmin vmax = opt.real_vmax xmin, xmax, zmin, zmax, vmin, vmax = check_minmax(ov_plot.plotman, self.cid, opt.xmin, opt.xmax, opt.zmin, opt.zmax, vmin, vmax, ) # plot fig, ax, cnorm, cmap, cb = ov_plot.plotman.plot_elements_to_ax( cid=self.cid, cid_alpha=ov_plot.alpha, ax=self.ax, xmin=xmin, xmax=xmax, zmin=zmin, zmax=zmax, cblabel=cblabel, cbnrticks=opt.cbtiks, title=self.title[3:], zlabel=zlabel, xlabel=xlabel, plot_colorbar=True, cmap_name=ov_plot.cm, cbmin=vmin, cbmax=vmax, )
def plot_pha(cid, ax, plotman, title, alpha, vmin, vmax, xmin, xmax, zmin, zmax, xunit, cbtiks, elecs): '''Plot phase of the complex resistivity using the pha_options. ''' # handle options cblabel = units.get_label('phi') zlabel = 'z [' + xunit + ']' xlabel = 'x [' + xunit + ']' cm = 'plasma' cm = 'jet_r' xmin, xmax, zmin, zmax, vmin, vmax = check_minmax( plotman, cid, xmin, xmax, zmin, zmax, vmin, vmax, ) # plot fig, ax, cnorm, cmap, cb, scalarMap = plotman.plot_elements_to_ax( cid=cid, ax=ax, cid_alpha=alpha, xmin=xmin, xmax=xmax, zmin=zmin, zmax=zmax, cblabel=cblabel, cbnrticks=cbtiks, title=title, zlabel=zlabel, xlabel=xlabel, plot_colorbar=True, cmap_name=cm, no_elecs=elecs, cbmin=vmin, cbmax=vmax, ) return fig, ax, cnorm, cmap, cb
def plot_imag(cid, ax, plotman, title, alpha, vmin, vmax, xmin, xmax, zmin, zmax, xunit, cbtiks, elecs): '''Plot imag parts of the complex conductivity using the imag_options. ''' # handle options cblabel = units.get_label('log_imag') zlabel = 'z [' + xunit + ']' xlabel = 'x [' + xunit + ']' cm = 'plasma_r' xmin, xmax, zmin, zmax, vmin, vmax = check_minmax( plotman, cid, xmin, xmax, zmin, zmax, vmin, vmax, ) print('IMAG vmin/vmax', vmin, vmax) # plot fig, ax, cnorm, cmap, cb, scalarMap = plotman.plot_elements_to_ax( cid=cid, cid_alpha=alpha, ax=ax, xmin=xmin, xmax=xmax, zmin=zmin, zmax=zmax, cblabel=cblabel, cbnrticks=cbtiks, title=title, zlabel=zlabel, xlabel=xlabel, plot_colorbar=True, cmap_name=cm, no_elecs=elecs, cbmin=vmin, cbmax=vmax, ) return fig, ax, cnorm, cmap, cb
def plot_histograms(ertobj, keys, **kwargs): """Generate histograms for one or more keys in the given container. Parameters ---------- ertobj : container instance or :class:`pandas.DataFrame` data object which contains the data. keys : str or list of strings which keys (column names) to plot merge : bool, optional if True, then generate only one figure with all key-plots as columns (default True) log10plot : bool, optional default: True extra_dims : list, optional Examples -------- >>> from reda.plotters import plot_histograms >>> from reda.testing import ERTContainer >>> figs_dict = plot_histograms(ERTContainer, "r", merge=False) Generating histogram plot for key: r Returns ------- figures : dict dictionary with the generated histogram figures """ # you can either provide a DataFrame or an ERT object if isinstance(ertobj, pd.DataFrame): df = ertobj else: df = ertobj.data if df.shape[0] == 0: raise Exception('No data present, cannot plot') if isinstance(keys, str): keys = [ keys, ] figures = {} merge_figs = kwargs.get('merge', True) if merge_figs: nr_x = 2 nr_y = len(keys) size_x = 15 / 2.54 size_y = 5 * nr_y / 2.54 fig, axes_all = plt.subplots(nr_y, nr_x, figsize=(size_x, size_y)) axes_all = np.atleast_2d(axes_all) for row_nr, key in enumerate(keys): print('Generating histogram plot for key: {0}'.format(key)) subdata_raw = df[key].values subdata = subdata_raw[~np.isnan(subdata_raw)] subdata = subdata[np.isfinite(subdata)] subdata_log10_with_nan = np.log10(subdata[subdata > 0]) subdata_log10 = subdata_log10_with_nan[~np.isnan(subdata_log10_with_nan )] subdata_log10 = subdata_log10[np.isfinite(subdata_log10)] if merge_figs: axes = axes_all[row_nr].squeeze() else: fig, axes = plt.subplots(1, 2, figsize=(10 / 2.54, 5 / 2.54)) ax = axes[0] ax.hist( subdata, _get_nr_bins(subdata.size), ) ax.set_xlabel(units.get_label(key)) ax.set_ylabel('count') ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(5)) ax.tick_params(axis='both', which='major', labelsize=6) ax.tick_params(axis='both', which='minor', labelsize=6) if subdata_log10.size > 0: ax = axes[1] ax.hist( subdata_log10, _get_nr_bins(subdata.size), ) ax.set_xlabel(r'$log_{10}($' + units.get_label(key) + ')') ax.set_ylabel('count') ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(5)) else: pass # del(axes[1]) fig.tight_layout() if not merge_figs: figures[key] = fig if merge_figs: figures['all'] = fig return figures
def plot_histograms_extra_dims(dataobj, keys, primary_dim=None, **kwargs): """Produce histograms grouped by one extra dimensions. Produce additional figures for all extra dimensions. The dimension to spread out along subplots is called the primary extra dimension. Extra dimensions are: * timesteps * frequency If only "timesteps" are present, timesteps will be plotted as subplots. If only "frequencies" are present, frequencies will be plotted as subplots. If more than one extra dimensions is present, multiple figures will be generated. Test cases: * not extra dims present (primary_dim=None, timestep, frequency) * timestep (primary_dim=None, timestep, frequency) * frequency (primary_dim=None, timestep, frequency) * timestep + frequency (primary_dim=None, timestep, frequency) check nr of returned figures. Parameters ---------- dataobj : :py:class:`pandas.DataFrame` or reda container The data container/data frame which holds the data keys : string|list|tuple|iterable The keys (columns) of the dataobj to plot primary_dim : string primary extra dimension to plot along subplots. If None, the first extra dimension found in the data set is used, in the following order: timestep, frequency. subquery : str, optional if provided, apply this query statement to the data before plotting log10 : bool Plot only log10 transformation of data (default: False) lin_and_log10 : bool Plot both linear and log10 representation of data (default: False) Nx : int, optional Number of subplots in x direction Returns ------- dim_name : str name of secondary dimensions, i.e. the dimensions for which separate figures were created figures : dict dict containing the generated figures. The keys of the dict correspond to the secondary dimension grouping keys Examples -------- >>> import reda.testing.containers >>> ert = reda.testing.containers.ERTContainer_nr >>> import reda.plotters.histograms as RH >>> dim_name, fig = RH.plot_histograms_extra_dims(ert, ['r', ]) >>> import reda.testing.containers >>> ert = reda.testing.containers.ERTContainer_nr >>> import reda.plotters.histograms as RH >>> dim_name, fig = RH.plot_histograms_extra_dims(ert, ['r', 'a']) """ if isinstance(dataobj, pd.DataFrame): df_raw = dataobj else: df_raw = dataobj.data if kwargs.get('subquery', False): df = df_raw.query(kwargs.get('subquery')) else: df = df_raw # define some labels edim_labels = { 'timestep': ('time', ''), 'frequency': ( 'frequency', 'Hz', ), } # prepare data columns to plot if isinstance(keys, str): keys = [ keys, ] columns = keys N_c = len(columns) # create log10 plots? if kwargs.get('lin_and_log10', False): transformers = ['lin', 'log10'] N_trafo = 2 elif kwargs.get('log10', False): transformers = [ 'log10', ] N_trafo = 1 else: transformers = [ 'lin', ] N_trafo = 1 # available extra dimensions extra_dims = ('timestep', 'frequency') # select dimension to plot into subplots if primary_dim is None or primary_dim not in df.columns: for extra_dim in extra_dims: if extra_dim in df.columns: primary_dim = extra_dim # now primary_dim is either None (i.e., we don't have any extra dims to # group), or it contains a valid column to group # now prepare the secondary dimensions for which we create extra figures secondary_dimensions = [] for extra_dim in extra_dims: if extra_dim in df.columns and extra_dim != primary_dim: secondary_dimensions.append(extra_dim) # group secondary dimensions, or create a tuple with all the data if secondary_dimensions: group_secondary = df.groupby(secondary_dimensions) else: group_secondary = (('all', df), ) figures = {} for sec_g_name, sec_g in group_secondary: # group over primary dimension if primary_dim is None: group_primary = (('all', sec_g), ) N_primary = 1 else: group_primary = sec_g.groupby(primary_dim) N_primary = group_primary.ngroups # determine layout of Figure Nx_max = kwargs.get('Nx', 4) N = N_primary * N_c * N_trafo Nx = min(Nx_max, N) Ny = int(np.ceil(N / Nx)) size_x = 5 * Nx / 2.54 size_y = 5 * Ny / 2.54 fig, axes = plt.subplots(Ny, Nx, figsize=(size_x, size_y), sharex=True, sharey=True) axes = np.atleast_2d(axes) index = 0 for p_name, pgroup in group_primary: for column in columns: for transformer in transformers: # print('{0}-{1}-{2}'.format(ts_name, column, transformer)) subdata_raw = pgroup[column].values subdata = subdata_raw[~np.isnan(subdata_raw)] subdata = subdata[np.isfinite(subdata)] if transformer == 'log10': subdata_log10_with_nan = np.log10(subdata[subdata > 0]) subdata_log10 = subdata_log10_with_nan[ ~np.isnan(subdata_log10_with_nan)] subdata_log10 = subdata_log10[np.isfinite( subdata_log10)] subdata = subdata_log10 ax = axes.flat[index] ax.hist( subdata, _get_nr_bins(subdata.size), ) ax.set_xlabel(units.get_label(column)) ax.set_ylabel('count') ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(3)) ax.tick_params(axis='both', which='major', labelsize=6) ax.tick_params(axis='both', which='minor', labelsize=6) # depending on the type of pname, change the format p_name_fmt = '{}' from numbers import Number if isinstance(p_name, Number): p_name_fmt = '{:.4f}' title_str = '{}: ' + p_name_fmt + ' {}' ax.set_title( title_str.format( edim_labels[primary_dim][0], p_name, edim_labels[primary_dim][1], ), fontsize=7.0, ) index += 1 # remove some labels for ax in axes[:, 1:].flat: ax.set_ylabel('') for ax in axes[:-1, :].flat: ax.set_xlabel('') fig.tight_layout() for ax in axes.flat[index:]: ax.set_visible(False) figures[sec_g_name] = fig return '_'.join(secondary_dimensions), figures
def plot_pseudosection_type2(dataobj, column, **kwargs): """Create a pseudosection plot of type 2. For a given measurement data set, create plots that graphically show the data in a 2D color plot. Hereby, x and y coordinates in the plot are determined by the current dipole (x-axis) and voltage dipole (y-axis) of the corresponding measurement configurations. This type of rawdata plot can plot any type of measurement configurations, i.e., it is not restricted to certain types of configurations such as Dipole-dipole or Wenner configurations. However, spatial inferences cannot be made from the plots for all configuration types. Coordinates are generated by separately sorting the dipoles (current/voltage) along the first electrode, and then subsequently sorting by the difference (skip) between both electrodes. Note that this type of raw data plot does not take into account the real electrode spacing of the measurement setup. Type 2 plots can show normal and reciprocal data at the same time. Hereby the upper left triangle of the plot area usually contains normal data, and the lower right triangle contains the corresponding reciprocal data. Therefore a quick assessment of normal-reciprocal differences can be made by visually comparing the symmetry on the 1:1 line going from the lower left corner to the upper right corner. Note that this interpretation usually only holds for Dipole-Dipole data (and the related Wenner configurations). Parameters ---------- dataobj: ERT container|pandas.DataFrame Container or DataFrame with data to plot column: string Column key to plot ax: matplotlib.Axes object, optional axes object to plot to. If not provided, a new figure and axes object will be created and returned nocb: bool, optional if set to False, don't plot the colorbar cblabel: string, optional label for the colorbar cbmin: float, optional colorbar minimum cbmax: float, optional colorbar maximum xlabel: string, optional xlabel for the plot ylabel: string, optional ylabel for the plot do_not_saturate: bool, optional if set to True, then values outside the colorbar range will not saturate with the respective limit colors. Instead, values lower than the CB are colored "cyan" and vaues above the CB limit are colored "red" log10: bool, optional if set to True, plot the log10 values of the provided data Returns ------- fig: figure object ax: axes object cb: colorbar object Examples -------- You can just supply a pandas.DataFrame to the plot function: .. plot:: :include-source: import numpy as np configs = np.array(( (1, 2, 4, 3), (1, 2, 5, 4), (1, 2, 6, 5), (2, 3, 5, 4), (2, 3, 6, 5), (3, 4, 6, 5), )) measurements = np.random.random(configs.shape[0]) import pandas as pd df = pd.DataFrame(configs, columns=['a', 'b', 'm', 'n']) df['measurements'] = measurements from reda.plotters.pseudoplots import plot_pseudosection_type2 fig, ax, cb = plot_pseudosection_type2( dataobj=df, column='measurements', ) You can also supply axes to plot to: .. plot:: :include-source: import numpy as np configs = np.array(( (1, 2, 4, 3), (1, 2, 5, 4), (1, 2, 6, 5), (2, 3, 5, 4), (2, 3, 6, 5), (3, 4, 6, 5), )) measurements = np.random.random(configs.shape[0]) measurements2 = np.random.random(configs.shape[0]) import pandas as pd df = pd.DataFrame(configs, columns=['a', 'b', 'm', 'n']) df['measurements'] = measurements df['measurements2'] = measurements2 from reda.plotters.pseudoplots import plot_pseudosection_type2 fig, axes = plt.subplots(1, 2) plot_pseudosection_type2( df, column='measurements', ax=axes[0], cblabel='this label', xlabel='xlabel', ylabel='ylabel', ) plot_pseudosection_type2( df, column='measurements2', ax=axes[1], cblabel='measurement 2', xlabel='xlabel', ylabel='ylabel', ) fig.tight_layout() >>> from reda.testing.containers import ERTContainer_nr >>> import reda.plotters.pseudoplots as ps >>> fig, axes, cb = ps.plot_pseudosection_type2(ERTContainer_nr, 'r') """ if isinstance(dataobj, pd.DataFrame): df = dataobj else: df = dataobj.data c = df[['a', 'b', 'm', 'n']].values AB_ids = _get_unique_identifiers(c[:, 0:2]) MN_ids = _get_unique_identifiers(c[:, 2:4]) ab_sorted = np.sort(c[:, 0:2], axis=1) mn_sorted = np.sort(c[:, 2:4], axis=1) AB_coords = [ AB_ids[x] for x in (ab_sorted[:, 0] * 1e5 + ab_sorted[:, 1]).astype(int) ] MN_coords = [ MN_ids[x] for x in (mn_sorted[:, 0] * 1e5 + mn_sorted[:, 1]).astype(int) ] # check for duplicate positions ABMN_coords = np.vstack((AB_coords, MN_coords)).T.copy() _, counts = np.unique( ABMN_coords.view(ABMN_coords.dtype.descr * 2), return_counts=True, ) # import IPython # IPython.embed() # exit() if np.any(counts > 1): print('found duplicate coordinates!') # duplicate_configs = np.where(counts > 1)[0] # print('duplicate configs:') # print('A B M N') # for i in duplicate_configs: # print(c[i, :]) # prepare matrix plot_values = np.squeeze(df[column].values) if kwargs.get('log10', False): plot_values = np.log10(plot_values) C = np.zeros((len(MN_ids.items()), len(AB_ids))) * np.nan C[MN_coords, AB_coords] = plot_values # for display purposes, reverse the first dimension C = C[::-1, :] ax = kwargs.get('ax', None) if ax is None: fig, ax = plt.subplots(1, 1, figsize=(15 / 2.54, 10 / 2.54)) fig = ax.get_figure() cmap = mpl.cm.get_cmap('viridis') if kwargs.get('do_not_saturate', False): cmap.set_over(color='r') cmap.set_under(color='c') im = ax.matshow( C, interpolation='none', cmap=cmap, aspect='auto', vmin=kwargs.get('cbmin', None), vmax=kwargs.get('cbmax', None), extent=[ 0, max(AB_coords), 0, max(MN_coords), ], ) max_xy = max((max(AB_coords), max(MN_coords))) ax.plot( (0, max_xy), (0, max_xy), '-', color='k', linewidth=1.0, ) cb = None if not kwargs.get('nocb', False): cb = fig.colorbar(im, ax=ax) label = units.get_label(column) if mpl.rcParams['text.usetex']: label = label.replace('_', '-') cb.set_label(kwargs.get('cblabel', label)) ax.set_xlabel(kwargs.get('xlabel', 'current dipoles')) ax.set_ylabel(kwargs.get('ylabel', 'voltage dipoles')) return fig, ax, cb
def plot_pseudosection_type3(dataobj, column, **kwargs): """Create a pseudosection plot of type 3. For a given measurement data set, create plots that graphically show the data in a 2D pseudoplot. Hereby, x and y coordinates (pseudodistance and pseudodepth) in the plot are determined by the corresponding measurement configuration (after Roy and Apparao (1971) and Dahlin and Zou (2005)). This type of rawdata plot can plot any type of measurement configurations, i.e., it is not restricted to certain types of configurations such as Dipole-dipole or Wenner configurations. Parameters ---------- dataobj: ERT container|pandas.DataFrame Container or DataFrame with data to plot column: string Column key to plot ax: matplotlib.Axes object, optional axes object to plot to. If not provided, a new figure and axes object will be created and returned nocb: bool, optional if set to False, don't plot the colorbar cblabel: string, optional label for the colorbar cbmin: float, optional colorbar minimum cbmax: float, optional colorbar maximum xlabel: string, optional xlabel for the plot ylabel: string, optional ylabel for the plot do_not_saturate: bool, optional if set to True, then values outside the colorbar range will not saturate with the respective limit colors. Instead, values lower than the CB are colored "cyan" and vaues above the CB limit are colored "red" markersize: float, optional size of plotted data points spacing: float, optional if set to True, the actual electrode spacing is used for the computation of the pseudodepth and -distance; default value is 1 m log10: bool, optional if set to True, plot the log10 values of the provided data Returns ------- fig: figure object ax: axes object cb: colorbar object Examples -------- You can just supply a pandas.DataFrame to the plot function: .. plot:: :include-source: import numpy as np configs = np.array(( (1, 2, 4, 3), (1, 2, 5, 4), (1, 2, 6, 5), (2, 3, 5, 4), (2, 3, 6, 5), (3, 4, 6, 5), )) measurements = np.random.random(configs.shape[0]) import pandas as pd df = pd.DataFrame(configs, columns=['a', 'b', 'm', 'n']) df['measurements'] = measurements from reda.plotters.pseudoplots import plot_pseudosection_type3 fig, ax, cb = plot_pseudosection_type3( dataobj=df, column='measurements', ) You can also supply axes to plot to: .. plot:: :include-source: import numpy as np configs = np.array(( (1, 2, 4, 3), (1, 2, 5, 4), (1, 2, 6, 5), (2, 3, 5, 4), (2, 3, 6, 5), (3, 4, 6, 5), )) measurements = np.random.random(configs.shape[0]) measurements2 = np.random.random(configs.shape[0]) import pandas as pd df = pd.DataFrame(configs, columns=['a', 'b', 'm', 'n']) df['measurements'] = measurements df['measurements2'] = measurements2 from reda.plotters.pseudoplots import plot_pseudosection_type3 fig, axes = plt.subplots(1, 2) plot_pseudosection_type3( df, column='measurements', ax=axes[0], cblabel='this label', xlabel='xlabel', ylabel='ylabel', ) plot_pseudosection_type3( df, column='measurements2', ax=axes[1], cblabel='measurement 2', xlabel='xlabel', ylabel='ylabel', ) fig.tight_layout() """ if isinstance(dataobj, pd.DataFrame): df = dataobj else: df = dataobj.data c = (df[['a', 'b', 'm', 'n']] - 1) * kwargs.get('spacing', 1) # define the configuration # check on first quadrupole and assume the config is consistent # dipole-dipole if (sum(np.greater([c.a[0], c.b[0]], [c.m[0], c.n[0]])) == 2 or sum(np.greater([c.m[0], c.n[0]], [c.a[0], c.b[0]])) == 2): c.loc[:, 'xp'] = ((c.a + c.b) / 2 + (c.n + c.m) / 2) / 2 c.loc[:, 'zp'] = -((c.n - c.b) * 0.195) # Roi and Appparo # multiple gradient else: xmn = (c.m + c.n) / 2 c.loc[:, 'xp'] = xmn c.loc[:, 'zp'] = np.abs( np.min([xmn - c.a, c.b - xmn], axis=0) / 3) * -1 # Dahlin, Zhou # extract the values to plot c['plot_values'] = df[column] if kwargs.get('log10', False): c['plot_values'] = np.log10(c['plot_values']) # sort after the pseudodistance and pseudodepth pseudocoords = c[['xp', 'zp', 'plot_values']].sort_values(by=['xp', 'zp']) ax = kwargs.get('ax', None) if ax is None: fig, ax = plt.subplots(1, 1, figsize=(15 / 2.54, 10 / 2.54)) fig = ax.get_figure() cmap = mpl.cm.get_cmap('viridis') if kwargs.get('do_not_saturate', False): cmap.set_over(color='r') cmap.set_under(color='c') pseudocoords['markersize'] = kwargs.get('markersize', 10) # check for same pseudocoordinates common_pscoords = pseudocoords[['xp', 'zp']].drop_duplicates() def smallify(markersize_array): """ For a given array of markersizes (with same size) compute a stepwise decreasing factor for the plotting size based on the length of the array. """ nelems = len(markersize_array) factor = 1 / nelems return markersize_array * np.flip(np.arange(1, nelems + 1) * factor) # check for overlapping points and adjust markersize accordingly for _, common in common_pscoords.iterrows(): subset = pseudocoords.query('xp == {} and zp == {}'.format( common.xp, common.zp)) pseudocoords.loc[subset.index, 'markersize'] = smallify( pseudocoords.loc[subset.index, 'markersize'].values) scat = ax.scatter(pseudocoords['xp'], pseudocoords['zp'], s=pseudocoords['markersize'], c=pseudocoords['plot_values'], marker='o', edgecolors='none', cmap=cmap, vmin=kwargs.get('cbmin', None), vmax=kwargs.get('cbmax', None), alpha=1) ax.set_xlim([ np.min(c['xp']) - 1 * kwargs.get('spacing', 1), np.max(c['xp']) + 1 * kwargs.get('spacing', 1) ]) ax.set_ylim([ np.min(c['zp']) - 1 * kwargs.get('spacing', 1), np.max(c['zp']) + 1 * kwargs.get('spacing', 1) ]) cb = None if not kwargs.get('nocb', False): cb = fig.colorbar(scat, ax=ax) cb.set_label(kwargs.get('cblabel', units.get_label(column))) ax.set_xlabel(kwargs.get('xlabel', 'Pseudodistance')) ax.set_ylabel(kwargs.get('ylabel', 'Pseudodepth')) return fig, ax, cb
def plot_histograms_extra_dims(dataobj, keys, **kwargs): """Produce histograms grouped by the extra dims. Parameters ---------- Examples -------- >>> import reda.testing.containers >>> ert = reda.testing.containers.ERTContainer_nr >>> import reda.plotters.histograms as RH >>> fig = RH.plot_histograms_extra_dims(ert, ['R', ]) >>> fig <matplotlib.figure.Figure object at ...> >>> import reda.testing.containers >>> ert = reda.testing.containers.ERTContainer_nr >>> import reda.plotters.histograms as RH >>> fig = RH.plot_histograms_extra_dims(ert, ['R', 'A']) >>> fig <matplotlib.figure.Figure object at ...> """ if isinstance(dataobj, pd.DataFrame): df_raw = dataobj else: df_raw = dataobj.data if kwargs.get('subquery', False): df = df_raw.query(kwargs.get('subquery')) else: df = df_raw split_timestamps = True if split_timestamps: group_timestamps = df.groupby('timestep') N_ts = len(group_timestamps.groups.keys()) else: group_timestamps = ('all', df) N_ts = 1 columns = keys N_c = len(columns) plot_log10 = kwargs.get('log10plot', False) if plot_log10: transformers = ['lin', 'log10'] N_log10 = 2 else: transformers = ['lin', ] N_log10 = 1 # determine layout of plots Nx_max = kwargs.get('Nx', 4) N = N_ts * N_c * N_log10 Nx = min(Nx_max, N) Ny = int(np.ceil(N / Nx)) size_x = 4 * Nx / 2.54 size_y = 5 * Ny / 2.54 fig, axes = plt.subplots(Ny, Nx, figsize=(size_x, size_y)) axes = np.atleast_2d(axes) index = 0 for ts_name, tgroup in group_timestamps: for column in columns: for transformer in transformers: # print('{0}-{1}-{2}'.format(ts_name, column, transformer)) subdata_raw = tgroup[column].values subdata = subdata_raw[~np.isnan(subdata_raw)] subdata = subdata[np.isfinite(subdata)] if transformer == 'log10': subdata_log10_with_nan = np.log10(subdata[subdata > 0]) subdata_log10 = subdata_log10_with_nan[~np.isnan( subdata_log10_with_nan) ] subdata_log10 = subdata_log10[np.isfinite(subdata_log10)] subdata = subdata_log10 ax = axes.flat[index] ax.hist( subdata, _get_nr_bins(subdata.size), ) ax.set_xlabel( units.get_label(column) ) ax.set_ylabel('count') ax.xaxis.set_major_locator(mpl.ticker.MaxNLocator(3)) index += 1 # remove some labels for ax in axes[:, 1:].flat: ax.set_ylabel('') fig.tight_layout() return fig
def create_singleplots(plotman, cov, mag, pha, pha_fpi, alpha, options): '''Plot the data of the tomodir in individual plots. ''' if cov is None: cov = np.ones_like(mag) * np.nan magunit = 'log_rho' if not pha == []: [real, imag] = calc_complex(mag, pha) if options.c_in_log: real = np.log10(real) with np.errstate(divide='ignore'): imag = np.log10(imag) imag[np.isinf(imag)] = np.nan if not pha_fpi == []: [real_fpi, imag_fpi] = calc_complex(mag, pha_fpi) if options.cmaglin: mag = np.power(10, mag) magunit = 'rho' if options.c_in_log: real_fpi = np.log10(real_fpi) with np.errstate(divide='ignore'): imag_fpi = np.log10(imag_fpi) imag_fpi[np.isinf(imag_fpi)] = np.nan # import IPython # IPython.embed() # print(imag_fpi, np.nanmin(imag_fpi), np.nanmax(imag_fpi)) # print(options.imag_vmin, options.imag_vmax) # exit() data = np.column_stack(( mag, cov, pha, real, imag, pha_fpi, real_fpi, imag_fpi )) titles = [ 'Magnitude', 'Coverage', 'Phase', 'Real Part', 'Imaginary Part', 'FPI Phase', 'FPI Real Part', 'FPI Imaginary Part' ] unites = [ magunit, 'cov', 'phi', 'log_real', 'log_imag', 'phi', 'log_real', 'log_imag' ] vmins = [ options.mag_vmin, options.cov_vmin, options.pha_vmin, options.real_vmin, options.imag_vmin, options.pha_vmin, options.real_vmin, options.imag_vmin ] vmaxs = [options.mag_vmax, options.cov_vmax, options.pha_vmax, options.real_vmax, options.imag_vmax, options.pha_vmax, options.real_vmax, options.imag_vmax] cmaps = ['jet', 'GnBu', 'jet_r', 'jet_r', 'plasma_r', 'jet_r', 'jet_r', 'plasma_r'] saves = ['rho', 'cov', 'phi', 'real', 'imag', 'fpi_phi', 'fpi_real', 'fpi_imag'] else: if options.cmaglin: mag = np.power(10, mag) magunit = 'rho' data = np.column_stack((mag, cov, pha, real, imag)) titles = ['Magnitude', 'Coverage', 'Phase', 'Real Part', 'Imaginary Part'] unites = [magunit, 'cov', 'phi', 'log_real', 'log_imag'] vmins = [options.mag_vmin, options.cov_vmin, options.pha_vmin, options.real_vmin, options.imag_vmin] vmaxs = [options.mag_vmax, options.cov_vmax, options.pha_vmax, options.real_vmax, options.imag_vmax] cmaps = ['jet', 'GnBu', 'jet_r', 'jet_r', 'plasma_r'] saves = ['rho', 'cov', 'phi', 'real', 'imag'] else: data = np.column_stack((mag, cov)) titles = ['Magnitude', 'Coverage'] unites = [magunit, 'cov'] vmins = [options.mag_vmin, options.cov_vmin] vmaxs = [options.mag_vmax, options.cov_vmax] cmaps = ['jet', 'GnBu'] saves = ['rho', 'cov'] try: mod_rho = np.genfromtxt('rho/rho.dat', skip_header=1, usecols=([0])) mod_pha = np.genfromtxt('rho/rho.dat', skip_header=1, usecols=([1])) data = np.column_stack((data, mod_rho, mod_pha)) titles.append('Model') titles.append('Model') unites.append('rho') unites.append('phi') vmins.append(options.mag_vmin) vmins.append(options.pha_vmin) vmaxs.append(options.mag_vmax) vmaxs.append(options.pha_vmax) cmaps.append('jet') cmaps.append('plasma') saves.append('rhomod') saves.append('phamod') except Exception: pass for datum, title, unit, vmin, vmax, cm, save in zip( np.transpose(data), titles, unites, vmins, vmaxs, cmaps, saves): # print(save) # if save == 'fpi_imag': # import IPython # IPython.embed() sizex, sizez = getfigsize(plotman) f, ax = plt.subplots(1, figsize=(sizex, sizez)) cid = plotman.parman.add_data(datum) # handle options cblabel = units.get_label(unit) if options.title is not None: title = options.title zlabel = 'z [' + options.unit + ']' xlabel = 'x [' + options.unit + ']' xmin, xmax, zmin, zmax, vmin, vmax = check_minmax( plotman, cid, options.xmin, options.xmax, options.zmin, options.zmax, vmin, vmax ) # plot cmap = mpl_cm.get_cmap(cm) fig, ax, cnorm, cmap, cb, scalarMap = plotman.plot_elements_to_ax( cid=cid, cid_alpha=alpha, ax=ax, xmin=xmin, xmax=xmax, zmin=zmin, zmax=zmax, cblabel=cblabel, title=title, zlabel=zlabel, xlabel=xlabel, plot_colorbar=True, cmap_name=cm, over=cmap(1.0), under=cmap(0.0), no_elecs=options.no_elecs, cbmin=vmin, cbmax=vmax, ) f.tight_layout() f.savefig(save + '.png', dpi=300)