示例#1
0
class Matplotlib2DContourViewer(AbstractMatplotlib2DViewer):
    """Displays a contour plot of a 2D `CellVariable` object.

    The `Matplotlib2DContourViewer` plots a 2D `CellVariable` using Matplotlib_.

    .. _Matplotlib: http://matplotlib.sourceforge.net/
    """

    __doc__ += AbstractMatplotlib2DViewer._test2D(viewer="Matplotlib2DContourViewer")


    def __init__(self, vars, title=None, limits={}, cmap=None, colorbar='vertical', axes=None, number=10, levels=None, figaspect='auto', **kwlimits):
        """Creates a `Matplotlib2DContourViewer`.

        Parameters
        ----------
        vars : ~fipy.variables.cellVariable.CellVariable
            `Variable` to display
        title : str, optional
            displayed at the top of the `Viewer` window
        limits : dict, optional
            a (deprecated) alternative to limit keyword arguments
        float xmin, xmax, ymin, ymax, datamin, datamax : float, optional
            displayed range of data. Any limit set to
            a (default) value of `None` will autoscale.
        cmap : ~matplotlib.colors.Colormap, optional
            the Colormap.
            Defaults to `matplotlib.cm.jet`
        colorbar : bool, optional
            plot a color bar in specified orientation if not `None`
        axes : ~matplotlib.axes.Axes, optional
            if not `None`, `vars` will be plotted into this Matplotlib `Axes` object
        number : int, optional
            contour `number` automatically-chosen levels
        levels : :obj:`list` of :obj:`float`, optional
            A list of numbers indicating the level
            curves to draw; e.g. to draw just the zero contour pass
            ``levels=[0]``
        figaspect : float
            desired aspect ratio of figure. If arg is a number, use that aspect
            ratio. If arg is `auto`, the aspect ratio will be determined from
            the Variable's mesh.

        """
        kwlimits.update(limits)
        AbstractMatplotlib2DViewer.__init__(self, vars=vars, title=title,
                                            cmap=cmap, colorbar=colorbar, axes=axes,
                                            figaspect=figaspect,
                                            **kwlimits)
        self.number = number
        self.levels = levels

        self._plot()

    def _getSuitableVars(self, vars):
        from fipy.meshes.mesh2D import Mesh2D
        from fipy.variables.cellVariable import CellVariable
        vars = [var for var in AbstractMatplotlib2DViewer._getSuitableVars(self, vars) \
          if ((isinstance(var.mesh, Mesh2D) and isinstance(var, CellVariable))
              and var.rank == 0)]
        if len(vars) == 0:
            from fipy.viewers import MeshDimensionError
            raise MeshDimensionError("Matplotlib2DViewer can only display a rank-0, 2D CellVariable")
        # this viewer can only display one variable
        return [vars[0]]

    def _plot(self):
##         plt.clf()

##         ## Added garbage collection since matplotlib objects seem to hang
##         ## around and accumulate.
##         import gc
##         gc.collect()

        mesh = self.vars[0].mesh
        x, y = mesh.cellCenters
        z = self.vars[0].value

        xmin, ymin = mesh.extents['min']
        xmax, ymax = mesh.extents['max']

        from matplotlib.mlab import griddata

        xi = numerix.linspace(xmin, xmax, 1000)
        yi = numerix.linspace(ymin, ymax, 1000)
        # grid the data.
        zi = griddata(x, y, z, xi, yi, interp='linear')

        if hasattr(self, "_contourSet"):
            for collection in self._contourSet.collections:
                try:
                    ix = self.axes.collections.index(collection)
                except ValueError as e:
                    ix = None

                if ix is not None:
                    del self.axes.collections[ix]

        zmin, zmax = self._autoscale(vars=self.vars,
                                     datamin=self._getLimit(('datamin', 'zmin')),
                                     datamax=self._getLimit(('datamax', 'zmax')))

        self.norm.vmin = zmin
        self.norm.vmax = zmax

        if self.levels is not None:
            levels = self.levels
        else:
            levels = numerix.arange(self.number + 1) * (zmax - zmin) / self.number + zmin


        self._contourSet = self.axes.contour(xi, yi, zi, levels=levels, cmap=self.cmap)

        self.axes.set_xlim(xmin=self._getLimit('xmin'),
                           xmax=self._getLimit('xmax'))

        self.axes.set_ylim(ymin=self._getLimit('ymin'),
                           ymax=self._getLimit('ymax'))

        if self.colorbar is not None:
            self.colorbar.plot()
