diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 6a08bd627..83de7011d 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 0.3.5 +current_version = 0.3.6 files = setup.py discretize/__init__.py docs/conf.py diff --git a/discretize/View.py b/discretize/View.py index 21b2555ae..1ef5b7e8e 100644 --- a/discretize/View.py +++ b/discretize/View.py @@ -700,8 +700,9 @@ def plotGrid( def plot_3d_slicer(self, v, xslice=None, yslice=None, zslice=None, - vType='CC', view='xy', transparent=None, clim=None, - aspect='auto', grid=[2, 2, 1], pcolorOpts=None): + vType='CC', view='real', axis='xy', transparent=None, + clim=None, aspect='auto', grid=[2, 2, 1], + pcolorOpts=None): """Plot slices of a 3D volume, interactively (scroll wheel). If called from a notebook, make sure to set @@ -728,7 +729,7 @@ def plot_3d_slicer(self, v, xslice=None, yslice=None, zslice=None, fig = plt.figure() # Populate figure - tracker = Slicer(self, v, xslice, yslice, zslice, vType, view, + tracker = Slicer(self, v, xslice, yslice, zslice, vType, view, axis, transparent, clim, aspect, grid, pcolorOpts) # Connect figure to scrolling @@ -1152,9 +1153,14 @@ class Slicer(object): defaults to the middle of the volume. vType: str - Type of visualization. At the moment only 'CC' is implemented. + Type of visualization. Default is 'CC'. + One of ['CC', 'Fx', 'Fy', 'Fz', 'Ex', 'Ey', 'Ez']. - view : 'xy' (default) or 'yx' + view : str + Which component to show. Defaults to 'real'. + One of ['real', 'imag', 'abs']. + + axis : 'xy' (default) or 'yx' 'xy': horizontal axis is x, vertical axis is y. Reversed otherwise. transparent : 'slider' or list of floats or pairs of floats, optional @@ -1187,26 +1193,53 @@ class Slicer(object): """ def __init__(self, mesh, v, xslice=None, yslice=None, zslice=None, - vType='CC', view='xy', transparent=None, clim=None, - aspect='auto', grid=[2, 2, 1], pcolorOpts=None): + vType='CC', view='real', axis='xy', transparent=None, + clim=None, aspect='auto', grid=[2, 2, 1], pcolorOpts=None): """Initialize interactive figure.""" # 0. Some checks, not very extensive + + # (a) Mesh dimensionality if mesh.dim != 3: err = 'Must be a 3D mesh. Use plotImage instead.' err += ' Mesh provided has {} dimension(s).'.format(mesh.dim) raise ValueError(err) - vTypeOpts = ['CC', ] + # (b) vType # Not yet working for ['CCv'] + vTypeOpts = ['CC', 'Fx', 'Fy', 'Fz', 'Ex', 'Ey', 'Ez'] if vType not in vTypeOpts: err = "vType must be in ['{0!s}'].".format("', '".join(vTypeOpts)) err += " vType provided: '{0!s}'.".format(vType) raise ValueError(err) + if vType != 'CC': + aveOp = 'ave' + vType + '2CC' + Av = getattr(mesh, aveOp) + if v.size == Av.shape[1]: + v = Av * v + else: + v = mesh.r(v, vType[0], vType) # get specific component + v = Av * v + + # (c) vOpts # Not yet working for 'vec' + + # Backwards compatibility + if view in ['xy', 'yx']: + axis = view + view = 'real' + + viewOpts = ['real', 'imag', 'abs'] + if view in viewOpts: + v = getattr(np, view)(v) # e.g. np.real(v) + else: + err = "view must be in ['{0!s}'].".format("', '".join(viewOpts)) + err += " view provided: '{0!s}'.".format(view) + raise ValueError(err) + # 1. Store relevant data # Store data in self as (nx, ny, nz) - self.v = v.reshape(mesh.nCx, mesh.nCy, mesh.nCz, order='F').copy() + self.v = mesh.r(v.reshape((mesh.nC, -1), order='F'), 'CC', 'CC', 'M') self.v = np.ma.masked_where(np.isnan(self.v), self.v) # Store relevant information from mesh in self @@ -1217,12 +1250,9 @@ def __init__(self, mesh, v, xslice=None, yslice=None, zslice=None, self.yc = mesh.vectorCCy # y-cell center locations self.zc = mesh.vectorCCz # z-cell center locations - # View: Default ('xy'): horizontal axis is x, vertical axis is y. + # Axis: Default ('xy'): horizontal axis is x, vertical axis is y. # Reversed otherwise. - if view == 'yx': - self.yx = True - else: - self.yx = False + self.yx = axis == 'yx' # Store initial slice indices; if not provided, takes the middle. if xslice is not None: @@ -1384,19 +1414,19 @@ def onscroll(self, event): # Update slice index depending on subplot over which mouse is if event.inaxes == self.ax1: # X-Y - self.zind = (self.zind + pm) % (self.zc.size - 1) + self.zind = (self.zind + pm) % self.zc.size self.update_xy() elif event.inaxes == self.ax2: # X-Z if self.yx: - self.xind = (self.xind + pm) % (self.xc.size - 1) + self.xind = (self.xind + pm) % self.xc.size else: - self.yind = (self.yind + pm) % (self.yc.size - 1) + self.yind = (self.yind + pm) % self.yc.size self.update_xz() elif event.inaxes == self.ax3: # Z-Y if self.yx: - self.yind = (self.yind + pm) % (self.yc.size - 1) + self.yind = (self.yind + pm) % self.yc.size else: - self.xind = (self.xind + pm) % (self.xc.size - 1) + self.xind = (self.xind + pm) % self.xc.size self.update_zy() plt.draw() diff --git a/discretize/__init__.py b/discretize/__init__.py index b9167c881..40ddd89a3 100644 --- a/discretize/__init__.py +++ b/discretize/__init__.py @@ -27,7 +27,7 @@ """ ) -__version__ = '0.3.5' +__version__ = '0.3.6' __author__ = 'SimPEG Team' __license__ = 'MIT' __copyright__ = '2013 - 2017, SimPEG Developers, http://simpeg.xyz' diff --git a/docs/conf.py b/docs/conf.py index d36c0e520..7aceda339 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,9 +60,9 @@ # built documents. # # The short X.Y version. -version = '0.3.5' +version = '0.3.6' # The full version, including alpha/beta/rc tags. -release = '0.3.5' +release = '0.3.6' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index 8f2b20f99..b222ddc05 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ def configuration(parent_package='', top_path=None): setup( name="discretize", - version="0.3.5", + version="0.3.6", install_requires=[ 'numpy>=1.7', 'scipy>=0.13',