def test_simpleNormalizer(self): """Verify that the factory sets min and max from a dataset.""" out = normalizerFactory(self.data, None, False, None, None) self._testNormalizer(out)
def test_normSubclass(self): """Verify that passing a subclass of Normalize is allowed.""" emin, emax = 5, 100 norm = LogNorm(vmin=emin, vmax=emax) out = normalizerFactory(self.data, norm, False, None, None) self.assertIs(norm, out)
def test_passNormaliser(self): """Verify that passing an instance of Normalize is allowed.""" emin, emax = 5, 100 norm = Normalize(vmin=emin, vmax=emax) out = normalizerFactory(self.data, norm, False, None, None) self.assertIs(norm, out)
def test_positiveLogNorm(self): """Verify the logScaling for a positive dataset.""" self.data[self.data <= 0] = 1 out = normalizerFactory(self.data, None, True, None, None) self._testNormalizer(out)
def cartMeshPlot(data, xticks=None, yticks=None, ax=None, cmap=None, logColor=False, normalizer=None, cbarLabel=None, **kwargs): """ Create a cartesian mesh plot of the data Parameters ---------- data: numpy.array 2D array of data to be plotted xticks: iterable or None yticks: iterable or None Values corresponding to lower x/y boundary of meshes. If not given, treat this as a matrix plot like :func:`matplotlib.pyplot.imshow`. If given, they should contain one more item than number of elements in their dimension to give dimensions for all meshes. {ax} {cmap} logColor: bool If true, apply a logarithmic coloring normalizer: callable or :py:class:`matplotlib.colors.Normalize` Custom normalizer for this plot. If an instance of :py:class:`matplotlib.colors.Normalize`, normalizer: callable or :py:class:`matplotlib.colors.Normalize` Custom normalizer for this plot. If an instance of :py:class:`matplotlib.colors.Normalize`, use directly. Otherwise, assume a callable object and call as ``norm = normalizer(data, xticks, yticks)`` cbarLabel: None or str Label to apply to colorbar {kwargs} :py:func:`matplotlib.pyplot.pcolormesh` or :func:`matplotlib.pyplot.imshow` if ``xticks`` and ``yticks`` are ``None`` Returns ------- {rax} Raises ------ ValueError: If ``logColor`` and data contains negative quantities TypeError: If only one of ``xticks`` or ``yticks`` is ``None``. Examples -------- .. plot:: :include-source: >>> from serpentTools.plot import cartMeshPlot >>> from numpy import arange >>> data = arange(100).reshape(10, 10) >>> x = y = arange(11) >>> cartMeshPlot(data, x, y, cbarLabel='Demo') .. plot:: :include-source: >>> from serpentTools.plot import cartMeshPlot >>> from numpy import eye >>> data = eye(10) >>> for indx in range(10): ... data[indx] *= indx >>> cartMeshPlot(data, logColor=True) All values less than or equal to zero are excluded from the color normalization. The ``logColor`` argument works well for plotting sparse matrices, as the zero-valued indices can be identified without obscuring the trends presented in the non-zero data. See Also -------- * :func:`matplotlib.pyplot.pcolormesh` * :func:`matplotlib.pyplot.imshow` * :class:`matplotlib.colors.Normalize` """ assert len(data.shape) == 2, 'Mesh plot requires 2D data, ' \ 'not {}'.format(data.shape) if ((xticks is None and yticks is not None) or (xticks is None and yticks is not None)): raise TypeError("Both X and Y must be None, or not None.") if kwargs.get('logScale', None) is not None: warning("Passing logScale is no longer supported. " "Use logColor instead.") logColor = bool(logColor or kwargs['logScale']) if logColor and data.min() < 0: raise ValueError("Will not apply log normalization to data with " "negative elements") norm = normalizerFactory(data, normalizer, logColor, xticks, yticks) # make the plot ax = ax or pyplot.gca() if xticks is None: mappable = ax.imshow(data, cmap=cmap, norm=norm) else: X, Y = meshgrid(xticks, yticks) mappable = ax.pcolormesh(X, Y, data, cmap=cmap, norm=norm, **kwargs) addColorbar(ax, mappable, norm, cbarLabel) return ax
def hexPlot(self, what='tallies', fixed=None, ax=None, cmap=None, logColor=False, xlabel=None, ylabel=None, logx=False, logy=False, loglog=False, title=None, normalizer=None, cbarLabel=None, borderpad=2.5, **kwargs): """ Create and return a hexagonal mesh plot. Parameters ---------- what: {'tallies', 'errors', 'scores'} Quantity to plot fixed: None or dict Dictionary of slicing arguments to pass to :meth:`slice` {ax} {cmap} {logColor} {xlabel} {ylabel} {logx} {logy} {loglog} {title} borderpad: int or float Percentage of total plot to apply as a border. A value of zero means that the extreme edges of the hexagons will touch the x and y axis. {kwargs} :class:`matplotlib.patches.RegularPolygon` Raises ------ AttributeError If :attr:`pitch` and :attr:`hexType` are not set. """ borderpad = max(0, float(borderpad)) if fixed and ('xcoord' in fixed or 'ycoord' in fixed): raise KeyError("Refusing to restrict along one of the hexagonal " "dimensions {x/y}coord") for attr in {'pitch', 'hexType'}: if getattr(self, attr) is None: raise AttributeError("{} is not set.".format(attr)) for key in {'color', 'fc', 'facecolor', 'orientation'}: checkClearKwargs(key, 'hexPlot', **kwargs) ec = kwargs.get('ec', None) or kwargs.get('edgecolor', None) if ec is None: ec = 'k' kwargs['ec'] = kwargs['edgecolor'] = ec if 'figure' in kwargs and kwargs['figure'] is not None: fig = kwargs['figure'] if not isinstance(fig, Figure): raise TypeError( "Expected 'figure' to be of type Figure, is {}".format( type(fig))) if len(fig.axes) != 1 and not ax: raise TypeError("Don't know where to place the figure since" "'figure' argument has multiple axes.") if ax and fig.axes and ax not in fig.axes: raise IndexError("Passed argument for 'figure' and 'ax', " "but ax is not attached to figure.") ax = ax or (fig.axes[0] if fig.axes else axes()) alpha = kwargs.get('alpha', None) ny = len(self.indexes['ycoord']) nx = len(self.indexes['xcoord']) data = self.slice(fixed, what) if data.shape != (ny, nx): raise IndexError("Constrained data does not agree with hexagonal " "grid structure. Coordinate grid: {}. " "Constrained shape: {}".format((ny, nx), data.shape)) nItems = ny * nx patches = empty(nItems, dtype=object) values = empty(nItems) coords = self.grids['COORD'] ax = ax or axes() pos = 0 xmax, ymax = [ -inf, ] * 2 xmin, ymin = [ inf, ] * 2 radius = self.pitch / sqrt(3) for xy, val in zip(coords, data.flat): values[pos] = val h = RegularPolygon(xy, 6, radius, self.__hexRot, **kwargs) verts = h.get_verts() vmins = verts.min(0) vmaxs = verts.max(0) xmax = max(xmax, vmaxs[0]) xmin = min(xmin, vmins[0]) ymax = max(ymax, vmaxs[1]) ymin = min(ymin, vmins[1]) patches[pos] = h pos += 1 normalizer = normalizerFactory(values, normalizer, logColor, coords[:, 0], coords[:, 1]) pc = PatchCollection(patches, cmap=cmap, alpha=alpha) pc.set_array(values) pc.set_norm(normalizer) ax.add_collection(pc) addColorbar(ax, pc, None, cbarLabel) formatPlot( ax, loglog=loglog, logx=logx, logy=logy, xlabel=xlabel or "X [cm]", ylabel=ylabel or "Y [cm]", title=title, ) setAx_xlims(ax, xmin, xmax, pad=borderpad) setAx_ylims(ax, ymin, ymax, pad=borderpad) return ax