示例#2
0
class Matplotlib2DGridViewer(AbstractMatplotlib2DViewer):
    """
    Displays an image plot of a 2D `CellVariable` object using Matplotlib_.

    .. _Matplotlib: http://matplotlib.sourceforge.net/
    """

    __doc__ += AbstractMatplotlib2DViewer._test2D(
        viewer="Matplotlib2DGridViewer")

    def __init__(self,
                 vars,
                 title=None,
                 limits={},
                 cmap=None,
                 colorbar='vertical',
                 axes=None,
                 figaspect='auto',
                 **kwlimits):
        """
        Creates a `Matplotlib2DGridViewer`.
        
        :Parameters:
          vars
            A `CellVariable` object.
          title
            displayed at the top of the `Viewer` window
          limits : dict
            a (deprecated) alternative to limit keyword arguments
          cmap
            The colormap. Defaults to `matplotlib.cm.jet`
          xmin, xmax, ymin, ymax, datamin, datamax
            displayed range of data. Any limit set to 
            a (default) value of `None` will autoscale.
          colorbar
            plot a colorbar in specified orientation if not `None`
          axes
            if not `None`, `vars` will be plotted into this Matplotlib `Axes` object
          figaspect
            desired aspect ratio of figure. If arg is a number, use that aspect
            ratio. If arg is 'auto', the aspect ratio will be determined from
            the Variable's mesh.
        """
        kwlimits.update(limits)
        AbstractMatplotlib2DViewer.__init__(self,
                                            vars=vars,
                                            title=title,
                                            cmap=cmap,
                                            colorbar=colorbar,
                                            axes=axes,
                                            figaspect=figaspect,
                                            **kwlimits)

        self.image = self.axes.imshow(self._data,
                                      extent=(self._getLimit('xmin'),
                                              self._getLimit('xmax'),
                                              self._getLimit('ymin'),
                                              self._getLimit('ymax')),
                                      vmin=0,
                                      vmax=1,
                                      cmap=self.cmap)

        if title is None:
            self.axes.set_title(self.vars[0].name)

    def _getLimit(self, key, default=None):
        limit = AbstractMatplotlib2DViewer._getLimit(self,
                                                     key,
                                                     default=default)
        if limit is None:
            X, Y = self.vars[0].mesh.faceCenters
            if 'xmin' in key:
                limit = float(min(X))
            elif 'ymin' in key:
                limit = float(min(Y))
            if 'xmax' in key:
                limit = float(max(X))
            elif 'ymax' in key:
                limit = float(max(Y))
        return limit

    def _getSuitableVars(self, vars):
        from fipy.meshes.uniformGrid2D import UniformGrid2D
        from fipy.variables.cellVariable import CellVariable
        vars = [var for var in AbstractMatplotlib2DViewer._getSuitableVars(self, vars) \
          if (isinstance(var.mesh, UniformGrid2D) and isinstance(var, CellVariable)
              and var.rank == 0)]
        if len(vars) == 0:
            from fipy.viewers import MeshDimensionError
            raise MeshDimensionError, "Matplotlib2DGridViewer can only display a rank-0 CellVariable with a UniformGrid2D mesh"
        # this viewer can only display one variable
        return [vars[0]]

    @getsetDeprecated
    def _getData(self):
        return self._data

    @property
    def _data(self):
        from fipy.tools.numerix import array, reshape
        return reshape(array(self.vars[0]),
                       self.vars[0].mesh.shape[::-1])[::-1]

    def _plot(self):
        self.norm.vmin = self._getLimit(('datamin', 'zmin'))
        self.norm.vmax = self._getLimit(('datamax', 'zmax'))

        self.image.set_data(self.norm(self._data))

        if self.colorbar is not None:
            self.colorbar.plot()
