Source code for pygimli.viewer.mpl.modelview

# -*- coding: utf-8 -*-
"""Model viewer functions."""
import numpy as np

import pygimli as pg
from pygimli.utils import rndig

from .colorbar import setMappableData
from .utils import updateAxes as updateAxes_


[docs] def drawModel1D(ax, thickness=None, values=None, model=None, depths=None, plot='plot', xlabel=r'Resistivity $(\Omega$m$)$', zlabel='Depth (m)', z0=0, zmax=None, **kwargs): """Draw 1d block model into axis ax. Draw 1d block model into axis ax defined by values and thickness vectors using plot function. For log y cases, z0 should be set > 0 so that the default becomes 1. Parameters ---------- ax : mpl axes Matplotlib Axes object to plot into. values : iterable [float] [N] Values for each layer plus lower background. thickness : iterable [float] [N-1] thickness for each layer. Either thickness or depths must be set. depths : iterable [float] [N-1] Values for layer depths (positive z-coordinates). Either thickness or depths must be set. model : iterable [float] Shortcut to use default model definition. thks = model[0:nLay] values = model[nLay:] plot : string Matplotlib plotting function. 'plot', 'semilogx', 'semilogy', 'loglog' xlabel : str Label for x axis. ylabel : str Label for y axis. z0 : float Starting depth in m **kwargs : dict() Forwarded to the plot routine Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> import pygimli as pg >>> # plt.style.use('ggplot') >>> thk = [1, 4, 4] >>> res = np.array([10., 5, 15, 50]) >>> fig, ax = plt.subplots() >>> pg.viewer.mpl.drawModel1D(ax, values=res*5, depths=np.cumsum(thk), ... plot='semilogx', color='blue') >>> pg.viewer.mpl.drawModel1D(ax, values=res, thickness=thk, z0=1, ... plot='semilogx', color='red') >>> pg.wait() """ if model is not None: nLayers = (len(model)-1)//2 thickness = model[:nLayers] values = model[nLayers:] if thickness is None and depths is None: raise Exception("Either thickness or depths must be given.") nLayers = len(values) px = np.zeros(nLayers * 2) pz = np.zeros(nLayers * 2) if thickness is not None: z1 = np.cumsum(thickness) + z0 else: z1 = depths for i in range(nLayers): px[2 * i] = values[i] px[2 * i + 1] = values[i] if i == nLayers - 1: pz[2 * i + 1] = zmax or z1[i - 1] * 1.2 else: pz[2 * i + 1] = z1[i] pz[2 * i + 2] = z1[i] if plot == 'loglog' or plot == 'semilogy': if z0 == 0: pz[0] = z1[0] / 2. else: pz[0] = z0 try: plot = getattr(ax, plot) plot(px, pz+z0, **kwargs) except BaseException as e: print(e) ax.set_ylabel(zlabel) ax.set_xlabel(xlabel) # assume positive depths pointing upward ax.set_ylim(pz[-1], pz[0]) ax.grid(True)
[docs] def draw1DColumn(ax, x, val, thk, width=30, ztopo=0, cMin=1, cMax=1000, cMap=None, name=None, textoffset=0.0, **kwargs): """Draw a 1D column (e.g., from a 1D inversion) on a given ax. Examples -------- >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from pygimli.viewer.mpl import draw1DColumn >>> thk = [1, 2, 3, 4] >>> val = thk >>> fig, ax = plt.subplots() >>> draw1DColumn(ax, 0.5, val, thk, width=0.1, cmin=1, cmax=4, name="VES") <matplotlib.collections.PatchCollection object at ...> >>> _ = ax.set_ylim(-np.sum(thk), 0) """ from matplotlib.patches import Rectangle from matplotlib.collections import PatchCollection from matplotlib.colors import LogNorm z = -np.hstack([0., np.cumsum(thk), np.sum(thk) * 1.5]) + ztopo recs = [] for i in range(len(val)): recs.append(Rectangle((x - width / 2., z[i]), width, z[i + 1] - z[i])) pp = PatchCollection(recs) col = ax.add_collection(pp) pp.set_edgecolor(None) pp.set_linewidth(0.0) if cMap is not None: if isinstance(cMap, str): pp.set_cmap(pg.viewer.mpl.cmapFromName(cMap)) else: pp.set_cmap(cMap) if kwargs.pop("logScale", True): pp.set_norm(LogNorm(cMin, cMax)) pp.set_array(np.array(val)) pp.set_clim(cMin, cMax) if name: ax.text(x+textoffset, ztopo, name, ha='center', va='bottom') updateAxes_(ax) return col
def showmymatrix(mat, x, y, dx=2, dy=1, xlab=None, ylab=None, cbar=None): """What is this good for?.""" pg.critical('who use this?') plt = pg.plt plt.imshow(mat, interpolation='nearest') plt.xticks(np.arange(0, len(x), dx), ["%g" % rndig(xi, 2) for xi in x]) plt.yticks(np.arange(0, len(y), dy), ["%g" % rndig(yi, 2) for yi in y]) plt.ylim((len(y) - 0.5, -0.5)) if xlab is not None: plt.xlabel(xlab) if ylab is not None: plt.ylabel(ylab) plt.axis('auto') if cbar is not None: plt.colorbar(orientation=cbar) return def draw1dmodelErr(x, xL, xU=None, thk=None, xcol='g', ycol='r', **kwargs): """TODO.""" pg.critical("in use?") if thk is None: nlay = (len(x) + 1) / 2 thk = np.array(x)[:nlay - 1] x = np.asarray(x)[nlay - 1:nlay * 2 - 1] thkL = np.array(xL)[:nlay - 1] thkU = np.array(xU)[:nlay - 1] xL = np.asarray(xL)[nlay - 1:nlay * 2 - 1] xU = np.asarray(xU)[nlay - 1:nlay * 2 - 1] # thk0 = np.hstack((thk, 0.)) # thkL0 = np.hstack((thkL, 0.)) # thkU0 = np.hstack((thkU, 0.)) zm = np.hstack((np.cumsum(thk) - thk / 2, np.sum(thk) * 1.2)) # midpoint zc = np.cumsum(thk) # cumulative draw1dmodel(x, thk, **kwargs) plt = pg.plt plt.xlim(min(xL) * 0.95, max(xU) * 1.05) plt.ylim(zm[-1] * 1.1, 0.) plt.errorbar( x, zm, fmt='.', xerr=np.vstack( (x - xL, xU - x)), ecolor=xcol, **kwargs) plt.errorbar((x[:-1] + x[1:]) / 2, zc, fmt='.', yerr=np.vstack((thk - thkL, thkU - thk)), ecolor=ycol)
[docs] def showStitchedModels(models, ax=None, x=None, cMin=None, cMax=None, thk=None, logScale=True, title=None, zMin=0, zMax=0, zLog=False, **kwargs): """Show several 1d block models as (stitched) section. Parameters ---------- model : iterable of iterable (np.ndarray or list of np.array) 1D models (consisting of thicknesses and values) to plot ax : matplotlib axes [None - create new] axes object to plot in x : iterable positions of individual models cMin/cMax : float [None - autodetection from range] minimum and maximum colorscale range logScale : bool [True] use logarithmic color scaling zMin/zMax : float [0 - automatic] range for z (y axis) limits zLog : bool use logarithmic z (y axis) instead of linear topo : iterable vector of elevation for shifting thk : iterable vector of layer thicknesses for all models Returns ------- ax : matplotlib axes [None - create new] axes object to plot in """ from matplotlib.patches import Rectangle from matplotlib.collections import PatchCollection from matplotlib.colors import LogNorm if x is None: x = np.arange(len(models)) topo = kwargs.pop('topo', np.zeros_like(x)) fig = None if ax is None: fig, ax = pg.plt.subplots() dxmed2 = kwargs.pop("width", np.median(np.diff(x))) / 2. patches = [] zMinLimit = 9e99 zMaxLimit = 0 if thk is not None: nlay = len(models[0]) else: nlay = int(np.floor((len(models[0]) + 1) / 2.)) vals = np.zeros((len(models), nlay)) for i, imod in enumerate(models): if thk is not None: # take only resistivity from model vals[i, :] = imod thki = thk else: # extract thickness from model vector if isinstance(imod, pg.Vector): vals[i, :] = imod[nlay - 1:2 * nlay - 1] thki = np.asarray(imod[:nlay - 1]) else: vals[i, :] = imod[nlay - 1:2 * nlay - 1] thki = imod[:nlay - 1] if zMax > 0: z = np.hstack((0., np.cumsum(thki), zMax)) else: thki = np.hstack((thki, thki[-1]*3)) z = np.hstack((0., np.cumsum(thki))) z = topo[i] - z zMinLimit = min(zMinLimit, z[-1]) zMaxLimit = max(zMaxLimit, z[0]) for j in range(nlay): rect = Rectangle((x[i] - dxmed2, z[j]), dxmed2 * 2, z[j+1]-z[j]) patches.append(rect) p = PatchCollection(patches) # , cmap=cmap, linewidths=0) if cMin is not None: p.set_clim(cMin, cMax) setMappableData(p, vals.ravel(), logScale=logScale) ax.add_collection(p) if logScale: norm = LogNorm(cMin, cMax) p.set_norm(norm) if 'cMap' in kwargs: p.set_cmap(kwargs['cMap']) # ax.set_ylim((zMaxLimit, zMin)) ax.set_ylim((zMinLimit, zMaxLimit)) if zLog: ax.set_yscale("log", nonposy='clip') ax.set_xlim((min(x) - dxmed2, max(x) + dxmed2)) if title is not None: ax.set_title(title) if kwargs.pop('colorBar', True): cb = pg.viewer.mpl.createColorBar(p, cMin=cMin, cMax=cMax, nLevs=5) # cb = plt.colorbar(p, orientation='horizontal',aspect=50,pad=0.1) if 'cticks' in kwargs: xt = np.unique(np.clip(kwargs['cticks'], cMin, cMax)) cb.set_ticks(xt) cb.set_ticklabels([str(xti) for xti in xt]) if 'label' in kwargs: cb.set_label(kwargs['label']) pg.plt.draw() return ax # maybe return cb as well?
[docs] def draw1dmodel(x, thk=None, xlab=None, zlab="z in m", islog=True, z0=0): """DEPRECATED.""" pg.critical("STYLE_WARNING!!!!!!! don't use this call. " "WHO use this anymore?? Use show1dmodel or drawModel1D instead.") show1dmodel(x, thk, xlab, zlab, islog, z0)
[docs] def show1dmodel(x, thk=None, xlab=None, zlab="z in m", islog=True, z0=0, **kwargs): """Show 1d block model defined by value and thickness vectors. """ pg.error("rename after naming convention, don't use plt") pg.critical("STYLE_WARNING!!!!!!! don't use this call. " "WHO use this anymore??.") if xlab is None: xlab = "$\\rho$ in $\\Omega$m" if thk is None: # gimli blockmodel (thk+x together) given nl = int(np.floor((len(x) - 1) / 2.)) + 1 thk = np.asarray(x)[:nl - 1] x = np.asarray(x)[nl - 1:nl * 2 - 1] z1 = np.concatenate(([0], np.cumsum(thk))) + z0 z = np.concatenate((z1, [z1[-1] * 1.2])) nl = len(x) # x.size() px = np.zeros((nl * 2, 1)) pz = np.zeros((nl * 2, 1)) for i in range(nl): px[2 * i] = x[i] px[2 * i + 1] = x[i] pz[2 * i + 1] = z[i + 1] if i < nl - 1: pz[2 * i + 2] = z[i + 1] plt = pg.plt # plt.cla() if islog: plt.semilogx(px, pz, **kwargs) else: plt.plot(px, pz, **kwargs) plt.ion() plt.grid(which='both') plt.xlim((np.min(x) * 0.9, np.max(x) * 1.1)) plt.ylim((max(z1) * 1.15, 0.)) plt.xlabel(xlab) plt.ylabel(zlab) plt.show() return
[docs] def showfdemsounding(freq, inphase, quadrat, response=None, npl=2): """Show FDEM sounding as real(inphase) and imaginary (quadrature) fields. Show FDEM sounding as real(inphase) and imaginary (quadrature) fields normalized by the (purely real) free air solution. """ pg.error("rename after naming convention, don't use plt") pg.critical("STYLE_WARNING!!!!!!! don't use this call. " "WHO use this anymore??.") nf = len(freq) plt = pg.plt fig = plt.figure(1) fig.clf() ax1 = fig.add_subplot(1, npl, npl - 1) plt.semilogy(inphase, freq, 'x-') if response is not None: plt.semilogy(np.asarray(response)[:nf], freq, 'x-') plt.grid(which='both') ax2 = fig.add_subplot(1, npl, npl) plt.semilogy(quadrat, freq, 'x-') if response is not None: plt.semilogy(np.asarray(response)[nf:], freq, 'x-') plt.grid(which='both') fig.show() ax = [ax1, ax2] if npl > 2: ax3 = fig.add_subplot(1, npl, 1) ax.append(ax3) return ax