Plot a two-dimensional histogram.

        The user needs to supply the histogram.  This method only plots
        the results.  You can use NumPy's histogram2d function.

        :param counts: array containing the count values.
        :param x_edges: array containing the x-axis bin edges.
        :param y_edges: array containing the y-axis bin edges.
        :param type: the type of histogram.  Allowed values are 'bw' for
            filled squares with shades from black (minimum value) to white
            (maximum value), 'reverse_bw' for filled squares with the
            shades reversed and, 'color' for color mapped histogram
            which uses the 'coolwarm' colormap by default, but can be
            overwritten with the colormap keyword, and 'area' for
            squares where the area of the square is a measure of the
            count in the bin.
        :param style: optional TikZ styles to apply (e.g. 'red').  Note
            that many color styles are overridden by the 'bw' and
            'reverse_bw' types.
        :param bitmap: Export the histogram as an image for better
            performance. This does expect all bins along an axis to have
            equal width. Can not be used in combination with type 'area'.
        :param colormap: A colormap for the 'color' type, as expected by
            the `Image.putpalette` method.

        Example::

            >>> x = np.random.uniform(low=1, high=1000, size=2000)
            >>> y = np.random.uniform(low=0, high=50, size=2000)
            >>> plot = artist.Plot()
            >>> n, xbins, ybins = np.histogram2d(x, y)
            >>> plot.histogram2d(n, xbins, ybins)

        When you desire logarithmic axes and bitmap is set to True special
        care has to be taken with the binning. This is because the bins along
        an axis have to be equal size in the final result. So use logarithmic
        binning for logarithmic axes.

        Example::

            >>> plot = artist.Plot(axis='semilogx')
            >>> xbins = np.logspace(0, 3, 20)
            >>> ybins = np.linspace(-5, 10, 10)
            >>> n, xbins, ybins = np.histogram2d(x, y, bins=[xbins, ybins])
            >>> plot.histogram2d(n, xbins, ybins, bitmap=True)

        For each bin where the counts are nan the value will be set to the
        minimum value (i.e. `np.nanmin(counts)`).

def histogram2d(self, counts, x_edges, y_edges, type='bw', style=None,
                    bitmap=False, colormap=None):
        """Plot a two-dimensional histogram.

        The user needs to supply the histogram.  This method only plots
        the results.  You can use NumPy's histogram2d function.

        :param counts: array containing the count values.
        :param x_edges: array containing the x-axis bin edges.
        :param y_edges: array containing the y-axis bin edges.
        :param type: the type of histogram.  Allowed values are 'bw' for
            filled squares with shades from black (minimum value) to white
            (maximum value), 'reverse_bw' for filled squares with the
            shades reversed and, 'color' for color mapped histogram
            which uses the 'coolwarm' colormap by default, but can be
            overwritten with the colormap keyword, and 'area' for
            squares where the area of the square is a measure of the
            count in the bin.
        :param style: optional TikZ styles to apply (e.g. 'red').  Note
            that many color styles are overridden by the 'bw' and
            'reverse_bw' types.
        :param bitmap: Export the histogram as an image for better
            performance. This does expect all bins along an axis to have
            equal width. Can not be used in combination with type 'area'.
        :param colormap: A colormap for the 'color' type, as expected by
            the `Image.putpalette` method.

        Example::

            >>> x = np.random.uniform(low=1, high=1000, size=2000)
            >>> y = np.random.uniform(low=0, high=50, size=2000)
            >>> plot = artist.Plot()
            >>> n, xbins, ybins = np.histogram2d(x, y)
            >>> plot.histogram2d(n, xbins, ybins)

        When you desire logarithmic axes and bitmap is set to True special
        care has to be taken with the binning. This is because the bins along
        an axis have to be equal size in the final result. So use logarithmic
        binning for logarithmic axes.

        Example::

            >>> plot = artist.Plot(axis='semilogx')
            >>> xbins = np.logspace(0, 3, 20)
            >>> ybins = np.linspace(-5, 10, 10)
            >>> n, xbins, ybins = np.histogram2d(x, y, bins=[xbins, ybins])
            >>> plot.histogram2d(n, xbins, ybins, bitmap=True)

        For each bin where the counts are nan the value will be set to the
        minimum value (i.e. `np.nanmin(counts)`).

        """
        if counts.shape != (len(x_edges) - 1, len(y_edges) - 1):
            raise RuntimeError(
                'The length of x_edges and y_edges should match counts')

        if type not in ['bw', 'reverse_bw', 'area', 'color']:
            raise RuntimeError('Histogram type %s not supported' % type)
        if type == 'area' and bitmap:
            raise RuntimeError('Histogram type %s not supported for bitmap '
                               'output' % type)
        if type == 'color' and not bitmap:
            raise RuntimeError('Histogram type %s not supported for '
                               'non-bitmapped output' % type)

        if bitmap:
            normed_counts = self._normalize_histogram2d(counts, type)
            img = Image.fromarray(np.flipud(normed_counts.T))
            if type == 'color':
                if colormap == 'viridis':
                    img.putpalette(VIRIDIS)
                elif colormap in [None, 'coolwarm']:
                    img.putpalette(COOLWARM)
                else:
                    img.putpalette(colormap)
            self.bitmap_list.append({'image': img,
                                     'xmin': min(x_edges),
                                     'xmax': max(x_edges),
                                     'ymin': min(y_edges),
                                     'ymax': max(y_edges)})
        else:
            x_centers = (x_edges[:-1] + x_edges[1:]) / 2
            y_centers = (y_edges[:-1] + y_edges[1:]) / 2

            self.histogram2d_list.append({'x_edges': x_edges,
                                          'y_edges': y_edges,
                                          'x_centers': x_centers,
                                          'y_centers': y_centers,
                                          'counts': counts,
                                          'max': np.nanmax(counts),
                                          'min': np.nanmin(counts),
                                          'type': type,
                                          'style': style})
        # Set limits unless lower/higher limits are already set.
        xmin = min(x for x in (min(x_edges), self.limits['xmin'])
                   if x is not None)
        ymin = min(y for y in (min(y_edges), self.limits['ymin'])
                   if y is not None)
        xmax = max(x for x in (max(x_edges), self.limits['xmax'])
                   if x is not None)
        ymax = max(y for y in (max(y_edges), self.limits['ymax'])
                   if y is not None)
        self.set_xlimits(xmin, xmax)
        self.set_ylimits(ymin, ymax)
        if type != 'area':
            self.set_mlimits(np.nanmin(counts), np.nanmax(counts))
        if type == 'bw':
            self.set_colormap('blackwhite')
        elif type == 'reverse_bw':
            self.set_colormap('whiteblack')
        elif type == 'color':
            if colormap == 'viridis':
                self.set_colormap('viridis')
            elif colormap in [None, 'coolwarm']:
                self.set_colormap('coolwarm')