class Matplotlib2DGridContourViewer(AbstractMatplotlib2DViewer):
    """Displays a contour plot of a 2D `CellVariable` object.    

    The `Matplotlib2DGridContourViewer` plots a 2D `CellVariable` using Matplotlib_.

    .. _Matplotlib: http://matplotlib.sourceforge.net/
    """

    __doc__ += AbstractMatplotlib2DViewer._test2D(
        viewer="Matplotlib2DGridContourViewer")

    def __init__(self,
                 vars,
                 title=None,
                 limits={},
                 cmap=None,
                 colorbar='vertical',
                 axes=None,
                 figaspect='auto',
                 **kwlimits):
        """Creates a `Matplotlib2DViewer`.
        
        :Parameters:
          vars
            a `CellVariable` object.
          title
            displayed at the top of the `Viewer` window
          limits : dict
            a (deprecated) alternative to limit keyword arguments
          xmin, xmax, ymin, ymax, datamin, datamax
            displayed range of data. Any limit set to 
            a (default) value of `None` will autoscale.
          cmap
            the colormap. Defaults to `matplotlib.cm.jet`
          colorbar
            plot a colorbar in specified orientation if not `None`
          axes
            if not `None`, `vars` will be plotted into this Matplotlib `Axes` object
          figaspect
            desired aspect ratio of figure. If arg is a number, use that aspect
            ratio. If arg is 'auto', the aspect ratio will be determined from
            the Variable's mesh.
        """
        kwlimits.update(limits)
        AbstractMatplotlib2DViewer.__init__(self,
                                            vars=vars,
                                            title=title,
                                            cmap=cmap,
                                            colorbar=colorbar,
                                            axes=axes,
                                            figaspect=figaspect,
                                            **kwlimits)

        self._plot()

    def _getSuitableVars(self, vars):
        from fipy.meshes.grid2D import Grid2D
        from fipy.meshes.uniformGrid2D import UniformGrid2D
        from fipy.variables.cellVariable import CellVariable
        vars = [var for var in AbstractMatplotlib2DViewer._getSuitableVars(self, vars) \
          if ((isinstance(var.mesh, Grid2D)
               or isinstance(var.mesh, UniformGrid2D))
              and isinstance(var, CellVariable))]
        if len(vars) == 0:
            from fipy.viewers import MeshDimensionError
            raise MeshDimensionError, "The mesh must be a Grid2D instance"
        # this viewer can only display one variable
        return [vars[0]]

    def _plot(self):
        ##         pylab.clf()

        ##         ## Added garbage collection since matplotlib objects seem to hang
        ##         ## around and accumulate.
        ##         import gc
        ##         gc.collect()

        mesh = self.vars[0].mesh
        shape = mesh.shape
        X, Y = mesh.cellCenters
        Z = self.vars[0].value
        X, Y, Z = [v.reshape(shape, order="FORTRAN") for v in (X, Y, Z)]

        zmin, zmax = self._autoscale(vars=self.vars,
                                     datamin=self._getLimit(
                                         ('datamin', 'zmin')),
                                     datamax=self._getLimit(
                                         ('datamax', 'zmax')))

        self.norm.vmin = zmin
        self.norm.vmax = zmax

        numberOfContours = 10
        smallNumber = 1e-7
        diff = zmax - zmin

        if diff < smallNumber:
            V = numerix.arange(numberOfContours +
                               1) * smallNumber / numberOfContours + zmin
        else:
            V = numerix.arange(numberOfContours +
                               1) * diff / numberOfContours + zmin

        self.axes.contourf(X, Y, Z, V, cmap=self.cmap)

        self.axes.set_xlim(xmin=self._getLimit('xmin'),
                           xmax=self._getLimit('xmax'))

        self.axes.set_ylim(ymin=self._getLimit('ymin'),
                           ymax=self._getLimit('ymax'))

        if self.colorbar is not None:
            self.colorbar.plot()