def __call__(self, data): ''' Parameters ---------- data: np.ndarray Surface data to be plotted. Should have the same number of data points as the surface Returns ------- rgba: np.ndarray Bitmap with RGBA values that can be plotted. ''' self._pre_setup() x, y, msk, xi, yi = self._grid_def olay = griddata(x, y, data, xi, yi) olay[-msk] = np.nan o_rgba = flat_surface_data2rgba(olay, self._range_, self._threshold, self._color_map) o_rgba[-msk] = np.nan # apply the mask again, to be sure if not self._underlay is None: o_msk = -np.isnan(np.sum(o_rgba, 2)) u_rgba = self._underlay u_msk = np.logical_and(-o_msk, msk) o_rgba[u_msk] = u_rgba[u_msk] return o_rgba
def __call__(self, data): ''' Parameters ---------- data: np.ndarray Surface data to be plotted. Should have the same number of data points as the surface Returns ------- rgba: np.ndarray Bitmap with RGBA values that can be plotted. ''' self._pre_setup() x, y, msk, xi, yi = self._grid_def olay = griddata(x, y, data, xi, yi) olay[-msk] = np.nan o_rgba = flat_surface_data2rgba(olay, self._range_ , self._threshold, self._color_map) o_rgba[-msk] = np.nan # apply the mask again, to be sure if self._underlay is not None: o_msk = -np.isnan(np.sum(o_rgba, 2)) u_rgba = self._underlay u_msk = np.logical_and(-o_msk, msk) o_rgba[u_msk] = u_rgba[u_msk] return o_rgba
def _set_underlay_from_curvature(self): if self._curvature is None: raise ValueError("Curvature is not set") if self._grid_def is None: self._set_grid_def() x, y, msk, xi, yi = self._grid_def ulay = griddata(x, y, self._curvature, xi, yi, interp='linear') ulay[-msk] = np.nan rgba = flat_surface_curvature2rgba(ulay) self.set_underlay(rgba)
def __call__(self, data): ''' Parameters ---------- data: np.ndarray Surface data to be plotted. Should have the same number of data points as the surface Returns ------- rgba: np.ndarray Bitmap with RGBA values that can be plotted. ''' self._pre_setup() expected_shape = (self._surface.nvertices,) if data.shape != expected_shape: raise ValueError('data shape was expected to be %s based on ' 'the number of nodes of the surface, ' 'found %s' % ( expected_shape, data.shape)) x, y, msk, xi, yi = self._grid_def olay = griddata(x, y, data, xi, yi, interp='linear') nan_msk = np.logical_not(msk) olay[nan_msk] = np.nan o_rgba = flat_surface_data2rgba(olay, self._range_, self._threshold, self._color_map) o_rgba[nan_msk] = np.nan # apply the mask again, to be sure if self._underlay is not None: o_msk = -np.isnan(np.sum(o_rgba, 2)) u_rgba = self._underlay u_msk = np.logical_and(np.logical_not(o_msk), msk) o_rgba[u_msk] = u_rgba[u_msk] return o_rgba
def __call__(self, data): ''' Parameters ---------- data: np.ndarray Surface data to be plotted. Should have the same number of data points as the surface Returns ------- rgba: np.ndarray Bitmap with RGBA values that can be plotted. ''' self._pre_setup() expected_shape = (self._surface.nvertices, ) if data.shape != expected_shape: raise ValueError('data shape was expected to be %s based on ' 'the number of nodes of the surface, ' 'found %s' % (expected_shape, data.shape)) x, y, msk, xi, yi = self._grid_def olay = griddata(x, y, data, xi, yi, interp='linear') nan_msk = np.logical_not(msk) olay[nan_msk] = np.nan o_rgba = flat_surface_data2rgba(olay, self._range_, self._threshold, self._color_map) o_rgba[nan_msk] = np.nan # apply the mask again, to be sure if self._underlay is not None: o_msk = -np.isnan(np.sum(o_rgba, 2)) u_rgba = self._underlay u_msk = np.logical_and(np.logical_not(o_msk), msk) o_rgba[u_msk] = u_rgba[u_msk] return o_rgba
def plot_head_topography(topography, sensorlocations, plotsensors=False, resolution=51, masked=True, plothead=True, plothead_kwargs=None, **kwargs): """Plot distribution to a head surface, derived from some sensor locations. The sensor locations are first projected onto the best fitting sphere and finally projected onto a circle (by simply ignoring the z-axis). Parameters ---------- topography : array A vector of some values corresponding to each sensor. sensorlocations : (nsensors x 3) array 3D coordinates of each sensor. The order of the sensors has to match with the `topography` vector. plotsensors : bool If True, sensor will be plotted on their projected coordinates. No sensor are shown otherwise. plothead : bool If True, a head outline is plotted. plothead_kwargs : dict Additional keyword arguments passed to `plot_head_outline()`. resolution : int Number of surface samples along both x and y-axis. masked : bool If True, all surface sample extending to head outline will be masked. **kwargs All additional arguments will be passed to `pylab.imshow()`. Returns ------- (map, head, sensors) The corresponding matplotlib objects are returned if plotted, ie. if plothead is set to `False`, `head` will be `None`. map The colormap that makes the actual plot, a matplotlib.image.AxesImage instance. head What is returned by `plot_head_outline()`. sensors The dots marking the electrodes, a matplotlib.lines.Line2d instance. """ # give sane defaults if plothead_kwargs is None: plothead_kwargs = {} # error function to fit the sensor locations to a sphere def err(params): r, cx, cy, cz = params return (sensorlocations[:, 0] - cx) ** 2 \ + (sensorlocations[:, 1] - cy) ** 2 \ + (sensorlocations[:, 2] - cz) ** 2 \ - r ** 2 # initial guess of sphere parameters (radius and center) params = (1, 0, 0, 0) # do fit (r, cx, cy, cz), stuff = leastsq(err, params) # size of each square ssh = float(r) / resolution # half-size ss = ssh * 2.0 # full-size # Generate a grid and interpolate using the griddata module x = np.arange(cx - r, cx + r, ss) + ssh y = np.arange(cy - r, cy + r, ss) + ssh x, y = pl.meshgrid(x, y) # project the sensor locations onto the sphere sphere_center = np.array((cx, cy, cz)) sproj = sensorlocations - sphere_center sproj = r * sproj / np.c_[np.sqrt(np.sum(sproj**2, axis=1))] sproj += sphere_center # fit topology onto xy projection of sphere topo = griddata(sproj[:, 0], sproj[:, 1], np.ravel(np.array(topography)), x, y, interp='nn' if externals.versions['matplotlib'] < '1.4.0' else 'linear') # mask values outside the head if masked: notinhead = np.greater_equal((x - cx)**2 + (y - cy)**2, (1.0 * r)**2) topo = ma.masked_where(notinhead, topo) # show surface map = pl.imshow(topo, origin="lower", extent=(-r, r, -r, r), **kwargs) pl.axis('off') if plothead: # plot scaled head outline head = plot_head_outline(scale=r, shift=(cx / 2.0, cy / 2.0), **plothead_kwargs) else: head = None if plotsensors: # plot projected sensor locations # reorder sensors so the ones below plotted first # TODO: please fix with more elegant solution zenum = [x[::-1] for x in enumerate(sproj[:, 2].tolist())] zenum.sort() indx = [x[1] for x in zenum] sensors = pl.plot(sproj[indx, 0] - cx / 2.0, sproj[indx, 1] - cy / 2.0, 'wo') else: sensors = None return map, head, sensors
def plot_head_topography(topography, sensorlocations, plotsensors=False, resolution=51, masked=True, plothead=True, plothead_kwargs=None, **kwargs): """Plot distribution to a head surface, derived from some sensor locations. The sensor locations are first projected onto the best fitting sphere and finally projected onto a circle (by simply ignoring the z-axis). Parameters ---------- topography : array A vector of some values corresponding to each sensor. sensorlocations : (nsensors x 3) array 3D coordinates of each sensor. The order of the sensors has to match with the `topography` vector. plotsensors : bool If True, sensor will be plotted on their projected coordinates. No sensor are shown otherwise. plothead : bool If True, a head outline is plotted. plothead_kwargs : dict Additional keyword arguments passed to `plot_head_outline()`. resolution : int Number of surface samples along both x and y-axis. masked : bool If True, all surface sample extending to head outline will be masked. **kwargs All additional arguments will be passed to `pylab.imshow()`. Returns ------- (map, head, sensors) The corresponding matplotlib objects are returned if plotted, ie. if plothead is set to `False`, `head` will be `None`. map The colormap that makes the actual plot, a matplotlib.image.AxesImage instance. head What is returned by `plot_head_outline()`. sensors The dots marking the electrodes, a matplotlib.lines.Line2d instance. """ # give sane defaults if plothead_kwargs is None: plothead_kwargs = {} # error function to fit the sensor locations to a sphere def err(params): r, cx, cy, cz = params return (sensorlocations[:, 0] - cx) ** 2 \ + (sensorlocations[:, 1] - cy) ** 2 \ + (sensorlocations[:, 2] - cz) ** 2 \ - r ** 2 # initial guess of sphere parameters (radius and center) params = (1, 0, 0, 0) # do fit (r, cx, cy, cz), stuff = leastsq(err, params) # size of each square ssh = float(r) / resolution # half-size ss = ssh * 2.0 # full-size # Generate a grid and interpolate using the griddata module x = np.arange(cx - r, cx + r, ss) + ssh y = np.arange(cy - r, cy + r, ss) + ssh x, y = pl.meshgrid(x, y) # project the sensor locations onto the sphere sphere_center = np.array((cx, cy, cz)) sproj = sensorlocations - sphere_center sproj = r * sproj / np.c_[np.sqrt(np.sum(sproj ** 2, axis=1))] sproj += sphere_center # fit topology onto xy projection of sphere topo = griddata(sproj[:, 0], sproj[:, 1], np.ravel(np.array(topography)), x, y, interp='nn' if externals.versions['matplotlib'] < '1.4.0' else 'linear') # mask values outside the head if masked: notinhead = np.greater_equal((x - cx) ** 2 + (y - cy) ** 2, (1.0 * r) ** 2) topo = ma.masked_where(notinhead, topo) # show surface map = pl.imshow(topo, origin="lower", extent=(-r, r, -r, r), **kwargs) pl.axis('off') if plothead: # plot scaled head outline head = plot_head_outline(scale=r, shift=(cx/2.0, cy/2.0), **plothead_kwargs) else: head = None if plotsensors: # plot projected sensor locations # reorder sensors so the ones below plotted first # TODO: please fix with more elegant solution zenum = [x[::-1] for x in enumerate(sproj[:, 2].tolist())] zenum.sort() indx = [ x[1] for x in zenum ] sensors = pl.plot(sproj[indx, 0] - cx/2.0, sproj[indx, 1] - cy/2.0, 'wo') else: sensors = None return map, head, sensors