PKQL+B--plotchecker/__init__.py""" A set of utilities for testing matplotlib plots in an object-oriented manner. """ from ._version import version_info, __version__ from .base import PlotChecker, InvalidPlotError from .lineplot import LinePlotChecker from .scatterplot import ScatterPlotChecker from .barplot import BarPlotCheckerPKQLRQ5HHplotchecker/_version.pyversion_info = (0, 2, 0) __version__ = '.'.join(map(str, version_info)) PKQLQ7Q7plotchecker/barplot.pyimport numpy as np from .base import PlotChecker, InvalidPlotError class BarPlotChecker(PlotChecker): """A plot checker for bar plots. Parameters ---------- axis : ``matplotlib.axes.Axes`` object A set of matplotlib axes (e.g. obtained through ``plt.gca()``) """ def __init__(self, axis): """Initialize the bar plot checker.""" super(BarPlotChecker, self).__init__(axis) self._patches = np.array(self.axis.patches) self._patches = self._patches[np.argsort([p.get_x() for p in self._patches])] if len(self._patches) == 0: raise InvalidPlotError("no data found") def _parse_expected_attr(self, attr_name, attr_val): """Ensure that the given expected attribute values are in the right shape.""" if attr_name in ('colors', 'edgecolors'): # if it's a color, first check if it's just a single color -- if it's # not a single color, this command will throw an error and we can try # iterating over the multiple colors that were given try: attr_val = np.array([self._color2rgb(attr_val)]) except (ValueError, TypeError): attr_val = np.array([self._color2rgb(x) for x in attr_val]) elif not hasattr(attr_val, '__iter__'): # if it's not a color, then just make sure we have an array attr_val = np.array([attr_val]) # tile the given values if we've only been given one, so it's the same # shape as the data if len(attr_val) == 1: attr_val = self._tile_or_trim(self.centers, attr_val) return attr_val def assert_num_bars(self, num_bars): """Assert that the plot has the given number of bars. Parameters ---------- num_bars : int """ if num_bars != len(self._patches): raise AssertionError( "Plot has incorrect number of bars: {} (expected {})".format( len(self._patches), num_bars)) @property def centers(self): """The centers of the plotted bars.""" return np.array([p.get_x() + (p.get_width() / 2) for p in self._patches]) def assert_centers_equal(self, centers): """Assert that the given centers are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.centers`. Parameters ---------- centers : 1-D array-like The expected centers. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.centers, self._parse_expected_attr("centers", centers)) def assert_centers_allclose(self, centers, **kwargs): """Assert that the given centers are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.centers`. Parameters ---------- centers : 1-D array-like The expected centers. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.centers, self._parse_expected_attr("centers", centers), **kwargs) @property def heights(self): """The heights of the plotted bars.""" return np.array([p.get_height() for p in self._patches]) def assert_heights_equal(self, heights): """Assert that the given heights are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.heights`. Parameters ---------- heights : 1-D array-like The expected heights. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.heights, self._parse_expected_attr("heights", heights)) def assert_heights_allclose(self, heights, **kwargs): """Assert that the given heights are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.heights`. Parameters ---------- heights : 1-D array-like The expected heights. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.heights, self._parse_expected_attr("heights", heights), **kwargs) @property def widths(self): """The widths of the plotted bars.""" return np.array([p.get_width() for p in self._patches]) def assert_widths_equal(self, widths): """Assert that the given widths are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.widths`. Parameters ---------- widths : 1-D array-like The expected widths. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.widths, self._parse_expected_attr("widths", widths)) def assert_widths_allclose(self, widths, **kwargs): """Assert that the given widths are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.widths`. Parameters ---------- widths : 1-D array-like The expected widths. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.widths, self._parse_expected_attr("widths", widths), **kwargs) @property def bottoms(self): """The y-coordinates of the bottoms of the plotted bars.""" return np.array([p.get_y() for p in self._patches]) def assert_bottoms_equal(self, bottoms): """Assert that the given bottoms are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.bottoms`. Parameters ---------- bottoms : 1-D array-like The expected bottoms. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.bottoms, self._parse_expected_attr("bottoms", bottoms)) def assert_bottoms_allclose(self, bottoms, **kwargs): """Assert that the given bottoms are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.bottoms`. Parameters ---------- bottoms : 1-D array-like The expected bottoms. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.bottoms, self._parse_expected_attr("bottoms", bottoms), **kwargs) @property def colors(self): """The colors of the plotted bars.""" return np.array([self._color2rgb(p.get_facecolor()) for p in self._patches]) def assert_colors_equal(self, colors): """Assert that the given colors are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.colors`. Parameters ---------- colors : single color, or list of expected colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ np.testing.assert_equal( self.colors, self._parse_expected_attr("colors", colors)) def assert_colors_allclose(self, colors, **kwargs): """Assert that the given colors are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.colors`. Parameters ---------- colors : single color, or list of expected edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.colors, self._parse_expected_attr("colors", colors), **kwargs) @property def edgecolors(self): """The edge colors of the plotted bars.""" return np.array([self._color2rgb(p.get_edgecolor()) for p in self._patches]) def assert_edgecolors_equal(self, edgecolors): """Assert that the given edgecolors are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.edgecolors`. Parameters ---------- edgecolors : single color, or list of expected edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ np.testing.assert_equal( self.edgecolors, self._parse_expected_attr("edgecolors", edgecolors)) def assert_edgecolors_allclose(self, edgecolors, **kwargs): """Assert that the given edgecolors are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.edgecolors`. Parameters ---------- edgecolors : single color, or list of expected edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.edgecolors, self._parse_expected_attr("edgecolors", edgecolors), **kwargs) @property def alphas(self): """The alpha values of the plotted bars.""" all_alphas = [] for p in self._patches: if p.get_alpha() is None: alpha = self._color2alpha(p.get_facecolor()) else: alpha = p.get_alpha() all_alphas.append(alpha) return np.array(all_alphas) def assert_alphas_equal(self, alphas): """Assert that the given alphas are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.alphas`. Parameters ---------- alphas : 1-D array-like The expected alphas. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.alphas, self._parse_expected_attr("alphas", alphas)) def assert_alphas_allclose(self, alphas, **kwargs): """Assert that the given alphas are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.alphas`. Parameters ---------- alphas : 1-D array-like The expected alphas. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.alphas, self._parse_expected_attr("alphas", alphas), **kwargs) @property def linewidths(self): """The line widths of the plotted bars.""" return np.array([p.get_linewidth() for p in self._patches]) def assert_linewidths_equal(self, linewidths): """Assert that the given linewidths are equivalent to the plotted :attr:`~plotchecker.BarPlotChecker.linewidths`. Parameters ---------- linewidths : 1-D array-like The expected linewidths. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). """ np.testing.assert_equal( self.linewidths, self._parse_expected_attr("linewidths", linewidths)) def assert_linewidths_allclose(self, linewidths, **kwargs): """Assert that the given linewidths are almost equal to the plotted :attr:`~plotchecker.BarPlotChecker.linewidths`. Parameters ---------- linewidths : 1-D array-like The expected linewidths. The number of elements should be equal to the (expected) number of plotted bars, or just a single value (which will then be applied to all bars). kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.linewidths, self._parse_expected_attr("linewidths", linewidths), **kwargs) PKvQLܧ//plotchecker/base.pyfrom __future__ import division import matplotlib import matplotlib.colors import matplotlib.markers import numpy as np import six import warnings try: _named_colors = matplotlib.colors.ColorConverter.colors.copy() for colorname, hexcode in matplotlib.colors.cnames.items(): _named_colors[colorname] = matplotlib.colors.hex2color(hexcode) except: # pragma: no cover warnings.warn("Could not get matplotlib colors, named colors will not be available") _named_colors = {} class InvalidPlotError(Exception): pass class PlotChecker(object): """A generic object to test plots. Parameters ---------- axis : ``matplotlib.axes.Axes`` object A set of matplotlib axes (e.g. obtained through ``plt.gca()``) """ _named_colors = _named_colors def __init__(self, axis): """Initialize the PlotChecker object.""" self.axis = axis @classmethod def _color2rgb(cls, color): """Converts the given color to a 3-tuple RGB color. Parameters ---------- color : Either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. Returns ------- rgb : 3-tuple RGB color """ if isinstance(color, six.string_types): if color in cls._named_colors: return tuple(cls._named_colors[color]) else: return tuple(matplotlib.colors.hex2color(color)) elif hasattr(color, '__iter__') and len(color) == 3: return tuple(float(x) for x in color) elif hasattr(color, '__iter__') and len(color) == 4: return tuple(float(x) for x in color[:3]) else: raise ValueError("Invalid color: {}".format(color)) @classmethod def _color2alpha(cls, color): """Converts the given color to an alpha value. For all cases except RGBA colors, this value will be 1.0. Parameters ---------- color : Either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. Returns ------- alpha : float """ if isinstance(color, six.string_types): return 1.0 elif hasattr(color, '__iter__') and len(color) == 3: return 1.0 elif hasattr(color, '__iter__') and len(color) == 4: return float(color[3]) else: raise ValueError("Invalid color: {}".format(color)) @classmethod def _parse_marker(cls, marker): """Converts the given marker to a consistent marker type. In practice, this is basically just making sure all null markers (``''``, ``'None'``, ``None``) get converted to empty strings. Parameters ---------- marker : string The marker type Returns ------- marker : string """ if marker is None or marker == 'None': return '' return marker @classmethod def _tile_or_trim(cls, x, y): """Tiles or trims the first dimension of ``y`` so that ``x.shape[0]`` == ``y.shape[0]``. Parameters ---------- x : array-like A numpy array with any number of dimensions. y : array-like A numpy array with any number of dimensions. """ xn = x.shape[0] yn = y.shape[0] if xn > yn: numrep = int(np.ceil(xn / yn)) y = np.tile(y, (numrep,) + (1,) * (y.ndim - 1)) yn = y.shape[0] if xn < yn: y = y[:xn] return y @property def title(self): """The title of the matplotlib plot, stripped of whitespace.""" return self.axis.get_title().strip() def assert_title_equal(self, title): """Asserts that the given title is the same as the plotted :attr:`~plotchecker.PlotChecker.title`. Parameters ---------- title : string The expected title """ title = title.strip() if self.title != title: raise AssertionError( "title is incorrect: '{}'' (expected '{}')".format( self.title, title)) def assert_title_exists(self): """Asserts that the plotted :attr:`~plotchecker.PlotChecker.title` is non-empty. """ if self.title == '': raise AssertionError("no title") @property def xlabel(self): """The xlabel of the matplotlib plot, stripped of whitespace.""" return self.axis.get_xlabel().strip() def assert_xlabel_equal(self, xlabel): """Asserts that the given xlabel is the same as the plotted :attr:`~plotchecker.PlotChecker.xlabel`. Parameters ---------- xlabel : string The expected xlabel """ xlabel = xlabel.strip() if self.xlabel != xlabel: raise AssertionError( "xlabel is incorrect: '{}'' (expected '{}')".format( self.xlabel, xlabel)) def assert_xlabel_exists(self): """Asserts that the plotted :attr:`~plotchecker.PlotChecker.xlabel` is non-empty. """ if self.xlabel == '': raise AssertionError("no xlabel") @property def ylabel(self): """The ylabel of the matplotlib plot, stripped of whitespace.""" return self.axis.get_ylabel().strip() def assert_ylabel_equal(self, ylabel): """Asserts that the given ylabel is the same as the plotted :attr:`~plotchecker.PlotChecker.ylabel`. Parameters ---------- ylabel : string The expected ylabel """ ylabel = ylabel.strip() if self.ylabel != ylabel: raise AssertionError( "ylabel is incorrect: '{}'' (expected '{}')".format( self.ylabel, ylabel)) def assert_ylabel_exists(self): """Asserts that the plotted :attr:`~plotchecker.PlotChecker.ylabel` is non-empty. """ if self.ylabel == '': raise AssertionError("no ylabel") @property def xlim(self): """The x-axis limits of the matplotlib plot.""" return self.axis.get_xlim() def assert_xlim_equal(self, xlim): """Asserts that the given xlim is the same as the plot's :attr:`~plotchecker.PlotChecker.xlim`. Parameters ---------- xlim : 2-tuple The expected xlim """ if self.xlim != xlim: raise AssertionError( "xlim is incorrect: {} (expected {})".format( self.xlim, xlim)) @property def ylim(self): """The y-axis limits of the matplotlib plot.""" return self.axis.get_ylim() def assert_ylim_equal(self, ylim): """Asserts that the given ylim is the same as the plot's :attr:`~plotchecker.PlotChecker.ylim`. Parameters ---------- ylim : 2-tuple The expected ylim """ if self.ylim != ylim: raise AssertionError( "ylim is incorrect: {} (expected {})".format( self.ylim, ylim)) @property def xticks(self): """The tick locations along the plot's x-axis.""" return self.axis.get_xticks() def assert_xticks_equal(self, xticks): """Asserts that the given xticks are the same as the plot's :attr:`~plotchecker.PlotChecker.xticks`. Parameters ---------- xticks : list The expected tick locations on the x-axis """ np.testing.assert_equal(self.xticks, xticks) @property def yticks(self): """The tick locations along the plot's y-axis.""" return self.axis.get_yticks() def assert_yticks_equal(self, yticks): """Asserts that the given yticks are the same as the plot's :attr:`~plotchecker.PlotChecker.yticks`. Parameters ---------- yticks : list The expected tick locations on the y-axis """ np.testing.assert_equal(self.yticks, yticks) @property def xticklabels(self): """The tick labels along the plot's x-axis, stripped of whitespace.""" return [x.get_text().strip() for x in self.axis.get_xticklabels()] def assert_xticklabels_equal(self, xticklabels): """Asserts that the given xticklabels are the same as the plot's :attr:`~plotchecker.PlotChecker.xticklabels`. Parameters ---------- xticklabels : list The expected tick labels on the x-axis """ xticklabels = [x.strip() for x in xticklabels] np.testing.assert_equal(self.xticklabels, xticklabels) @property def yticklabels(self): """The tick labels along the plot's y-axis, stripped of whitespace.""" return [x.get_text().strip() for x in self.axis.get_yticklabels()] def assert_yticklabels_equal(self, yticklabels): """Asserts that the given yticklabels are the same as the plot's :attr:`~plotchecker.PlotChecker.yticklabels`. Parameters ---------- yticklabels : list The expected tick labels on the y-axis """ yticklabels = [y.strip() for y in yticklabels] np.testing.assert_equal(self.yticklabels, yticklabels) @property def _texts(self): """All ``matplotlib.text.Text`` objects in the plot, excluding titles.""" texts = [] for x in self.axis.get_children(): if not isinstance(x, matplotlib.text.Text): continue if x == self.axis.title: continue if x == getattr(self.axis, '_left_title', None): continue if x == getattr(self.axis, '_right_title', None): continue texts.append(x) return texts @property def textlabels(self): """The labels of all ``matplotlib.text.Text`` objects in the plot, excluding titles.""" return [x.get_text().strip() for x in self._texts] def assert_textlabels_equal(self, textlabels): """Asserts that the given textlabels are the same as the plot's :attr:`~plotchecker.PlotChecker.textlabels`. Parameters ---------- textlabels : list The expected text labels on the plot """ textlabels = [x.strip() for x in textlabels] np.testing.assert_equal(self.textlabels, textlabels) @property def textpoints(self): """The locations of all ``matplotlib.text.Text`` objects in the plot, excluding titles.""" return np.vstack([x.get_position() for x in self._texts]) def assert_textpoints_equal(self, textpoints): """Asserts that the given locations of the text objects are the same as the plot's :attr:`~plotchecker.PlotChecker.textpoints`. Parameters ---------- textpoints : array-like, N-by-2 The expected text locations on the plot, where the first column corresponds to the x-values, and the second column corresponds to the y-values. """ np.testing.assert_equal(self.textpoints, textpoints) def assert_textpoints_allclose(self, textpoints, **kwargs): """Asserts that the given locations of the text objects are almost the same as the plot's :attr:`~plotchecker.PlotChecker.textpoints`. Parameters ---------- textpoints : array-like, N-by-2 The expected text locations on the plot, where the first column corresponds to the x-values, and the second column corresponds to the y-values. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose(self.textpoints, textpoints, **kwargs) PKQL᜹fQfQplotchecker/lineplot.pyimport numpy as np import itertools from .base import PlotChecker, InvalidPlotError class LinePlotChecker(PlotChecker): """A plot checker for line plots. Parameters ---------- axis : ``matplotlib.axes.Axes`` object A set of matplotlib axes (e.g. obtained through ``plt.gca()``) """ def __init__(self, axis): """Initialize the line plot checker.""" super(LinePlotChecker, self).__init__(axis) self._lines = self.axis.get_lines() self._perm = list(range(len(self._lines))) # check that there are some lines plotted if len(self._lines) == 0: raise InvalidPlotError("No data found") def _assert_equal(self, attr, expected, actual, perm=None, func=None, **kwargs): """Helper method for asserting that attributes are equal. This should only really be called by other methods in this class. Because the plot may have multiple lines, we want to first check whether the number of expected attributes is the same as the actual number of expected attributes. Then, assuming they are, we go check the equality of the attribute for each line separately. That way we can give a useful error message to users about which line, specifically, doesn't match. Parameters ---------- attr : string The name of the attribute expected : The expected value of the attribute actual : The actual value of the attribute perm : list of integers (default: ``None``) The permutation between the expected lines and actual lines. If not given, then ``self._perm`` is used. func : function (default=``numpy.testing.assert_equal``) An assertion function to check for equality. kwargs : Additional keyword arguments to pass to ``func`` """ # first check that the number of attributes matches if len(expected) != len(actual): raise AssertionError( "Invalid length for attribute '{}': {} (expected {})".format( attr, len(actual), len(expected))) # figure out the value of the permutation if perm is None: perm = self._perm # set the default value of the function, if necessary if func is None: func = np.testing.assert_equal # check each line separately for i in range(len(expected)): try: func(actual[i], expected[perm[i]], **kwargs) except AssertionError: raise AssertionError( "Attribute '{}' does not match for line {} (expected: {}, actual: {})".format( attr, i, expected[perm[i]], actual[i])) def _assert_allclose(self, attr, expected, actual, perm=None, **kwargs): """Wrapper for ``self._assert_equal`` that passes ``numpy.testing.assert_allclose`` as the assertion function. """ self._assert_equal( attr, expected, actual, perm=perm, func=np.testing.assert_allclose, **kwargs) def find_permutation(self, attr_name, attr_vals): """Find the order of the lines such that the given attribute (given by ``attr_name`` and ``attr_vals``) has values in the same order as those that were plotted. This function is useful if you are not sure what order the lines were plotted in. If, for example, you know there should be one red line, one blue line, and one green line---but not the order---you can use this method with ``'color'`` as the attribute name and ``['red', 'green', 'blue']`` as the attribute values. Then, any subsequent assertions will use the permutation found by this function. Parameters ---------- attr_name : string The name of the attribute to use for finding the permutation. attr_vals : The expected values of the attribute Examples -------- Let's say the instructions are to create three lines: one red line with data ``xr`` and ``yr``; one blue line with data ``xb`` and ``yb``, and one green line with data ``xg`` and ``yg``. Here is one way that plot might be created: .. code:: python fig, ax = plt.subplots() ax.plot(xg, yg, 'g-') ax.plot(xb, yb, 'b-') ax.plot(xr, yr, 'r-') However, the lines could have been plotted in any order. So, for example, the following would fail, because it assumes the order is 'red', 'green', and 'blue': .. code:: python pc = LinePlotChecker(ax) pc.assert_x_data_equal([xr, xg, xb]) # fails To avoid having to check every permutation, you can use this ``find_permutation`` method to do it for you: .. code:: python pc = LinePlotChecker(ax) pc.find_permutation('color', ['r', 'g', 'b']) pc.assert_x_data_equal([xr, xg, xb]) # passes """ # if the attribute is one of the color attributes, we need to make sure # to properly parse the values into RGB tuples if attr_name in ('colors', 'markerfacecolors', 'markeredgecolors'): expected = np.array([self._color2rgb(i) for i in attr_vals]) else: expected = attr_vals # get the actual value of the attribute actual = getattr(self, attr_name) # check that the length matches if len(expected) != len(actual): raise AssertionError( "Invalid length for attribute '{}': {} (expected {})".format( attr_name, len(actual), len(expected))) # look through all the permutations of the expected values, and try to # match them with the actual values. If a permutation is found where # the values match, then set that as the permutation for the class. If # no permutation is found, then raise an error. for perm in itertools.permutations(np.arange(len(expected))): try: self._assert_equal(attr_name, expected, actual, perm=perm) except AssertionError: pass else: self._perm = perm return raise AssertionError( "Could not match plotted values {} to expected values {} for attr '{}'".format( actual, expected, attr_name)) def assert_num_lines(self, num_lines): """Assert that the plot has the given number of lines. Parameters ---------- num_lines : int """ if num_lines != len(self._lines): raise AssertionError( "Plot has incorrect number of lines: {} (expected {})".format( len(self._lines), num_lines)) @property def x_data(self): """The x-values of the plotted data (list of arrays, one array per line).""" return [x.get_xydata()[:, 0] for x in self._lines] def assert_x_data_equal(self, x_data): """Assert that the given x-data is equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.x_data`. Parameters ---------- x_data : list of array-like The expected x-data. The number of elements should be equal to the (expected) number of plotted lines. """ self._assert_equal("x_data", x_data, self.x_data) def assert_x_data_allclose(self, x_data, **kwargs): """Assert that the given x-data is almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.x_data`. Parameters ---------- x_data : list of array-like The expected x-data. The number of elements should be equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose("x_data", x_data, self.x_data, **kwargs) @property def y_data(self): """The y-values of the plotted data (list of arrays, one array per line).""" return [x.get_xydata()[:, 1] for x in self._lines] def assert_y_data_equal(self, y_data): """Assert that the given y-data is equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.y_data`. Parameters ---------- y_data : list of array-like The expected y-data. The number of elements should be equal to the (expected) number of plotted lines. """ self._assert_equal("y_data", y_data, self.y_data) def assert_y_data_allclose(self, y_data, **kwargs): """Assert that the given y-data is almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.y_data`. Parameters ---------- y_data : list of array-like The expected y-data. The number of elements should be equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose("y_data", y_data, self.y_data, **kwargs) @property def colors(self): """The colors of the plotted lines. Each color is a RGB 3-tuple.""" return np.array([self._color2rgb(x.get_color()) for x in self._lines]) def assert_colors_equal(self, colors): """Assert that the given colors are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.colors`. Parameters ---------- colors : list of expected line colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ colors = np.array([self._color2rgb(x) for x in colors]) self._assert_equal("colors", colors, self.colors) def assert_colors_allclose(self, colors, **kwargs): """Assert that the given colors are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.colors`. Parameters ---------- colors : list of expected line colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ colors = np.array([self._color2rgb(x) for x in colors]) self._assert_allclose("colors", colors, self.colors, **kwargs) @property def alphas(self): """The alpha values of the plotted lines.""" all_alphas = [] for x in self._lines: if x.get_alpha() is None: all_alphas.append(self._color2alpha(x.get_color())) else: all_alphas.append(x.get_alpha()) return all_alphas def assert_alphas_equal(self, alphas): """Assert that the given alpha values are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.alphas`. Parameters ---------- alphas : list of floats The expected alpha values, with length equal to the (expected) number of plotted lines. """ self._assert_equal("alphas", alphas, self.alphas) def assert_alphas_allclose(self, alphas, **kwargs): """Assert that the given alpha values are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.alphas`. Parameters ---------- alphas : list of floats The expected alpha values, with length equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose("alphas", alphas, self.alphas, **kwargs) @property def linewidths(self): """The line widths of the plotted lines.""" return [x.get_linewidth() for x in self._lines] def assert_linewidths_equal(self, linewidths): """Assert that the given line widths are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.linewidths`. Parameters ---------- linewidths : list of numbers The expected linewidths, with length equal to the (expected) number of plotted lines. """ self._assert_equal("linewidths", linewidths, self.linewidths) def assert_linewidths_allclose(self, linewidths, **kwargs): """Assert that the given line widths are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.linewidths`. Parameters ---------- linewidths : list of numbers The expected linewidths, with length equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose("linewidths", linewidths, self.linewidths, **kwargs) @property def markerfacecolors(self): """The colors of the marker faces for the plotted lines.""" return [self._color2rgb(x.get_markerfacecolor()) for x in self._lines] def assert_markerfacecolors_equal(self, markerfacecolors): """Assert that the given marker face colors are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.markerfacecolors`. Parameters ---------- markerfacecolors : list of expected marker face colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ markerfacecolors = np.array([self._color2rgb(x) for x in markerfacecolors]) self._assert_equal("markerfacecolors", markerfacecolors, self.markerfacecolors) def assert_markerfacecolors_allclose(self, markerfacecolors, **kwargs): """Assert that the given marker face colors are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.markerfacecolors`. Parameters ---------- markerfacecolors : list of expected marker face colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ markerfacecolors = np.array([self._color2rgb(x) for x in markerfacecolors]) self._assert_allclose( "markerfacecolors", markerfacecolors, self.markerfacecolors, **kwargs) @property def markeredgecolors(self): """The colors of the marker edges for the plotted lines.""" return [self._color2rgb(x.get_markeredgecolor()) for x in self._lines] def assert_markeredgecolors_equal(self, markeredgecolors): """Assert that the given marker edge colors are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.markeredgecolors`. Parameters ---------- markeredgecolors : list of expected marker edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ markeredgecolors = np.array([self._color2rgb(x) for x in markeredgecolors]) self._assert_equal("markeredgecolors", markeredgecolors, self.markeredgecolors) def assert_markeredgecolors_allclose(self, markeredgecolors, **kwargs): """Assert that the given marker edge colors are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.markeredgecolors`. Parameters ---------- markeredgecolors : list of expected marker edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ markeredgecolors = np.array([self._color2rgb(x) for x in markeredgecolors]) self._assert_allclose( "markeredgecolors", markeredgecolors, self.markeredgecolors, **kwargs) @property def markeredgewidths(self): """The widths of the marker edges for the plotted lines.""" return [x.get_markeredgewidth() for x in self._lines] def assert_markeredgewidths_equal(self, markeredgewidths): """Assert that the given marker edge widths are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.markeredgewidths`. Parameters ---------- markeredgewidths : list of expected marker edge widths The expected edge widths, with length equal to the (expected) number of plotted lines. """ self._assert_equal("markeredgewidths", markeredgewidths, self.markeredgewidths) def assert_markeredgewidths_allclose(self, markeredgewidths, **kwargs): """Assert that the given marker edge widths are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.markeredgewidths`. Parameters ---------- markeredgewidths : list of expected marker edge widths The expected edge widths, with length equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose( "markeredgewidths", markeredgewidths, self.markeredgewidths, **kwargs) @property def markersizes(self): """The marker sizes for the plotted lines.""" return [x.get_markersize() for x in self._lines] def assert_markersizes_equal(self, markersizes): """Assert that the given marker sizes are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.markersizes`. Parameters ---------- markersizes : list of expected marker sizes The expected marker sizes, with length equal to the (expected) number of plotted lines. """ self._assert_equal("markersizes", markersizes, self.markersizes) def assert_markersizes_allclose(self, markersizes, **kwargs): """Assert that the given marker sizes are almost equal to the plotted :attr:`~plotchecker.LinePlotChecker.markersizes`. Parameters ---------- markersizes : list of expected marker sizes The expected marker sizes, with length equal to the (expected) number of plotted lines. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ self._assert_allclose( "markersizes", markersizes, self.markersizes, **kwargs) @property def markers(self): """The marker types for the plotted lines.""" return [self._parse_marker(x.get_marker()) for x in self._lines] def assert_markers_equal(self, markers): """Assert that the given markers are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.markers`. Parameters ---------- markers : list of strings The expected markers, with length equal to the (expected) number of plotted lines. """ markers = [self._parse_marker(x) for x in markers] self._assert_equal("markers", markers, self.markers) @property def labels(self): """The legend labels of the plotted lines.""" legend = self.axis.get_legend() if legend is None: return [] return [x.get_text() for x in legend.texts] def assert_labels_equal(self, labels): """Assert that the given legend labels are equivalent to the plotted :attr:`~plotchecker.LinePlotChecker.labels`. Parameters ---------- labels : list of strings The expected legend labels, with length equal to the (expected) number of plotted lines. """ self._assert_equal("labels", labels, self.labels) PKQLM@GGplotchecker/scatterplot.pyimport numpy as np from .base import PlotChecker, InvalidPlotError class ScatterPlotChecker(PlotChecker): """A plot checker for scatter plots. Parameters ---------- axis : ``matplotlib.axes.Axes`` object A set of matplotlib axes (e.g. obtained through ``plt.gca()``) """ def __init__(self, axis): """Initialize the scatter plot checker.""" super(ScatterPlotChecker, self).__init__(axis) self.lines = self.axis.get_lines() self.collections = self.axis.collections # check that there are only lines or collections, not both if len(self.lines) == 0 and len(self.collections) == 0: raise InvalidPlotError("No data found") # check that if there are lines, linestyle is '' and markers are not '' for x in self.lines: if len(x.get_xydata()) > 1 and x.get_linestyle() != 'None': raise InvalidPlotError("This is supposed to be a scatter plot, but it has lines!") if self._parse_marker(x.get_marker()) == '': raise InvalidPlotError("This is supposed to be a scatter plot, but there are no markers!") def _parse_expected_attr(self, attr_name, attr_val): """Ensure that the given expected attribute values are in the right shape.""" if attr_name in ('colors', 'edgecolors'): # if it's a color, first check if it's just a single color -- if it's # not a single color, this command will throw an error and we can try # iterating over the multiple colors that were given try: attr_val = np.array([self._color2rgb(attr_val)]) except (ValueError, TypeError): attr_val = np.array([self._color2rgb(x) for x in attr_val]) elif not hasattr(attr_val, '__iter__'): # if it's not a color, then just make sure we have an array attr_val = np.array([attr_val]) # tile the given values if we've only been given one, so it's the same # shape as the data if len(attr_val) == 1: attr_val = self._tile_or_trim(self.x_data, attr_val) return attr_val def assert_num_points(self, num_points): """Assert that the plot has the given number of points. Parameters ---------- num_points : int """ if num_points != len(self.x_data): raise AssertionError( "Plot has incorrect number of points: {} (expected {})".format( len(self.x_data), num_points)) @property def x_data(self): """The x-values of the plotted data (1-D array).""" all_x_data = [] if len(self.lines) > 0: all_x_data.append(np.concatenate([x.get_xydata()[:, 0] for x in self.lines])) if len(self.collections) > 0: all_x_data.append(np.concatenate([x.get_offsets()[:, 0] for x in self.collections])) return np.concatenate(all_x_data, axis=0) def assert_x_data_equal(self, x_data): """Assert that the given x-data is equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.x_data`. Parameters ---------- x_data : 1-D array-like The expected x-data. The number of elements should be equal to the (expected) number of plotted points. """ np.testing.assert_equal(self.x_data, x_data) def assert_x_data_allclose(self, x_data, **kwargs): """Assert that the given x-data is almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.x_data`. Parameters ---------- x_data : 1-D array-like The expected x-data. The number of elements should be equal to the (expected) number of plotted points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose(self.x_data, x_data, **kwargs) @property def y_data(self): """The y-values of the plotted data (1-D array).""" all_y_data = [] if len(self.lines) > 0: all_y_data.append(np.concatenate([x.get_xydata()[:, 1] for x in self.lines])) if len(self.collections) > 0: all_y_data.append(np.concatenate([x.get_offsets()[:, 1] for x in self.collections])) return np.concatenate(all_y_data, axis=0) def assert_y_data_equal(self, y_data): """Assert that the given y-data is equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.y_data`. Parameters ---------- y_data : 1-D array-like The expected y-data. The number of elements should be equal to the (expected) number of plotted points. """ np.testing.assert_equal(self.y_data, y_data) def assert_y_data_allclose(self, y_data, **kwargs): """Assert that the given y-data is almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.y_data`. Parameters ---------- y_data : 1-D array-like The expected y-data. The number of elements should be equal to the (expected) number of plotted points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose(self.y_data, y_data, **kwargs) @property def colors(self): """The colors of the plotted points. Columns correspond to RGB values.""" all_colors = [] if len(self.lines) > 0: for x in self.lines: points = x.get_xydata() colors = np.array([self._color2rgb(x.get_markerfacecolor())]) all_colors.append(self._tile_or_trim(points, colors)) if len(self.collections) > 0: for x in self.collections: points = x.get_offsets() colors = np.array([self._color2rgb(i) for i in x.get_facecolors()]) all_colors.append(self._tile_or_trim(points, colors)) return np.concatenate(all_colors, axis=0) def assert_colors_equal(self, colors): """Assert that the given colors are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.colors`. Parameters ---------- colors : single color, or list of expected line colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ np.testing.assert_equal( self.colors, self._parse_expected_attr("colors", colors)) def assert_colors_allclose(self, colors, **kwargs): """Assert that the given colors are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.colors`. Parameters ---------- colors : single color, or list of expected line colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.colors, self._parse_expected_attr("colors", colors), **kwargs) @property def alphas(self): """The alpha values of the plotted points.""" all_alphas = [] if len(self.lines) > 0: for x in self.lines: points = x.get_xydata() if x.get_alpha() is None: alpha = np.array([self._color2alpha(x.get_markerfacecolor())]) else: alpha = np.array([x.get_alpha()]) all_alphas.append(self._tile_or_trim(points, alpha)) if len(self.collections) > 0: for x in self.collections: points = x.get_offsets() if x.get_alpha() is None: alpha = np.array([self._color2alpha(i) for i in x.get_facecolors()]) else: alpha = np.array([x.get_alpha()]) all_alphas.append(self._tile_or_trim(points, alpha)) return np.concatenate(all_alphas) def assert_alphas_equal(self, alphas): """Assert that the given alpha values are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.alphas`. Parameters ---------- alphas : The expected alpha values. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. """ np.testing.assert_equal( self.alphas, self._parse_expected_attr("alphas", alphas)) def assert_alphas_allclose(self, alphas, **kwargs): """Assert that the given alpha values are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.alphas`. Parameters ---------- alphas : The expected alpha values. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.alphas, self._parse_expected_attr("alphas", alphas), **kwargs) @property def edgecolors(self): """The edge colors of the plotted points. Columns correspond to RGB values.""" all_colors = [] if len(self.lines) > 0: for x in self.lines: points = x.get_xydata() colors = np.array([self._color2rgb(x.get_markeredgecolor())]) all_colors.append(self._tile_or_trim(points, colors)) if len(self.collections) > 0: for x in self.collections: points = x.get_offsets() colors = np.array([self._color2rgb(i) for i in x.get_edgecolors()]) all_colors.append(self._tile_or_trim(points, colors)) return np.concatenate(all_colors, axis=0) def assert_edgecolors_equal(self, edgecolors): """Assert that the given edge colors are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.edgecolors`. Parameters ---------- edgecolors : single color, or list of expected edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. """ np.testing.assert_equal( self.edgecolors, self._parse_expected_attr("edgecolors", edgecolors)) def assert_edgecolors_allclose(self, edgecolors, **kwargs): """Assert that the given edge colors are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.edgecolors`. Parameters ---------- edgecolors : single color, or list of expected edge colors Each color can be either a matplotlib color name (e.g. ``'r'`` or ``'red'``), a hexcode (e.g. ``"#FF0000"``), a 3-tuple RGB color, or a 4-tuple RGBA color. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.edgecolors, self._parse_expected_attr("edgecolors", edgecolors), **kwargs) @property def edgewidths(self): """The edge widths of the plotted points.""" all_colors = [] if len(self.lines) > 0: for x in self.lines: points = x.get_xydata() colors = np.array([x.get_markeredgewidth()]) all_colors.append(self._tile_or_trim(points, colors)) if len(self.collections) > 0: for x in self.collections: points = x.get_offsets() colors = np.array(x.get_linewidths()) all_colors.append(self._tile_or_trim(points, colors)) return np.concatenate(all_colors, axis=0) def assert_edgewidths_equal(self, edgewidths): """Assert that the given edge widths are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.edgewidths`. Parameters ---------- edgewidths : The expected edge widths. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. """ np.testing.assert_equal( self.edgewidths, self._parse_expected_attr("edgewidths", edgewidths)) def assert_edgewidths_allclose(self, edgewidths, **kwargs): """Assert that the given edge widths are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.edgewidths`. Parameters ---------- edgewidths : The expected edge widths. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.edgewidths, self._parse_expected_attr("edgewidths", edgewidths), **kwargs) @property def sizes(self): """The size of the plotted points. This is the square of :attr:`~plotchecker.ScatterPlotChecker.markersizes`. """ all_sizes = [] if len(self.lines) > 0: for x in self.lines: points = x.get_xydata() sizes = np.array([x.get_markersize() ** 2]) all_sizes.append(self._tile_or_trim(points, sizes)) if len(self.collections) > 0: for x in self.collections: points = x.get_offsets() sizes = x.get_sizes() all_sizes.append(self._tile_or_trim(points, sizes)) return np.concatenate(all_sizes, axis=0) def assert_sizes_equal(self, sizes): """Assert that the given point sizes are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.sizes`. Parameters ---------- sizes : The expected point sizes. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. """ np.testing.assert_equal( self.sizes, self._parse_expected_attr("sizes", sizes)) def assert_sizes_allclose(self, sizes, **kwargs): """Assert that the given point sizes are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.sizes`. Parameters ---------- sizes : The expected point sizes. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.sizes, self._parse_expected_attr("sizes", sizes), **kwargs) @property def markersizes(self): """The marker size of the plotted points. This is the square root of :attr:`~plotchecker.ScatterPlotChecker.sizes`. """ return np.sqrt(self.sizes) def assert_markersizes_equal(self, markersizes): """Assert that the given marker sizes are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.markersizes`. Parameters ---------- markersizes : The expected marker sizes. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. """ np.testing.assert_equal( self.markersizes, self._parse_expected_attr("markersizes", markersizes)) def assert_markersizes_allclose(self, markersizes, **kwargs): """Assert that the given marker sizes are almost equal to the plotted :attr:`~plotchecker.ScatterPlotChecker.markersizes`. Parameters ---------- markersizes : The expected marker sizes. This should either be a single number (which will apply to all the points) or an array with size equal to the number of (expected) points. kwargs : Additional keyword arguments to pass to ``numpy.testing.assert_allclose`` """ np.testing.assert_allclose( self.markersizes, self._parse_expected_attr("markersizes", markersizes), **kwargs) @property def markers(self): """The marker styles of the plotted points. Unfortunately, this information is currently unrecoverable from matplotlib, and so this attribute is not actually implemented. """ raise NotImplementedError("markers are unrecoverable for scatter plots") def assert_markers_equal(self, markers): """Assert that the given marker styles are equivalent to the plotted :attr:`~plotchecker.ScatterPlotChecker.markers`. Note: information about marker style is currently unrecoverable from collections in matplotlib, so this method is not actually implemented. Parameters ---------- markers : The expected marker styles. This should either be a single style (which will apply to all the points) or an array with size equal to the number of (expected) points. """ np.testing.assert_equal( self.markers, self._parse_expected_attr("markers", markers)) PKQLplotchecker/tests/__init__.pyPKQL}ыplotchecker/tests/conftest.pyimport matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt import pytest @pytest.fixture def axis(request): fig, ax = plt.subplots() def fin(): plt.close(fig) request.addfinalizer(fin) return ax @pytest.fixture def axes(request): fig, axes = plt.subplots(1, 3) def fin(): plt.close(fig) request.addfinalizer(fin) return axes PKvQL-b!!!plotchecker/tests/test_barplot.pyimport pytest import numpy as np from .. import BarPlotChecker, InvalidPlotError def test_empty_plot(axis): """Is an error thrown when there is nothing plotted?""" with pytest.raises(InvalidPlotError): BarPlotChecker(axis) def test_num_bars(axis): """Are the number of bars correct?""" x = np.arange(10) y = np.linspace(1, 5, 10) axis.bar(x, y) pc = BarPlotChecker(axis) pc.assert_num_bars(10) with pytest.raises(AssertionError): pc.assert_num_bars(6) def test_data_left(axis): """Are the x and y values correct?""" x = np.arange(10) y = np.linspace(1, 5, 10) b = np.linspace(0, 1, 10) axis.bar(x, y, bottom=b, align='edge') pc = BarPlotChecker(axis) pc.assert_centers_equal(x + 0.4) pc.assert_heights_equal(y) pc.assert_bottoms_equal(b) def test_data_left_allclose(axis): """Are the x and y values almost correct?""" err = 1e-12 x = np.arange(1, 11) y = np.linspace(1, 5, 10) b = np.linspace(0.1, 1, 10) axis.bar(x + err, y + err, bottom=b + err, align='edge') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_centers_equal(x + 0.4) with pytest.raises(AssertionError): pc.assert_heights_equal(y) with pytest.raises(AssertionError): pc.assert_bottoms_equal(b) with pytest.raises(AssertionError): pc.assert_centers_allclose(x + 0.4, rtol=1e-13) with pytest.raises(AssertionError): pc.assert_heights_allclose(y, rtol=1e-13) with pytest.raises(AssertionError): pc.assert_bottoms_allclose(b, rtol=1e-13) pc.assert_centers_allclose(x + 0.4) pc.assert_heights_allclose(y) pc.assert_bottoms_allclose(b) def test_data_center(axis): """Are the x and y values correct with align=center?""" x = np.arange(10) y = np.linspace(1, 5, 10) b = np.linspace(0, 1, 10) axis.bar(x, y, bottom=b, align='center') pc = BarPlotChecker(axis) pc.assert_centers_equal(x) pc.assert_heights_equal(y) pc.assert_bottoms_equal(b) def test_data_center_allclose(axis): """Are the x and y values almost correct?""" err = 1e-12 x = np.arange(1, 11) y = np.linspace(1, 5, 10) b = np.linspace(0.1, 1, 10) axis.bar(x + err, y + err, bottom=b + err, align='center') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_centers_equal(x) with pytest.raises(AssertionError): pc.assert_heights_equal(y) with pytest.raises(AssertionError): pc.assert_bottoms_equal(b) with pytest.raises(AssertionError): pc.assert_centers_allclose(x, rtol=1e-13) with pytest.raises(AssertionError): pc.assert_heights_allclose(y, rtol=1e-13) with pytest.raises(AssertionError): pc.assert_bottoms_allclose(b, rtol=1e-13) pc.assert_centers_allclose(x) pc.assert_heights_allclose(y) pc.assert_bottoms_allclose(b) def test_widths(axis): """Are the widths correct?""" x = np.arange(10) y = np.linspace(1, 5, 10) w = np.linspace(0.5, 1, 10) for i in range(len(x)): axis.bar(x[i], y[i], width=w[i], align='center') pc = BarPlotChecker(axis) pc.assert_centers_equal(x) pc.assert_heights_equal(y) pc.assert_widths_equal(w) def test_widths_allclose(axis): """Are the widths almost correct?""" err = 1e-12 x = np.arange(10) y = np.linspace(1, 5, 10) w = np.linspace(0.5, 1, 10) for i in range(len(x)): axis.bar(x[i], y[i], width=w[i] + err, align='center') pc = BarPlotChecker(axis) pc.assert_centers_equal(x) pc.assert_heights_equal(y) with pytest.raises(AssertionError): pc.assert_widths_equal(w) with pytest.raises(AssertionError): pc.assert_widths_allclose(w, rtol=1e-13) pc.assert_widths_allclose(w) def test_colors(axis): """Are the colors correct?""" x = np.arange(5) y = np.linspace(1, 5, 5) colors = ['r', '#FF0000', (0, 0, 0), 'blue', (0, 1, 0.5, 1)] for i in range(len(x)): axis.bar(x[i], y[i], color=colors[i], align='center') pc = BarPlotChecker(axis) pc.assert_colors_equal(colors) def test_colors_allclose(axis): """Are the colors almost correct?""" err = 1e-12 x = np.arange(5) y = np.linspace(1, 5, 5) colors = np.array([(0.8, 0.2, 0.2), (0.2, 0.8, 0.2), (0.2, 0.2, 0.2), (0.2, 0.2, 0.8), (0.8, 0.8, 0.8)]) for i in range(len(x)): axis.bar(x[i], y[i], color=tuple(colors[i] + err), align='center') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_colors_equal(colors) with pytest.raises(AssertionError): pc.assert_colors_allclose(colors, rtol=1e-13) pc.assert_colors_allclose(colors) def test_edgecolors(axis): """Are the edgecolors correct?""" x = np.arange(5) y = np.linspace(1, 5, 5) edgecolors = ['r', '#FF0000', (0, 0, 0), 'blue', (0, 1, 0.5, 1)] for i in range(len(x)): axis.bar(x[i], y[i], edgecolor=edgecolors[i], align='center') pc = BarPlotChecker(axis) pc.assert_edgecolors_equal(edgecolors) def test_edgecolors_allclose(axis): """Are the edgecolors almost correct?""" err = 1e-12 x = np.arange(5) y = np.linspace(1, 5, 5) edgecolors = np.array([(0.8, 0.2, 0.2), (0.2, 0.8, 0.2), (0.2, 0.2, 0.2), (0.2, 0.2, 0.8), (0.8, 0.8, 0.8)]) for i in range(len(x)): axis.bar(x[i], y[i], edgecolor=tuple(edgecolors[i] + err), align='center') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_edgecolors_equal(edgecolors) with pytest.raises(AssertionError): pc.assert_edgecolors_allclose(edgecolors, rtol=1e-13) pc.assert_edgecolors_allclose(edgecolors) def test_alphas(axis): """Are the alphas correct?""" x = np.arange(5) y = np.linspace(1, 5, 5) alphas = np.linspace(0.1, 1, 5) for i in range(len(x)): axis.bar(x[i], y[i], alpha=alphas[i], align='center') pc = BarPlotChecker(axis) pc.assert_alphas_equal(alphas) def test_alphas_allclose(axis): """Are the alphas almost correct?""" err = 1e-12 x = np.arange(5) y = np.linspace(1, 5, 5) alphas = np.linspace(0.1, 0.99, 5) for i in range(len(x)): axis.bar(x[i], y[i], alpha=alphas[i] + err, align='center') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_alphas_equal(alphas) with pytest.raises(AssertionError): pc.assert_alphas_allclose(alphas, rtol=1e-13) pc.assert_alphas_allclose(alphas) def test_linewidths(axis): """Are the linewidths correct?""" x = np.arange(5) y = np.linspace(1, 5, 5) linewidths = np.linspace(0.1, 1, 5) for i in range(len(x)): axis.bar(x[i], y[i], linewidth=linewidths[i], align='center') pc = BarPlotChecker(axis) pc.assert_linewidths_equal(linewidths) def test_linewidths_allclose(axis): """Are the linewidths almost correct?""" err = 1e-12 x = np.arange(5) y = np.linspace(1, 5, 5) linewidths = np.linspace(0.1, 1, 5) for i in range(len(x)): axis.bar(x[i], y[i], linewidth=linewidths[i] + err, align='center') pc = BarPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_linewidths_equal(linewidths) with pytest.raises(AssertionError): pc.assert_linewidths_allclose(linewidths, rtol=1e-13) pc.assert_linewidths_allclose(linewidths) def test_example(axes): x = np.arange(1, 11) y = np.random.rand(10) colors = np.random.rand(10, 4) alphas = colors[:, 3] widths = (np.random.rand(10) / 2) + 0.5 # plot some bars for i in range(len(x)): axes[0].bar(x[i], y[i], width=widths[i], align='center', color=colors[i]) # plot them in a different order idx = np.arange(len(x)) np.random.shuffle(idx) for i in idx: axes[1].bar(x[i] - (widths[i] / 2), y[i], width=widths[i], align='edge', color=colors[i, :3], alpha=alphas[i]) # plot them in yet another order idx = np.arange(len(x))[::-1] for i in idx: axes[2].bar(x[i], y[i], width=widths[i], align='center', color=colors[i, :3], alpha=alphas[i]) for ax in axes: pc = BarPlotChecker(ax) pc.assert_centers_equal(x) pc.assert_heights_equal(y) pc.assert_widths_equal(widths) pc.assert_bottoms_equal(0) pc.assert_colors_equal(colors) pc.assert_edgecolors_equal('k') pc.assert_alphas_equal(alphas) pc.assert_linewidths_equal(1) PKQLplotchecker/tests/test_base.pyimport pytest import numpy as np from .. import PlotChecker def test_color2rgb(): assert PlotChecker._color2rgb('r') == (1, 0, 0) assert PlotChecker._color2rgb('black') == (0, 0, 0) assert PlotChecker._color2rgb([0, 1, 0]) == (0, 1, 0) assert PlotChecker._color2rgb([0, 1, 0, 1]) == (0, 1, 0) with pytest.raises(ValueError): PlotChecker._color2rgb('foo') with pytest.raises(ValueError): PlotChecker._color2rgb(1) def test_color2alpha(): assert PlotChecker._color2alpha('r') == 1 assert PlotChecker._color2alpha('black') == 1 assert PlotChecker._color2alpha([0, 1, 0]) == 1 assert PlotChecker._color2alpha([0, 1, 0, 0.5]) == 0.5 with pytest.raises(ValueError): PlotChecker._color2alpha(1) def test_tile_or_trim(): x = np.array([1, 2, 3]) y0 = np.array([4, 5]) y1 = PlotChecker._tile_or_trim(x, y0) np.testing.assert_array_equal(y1, np.array([4, 5, 4])) x = np.array([1, 2, 3]) y0 = np.array([[0, -1, -2]]) y1 = PlotChecker._tile_or_trim(x, y0) np.testing.assert_array_equal(y1, np.array([[0, -1, -2], [0, -1, -2], [0, -1, -2]])) x = np.array([[1, 0], [2, 1], [3, 4]]) y0 = np.array([[0, -1, -2]]) y1 = PlotChecker._tile_or_trim(x, y0) np.testing.assert_array_equal(y1, np.array([[0, -1, -2], [0, -1, -2], [0, -1, -2]])) def test_title_assertions(axis): pc = PlotChecker(axis) with pytest.raises(AssertionError): pc.assert_title_exists() axis.set_title("foo") pc.assert_title_exists() pc.assert_title_equal("foo") with pytest.raises(AssertionError): pc.assert_title_equal("bar") def test_xlabel_assertions(axis): pc = PlotChecker(axis) with pytest.raises(AssertionError): pc.assert_xlabel_exists() axis.set_xlabel("foo") pc.assert_xlabel_exists() pc.assert_xlabel_equal("foo") with pytest.raises(AssertionError): pc.assert_xlabel_equal("bar") def test_ylabel_assertions(axis): pc = PlotChecker(axis) with pytest.raises(AssertionError): pc.assert_ylabel_exists() axis.set_ylabel("foo") pc.assert_ylabel_exists() pc.assert_ylabel_equal("foo") with pytest.raises(AssertionError): pc.assert_ylabel_equal("bar") def test_assert_xlim_equal(axis): pc = PlotChecker(axis) axis.set_xlim(0, 1) pc.assert_xlim_equal((0, 1)) with pytest.raises(AssertionError): pc.assert_xlim_equal((1, 0)) def test_assert_ylim_equal(axis): pc = PlotChecker(axis) axis.set_ylim(0, 1) pc.assert_ylim_equal((0, 1)) with pytest.raises(AssertionError): pc.assert_ylim_equal((1, 0)) def test_assert_xticks_equal(axis): pc = PlotChecker(axis) axis.set_xticks([0, 1, 2, 3]) pc.assert_xticks_equal([0, 1, 2, 3]) with pytest.raises(AssertionError): pc.assert_xticks_equal([0, 1]) def test_assert_yticks_equal(axis): pc = PlotChecker(axis) axis.set_yticks([0, 1, 2, 3]) pc.assert_yticks_equal([0, 1, 2, 3]) with pytest.raises(AssertionError): pc.assert_yticks_equal([0, 1]) def test_assert_xticklabels_equal(axis): pc = PlotChecker(axis) axis.set_xticks([0, 1, 2, 3]) axis.set_xticklabels(['a', 'b', 'c', 'd']) pc.assert_xticklabels_equal(['a', 'b', 'c', 'd']) with pytest.raises(AssertionError): pc.assert_xticklabels_equal(['a', 'b', 'c']) def test_assert_yticklabels_equal(axis): pc = PlotChecker(axis) axis.set_yticks([0, 1, 2, 3]) axis.set_yticklabels(['a', 'b', 'c', 'd']) pc.assert_yticklabels_equal(['a', 'b', 'c', 'd']) with pytest.raises(AssertionError): pc.assert_yticklabels_equal(['a', 'b', 'c']) def test_texts(axis): x = np.random.rand(10) y = np.random.rand(10) t = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] for i in range(len(x)): axis.text(x[i], y[i], t[i]) axis.set_title('foo') axis.set_xlabel('bar') axis.set_ylabel('baz') pc = PlotChecker(axis) pc.assert_textlabels_equal(t) pc.assert_textpoints_equal(np.array([x, y]).T) def test_texts_allclose(axis): err = 1e-12 x = np.round(np.random.rand(10), decimals=3) y = np.round(np.random.rand(10), decimals=3) x[x < 1e-3] = 1e-3 y[y < 1e-3] = 1e-3 t = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] for i in range(len(x)): axis.text(x[i] + err, y[i] + err, t[i]) axis.set_title('foo') axis.set_xlabel('bar') axis.set_ylabel('baz') pc = PlotChecker(axis) pc.assert_textlabels_equal(t) with pytest.raises(AssertionError): pc.assert_textpoints_equal(np.array([x, y]).T) with pytest.raises(AssertionError): pc.assert_textpoints_allclose(np.array([x, y]).T, rtol=1e-13) pc.assert_textpoints_allclose(np.array([x, y]).T) PKvQLEE"plotchecker/tests/test_lineplot.pyimport pytest import numpy as np from .. import LinePlotChecker, InvalidPlotError def test_empty_plot(axis): """Is an error thrown when there is nothing plotted?""" with pytest.raises(InvalidPlotError): LinePlotChecker(axis) def test_num_lines(axis): """Are the number of lines correct?""" # first just try for a single line x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0) pc = LinePlotChecker(axis) pc.assert_num_lines(1) # now plot another line x1 = [2, 3.17, 4.3, 5, 6] y1 = [1.5, 2.25, 3.4, 4, 7] axis.plot(x1, y1) pc = LinePlotChecker(axis) pc.assert_num_lines(2) # do a line without x values y2 = [10, 20, 30] axis.plot(y2) pc = LinePlotChecker(axis) pc.assert_num_lines(3) # and now two more lines, plotted at the same time x3 = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y3 = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x3.T, y3.T) pc = LinePlotChecker(axis) pc.assert_num_lines(5) with pytest.raises(AssertionError): pc.assert_num_lines(6) def test_data(axis): """Are the x and y values correct?""" # first just try for a single line x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0) pc = LinePlotChecker(axis) pc.assert_x_data_equal([x0]) pc.assert_y_data_equal([y0]) # now plot another line x1 = [2, 3.17, 4.3, 5, 6] y1 = [1.5, 2.25, 3.4, 4, 7] axis.plot(x1, y1) pc = LinePlotChecker(axis) pc.assert_x_data_equal([x0, x1]) pc.assert_y_data_equal([y0, y1]) # do a line without x values x2 = [0, 1, 2] y2 = [10, 20, 30] axis.plot(y2) pc = LinePlotChecker(axis) pc.assert_x_data_equal([x0, x1, x2]) pc.assert_y_data_equal([y0, y1, y2]) # and now two more lines, plotted at the same time x3 = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y3 = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x3.T, y3.T) pc = LinePlotChecker(axis) pc.assert_x_data_equal([x0, x1, x2] + list(x3)) pc.assert_y_data_equal([y0, y1, y2] + list(y3)) def test_data_allclose(axis): """Are the x and y values almost correct?""" err = 1e-12 x0 = np.array([1, 2.17, 3.3, 4]) y0 = np.array([2.5, 3.25, 4.4, 5]) axis.plot(x0 + err, y0 + err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_x_data_equal([x0]) with pytest.raises(AssertionError): pc.assert_y_data_equal([y0]) with pytest.raises(AssertionError): pc.assert_x_data_allclose([x0], rtol=1e-13) with pytest.raises(AssertionError): pc.assert_y_data_allclose([y0], rtol=1e-13) pc.assert_x_data_allclose([x0]) pc.assert_y_data_allclose([y0]) def test_colors(axis): """Are the colors correct?""" # first just try for a single line using rgb axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color=[0, 1, 1]) pc = LinePlotChecker(axis) pc.assert_colors_equal([[0, 1, 1]]) # add another line, using hex values axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color='#FF0000') pc = LinePlotChecker(axis) pc.assert_colors_equal([[0, 1, 1], '#FF0000']) # add another line, using matplotlib colors axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color='g') pc = LinePlotChecker(axis) pc.assert_colors_equal([[0, 1, 1], '#FF0000', 'g']) # add another line, using full matplotlib color names axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color='magenta') pc = LinePlotChecker(axis) pc.assert_colors_equal([[0, 1, 1], '#FF0000', 'g', 'magenta']) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, color='k') pc = LinePlotChecker(axis) pc.assert_colors_equal([[0, 1, 1], '#FF0000', 'g', 'magenta', 'k', 'k']) def test_colors_allclose(axis): """Are the colors almost correct?""" err = 1e-12 color = np.array([0.1, 1, 1]) axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color=color - err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_colors_equal([color]) with pytest.raises(AssertionError): pc.assert_colors_allclose([color], rtol=1e-13) pc.assert_colors_allclose([color]) def test_linewidths(axis): """Are the linewidths correct?""" # first just try for a single line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], linewidth=1) pc = LinePlotChecker(axis) pc.assert_linewidths_equal([1]) # add another line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], linewidth=2) pc = LinePlotChecker(axis) pc.assert_linewidths_equal([1, 2]) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, linewidth=4) pc = LinePlotChecker(axis) pc.assert_linewidths_equal([1, 2, 4, 4]) def test_linewidths_allclose(axis): """Are the linewidths almost correct?""" err = 1e-12 lw = 1 axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], lw=lw + err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_linewidths_equal([lw]) with pytest.raises(AssertionError): pc.assert_linewidths_allclose([lw], rtol=1e-13) pc.assert_linewidths_allclose([lw]) def test_markerfacecolors(axis): """Are the marker face colors correct?""" # inherit the color from the line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', color='c') pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c']) # add another line, using rgb axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markerfacecolor=[0, 1, 1]) pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c', [0, 1, 1]]) # add another line, using hex values axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markerfacecolor='#FF0000') pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c', [0, 1, 1], '#FF0000']) # add another line, using matplotlib colors axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markerfacecolor='g') pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c', [0, 1, 1], '#FF0000', 'g']) # add another line, using full matplotlib color names axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markerfacecolor='magenta') pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c', [0, 1, 1], '#FF0000', 'g', 'magenta']) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, marker='o', markerfacecolor='k') pc = LinePlotChecker(axis) pc.assert_markerfacecolors_equal(['c', [0, 1, 1], '#FF0000', 'g', 'magenta', 'k', 'k']) def test_markerfacecolors_allclose(axis): """Are the markerfacecolors almost correct?""" err = 1e-12 markerfacecolor = np.array([0.1, 1, 1]) axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], markerfacecolor=list(markerfacecolor + err)) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_markerfacecolors_equal([markerfacecolor]) with pytest.raises(AssertionError): pc.assert_markerfacecolors_allclose([markerfacecolor], rtol=1e-13) pc.assert_markerfacecolors_allclose([markerfacecolor]) def test_markeredgecolors(axis): """Are the marker edge colors correct?""" # inherit the color from the line -- this should actually be the default (grey) axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', color='c') pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75]]) # add another line, using rgb axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgecolor=[0, 1, 1]) pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75], [0, 1, 1]]) # add another line, using hex values axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgecolor='#FF0000') pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75], [0, 1, 1], '#FF0000']) # add another line, using matplotlib colors axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgecolor='g') pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75], [0, 1, 1], '#FF0000', 'g']) # add another line, using full matplotlib color names axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgecolor='magenta') pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75], [0, 1, 1], '#FF0000', 'g', 'magenta']) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, marker='o', markeredgecolor='k') pc = LinePlotChecker(axis) pc.assert_markeredgecolors_equal([[0, 0.75, 0.75], [0, 1, 1], '#FF0000', 'g', 'magenta', 'k', 'k']) def test_markeredgecolors_allclose(axis): """Are the markeredgecolors almost correct?""" err = 1e-12 markeredgecolor = np.array([0.1, 1, 1]) axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], markeredgecolor=list(markeredgecolor + err)) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_markeredgecolors_equal([markeredgecolor]) with pytest.raises(AssertionError): pc.assert_markeredgecolors_allclose([markeredgecolor], rtol=1e-13) pc.assert_markeredgecolors_allclose([markeredgecolor]) def test_markeredgewidths(axis): """Are the markeredgewidths correct?""" # first just try for a single line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgewidth=1) pc = LinePlotChecker(axis) pc.assert_markeredgewidths_equal([1]) # add another line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markeredgewidth=2) pc = LinePlotChecker(axis) pc.assert_markeredgewidths_equal([1, 2]) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, marker='o', markeredgewidth=4) pc = LinePlotChecker(axis) pc.assert_markeredgewidths_equal([1, 2, 4, 4]) def test_markeredgewidths_allclose(axis): """Are the markeredgewidths almost correct?""" err = 1e-12 markeredgewidth = 1 axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], markeredgewidth=markeredgewidth + err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_markeredgewidths_equal([markeredgewidth]) with pytest.raises(AssertionError): pc.assert_markeredgewidths_allclose([markeredgewidth], rtol=1e-13) pc.assert_markeredgewidths_allclose([markeredgewidth]) def test_markersizes(axis): """Are the markersizes correct?""" # first just try for a single line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markersize=1) pc = LinePlotChecker(axis) pc.assert_markersizes_equal([1]) # add another line axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o', markersize=2) pc = LinePlotChecker(axis) pc.assert_markersizes_equal([1, 2]) # and now two more lines, plotted at the same time x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, marker='o', markersize=4) pc = LinePlotChecker(axis) pc.assert_markersizes_equal([1, 2, 4, 4]) def test_markersizes_allclose(axis): """Are the markersizes almost correct?""" err = 1e-12 markersize = 1 axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], markersize=markersize + err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_markersizes_equal([markersize]) with pytest.raises(AssertionError): pc.assert_markersizes_allclose([markersize], rtol=1e-13) pc.assert_markersizes_allclose([markersize]) def test_markers(axis): """Are the markers correct?""" # first just try for a single line with no markers axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5]) pc = LinePlotChecker(axis) pc.assert_markers_equal(['']) # now use an empty marker axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='') pc = LinePlotChecker(axis) pc.assert_markers_equal(['', '']) # now use the o marker axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='o') pc = LinePlotChecker(axis) pc.assert_markers_equal(['', '', 'o']) # add another line with the . marker axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], marker='.') pc = LinePlotChecker(axis) pc.assert_markers_equal(['', '', 'o', '.']) # and now two more lines, plotted at the same time, with the D marker x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, marker='D') pc = LinePlotChecker(axis) pc.assert_markers_equal(['', '', 'o', '.', 'D', 'D']) def test_kwarg_labels(axis): """Are the legend labels correct when given as kwargs?""" axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], label='foo') axis.plot([2.17, 3.3, 4], [3.25, 4.4, 5], label='bar') axis.plot([1, 2.17, 3.3], [2.5, 3.25, 4.4], label='baz') # make sure it fails before the legend is created pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_labels_equal(['foo', 'bar', 'baz']) axis.legend() pc = LinePlotChecker(axis) pc.assert_labels_equal(['foo', 'bar', 'baz']) def test_legend_labels(axis): """Are the legend labels correct when they are passed into the legend call?""" axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5]) axis.plot([2.17, 3.3, 4], [3.25, 4.4, 5]) axis.plot([1, 2.17, 3.3], [2.5, 3.25, 4.4]) # make sure it fails before the legend is created pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_labels_equal(['foo', 'bar', 'baz']) axis.legend(['foo', 'bar', 'baz']) pc = LinePlotChecker(axis) pc.assert_labels_equal(['foo', 'bar', 'baz']) def test_legend_handles_and_labels(axis): """Are the legend labels correct when they are passed into the legend call with the corresponding handle?""" l0, = axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5]) l1, = axis.plot([2.17, 3.3, 4], [3.25, 4.4, 5]) l2, = axis.plot([1, 2.17, 3.3], [2.5, 3.25, 4.4]) # make sure it fails before the legend is created pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_labels_equal(['foo', 'bar', 'baz']) axis.legend([l0, l1, l2], ['foo', 'bar', 'baz']) pc = LinePlotChecker(axis) pc.assert_labels_equal(['foo', 'bar', 'baz']) def test_alphas(axis): """Are the alphas correct?""" # first just try for a single line using rgb axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color=[0, 1, 1]) pc = LinePlotChecker(axis) pc.assert_alphas_equal([1]) # get the alpha value from rgba axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], color=[0, 1, 1, 0.5]) pc = LinePlotChecker(axis) pc.assert_alphas_equal([1, 0.5]) # specify the alpha value explicitly x = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x.T, y.T, alpha=0.2) pc = LinePlotChecker(axis) pc.assert_alphas_equal([1, 0.5, 0.2, 0.2]) def test_alphas_allclose(axis): """Are the alphas almost correct?""" err = 1e-12 alpha = 0.5 axis.plot([1, 2.17, 3.3, 4], [2.5, 3.25, 4.4, 5], alpha=alpha + err) pc = LinePlotChecker(axis) with pytest.raises(AssertionError): pc.assert_alphas_equal([alpha]) with pytest.raises(AssertionError): pc.assert_alphas_allclose([alpha], rtol=1e-13) pc.assert_alphas_allclose([alpha]) def test_permutations(axis): x = np.linspace(0, 1, 20)[None] * np.ones((3, 20)) y = x ** np.array([1, 2, 3])[:, None] colors = ['r', 'g', 'b'] markers = ['o', 's', 'D'] labels = ['Line A', 'Line B', 'Line C'] # plot lines in a different order from the values for i in [2, 0, 1]: axis.plot(x[i], y[i], color=colors[i], marker=markers[i], label=labels[i], alpha=0.5) axis.legend() # do the permutation based off of colors pc = LinePlotChecker(axis) pc.assert_num_lines(3) pc.find_permutation('colors', colors) pc.assert_x_data_equal(x) pc.assert_y_data_equal(y) pc.assert_colors_equal(colors) pc.assert_markers_equal(markers) pc.assert_labels_equal(labels) pc.assert_alphas_equal([0.5, 0.5, 0.5]) # do the permutation based off of markers pc = LinePlotChecker(axis) pc.assert_num_lines(3) pc.find_permutation('markers', markers) pc.assert_x_data_equal(x) pc.assert_y_data_equal(y) pc.assert_colors_equal(colors) pc.assert_markers_equal(markers) pc.assert_labels_equal(labels) pc.assert_alphas_equal([0.5, 0.5, 0.5]) # do the permutation based off of labels pc = LinePlotChecker(axis) pc.assert_num_lines(3) pc.find_permutation('labels', labels) pc.assert_x_data_equal(x) pc.assert_y_data_equal(y) pc.assert_colors_equal(colors) pc.assert_markers_equal(markers) pc.assert_labels_equal(labels) pc.assert_alphas_equal([0.5, 0.5, 0.5]) with pytest.raises(AssertionError): pc.find_permutation('labels', labels[:-1]) with pytest.raises(AssertionError): pc.find_permutation('labels', [x + 'a' for x in labels]) PKvQL;Glz}0}0%plotchecker/tests/test_scatterplot.pyimport numpy as np import pytest from .. import ScatterPlotChecker, InvalidPlotError def test_empty_plot(axis): """Is an error thrown when there is nothing plotted?""" with pytest.raises(InvalidPlotError): ScatterPlotChecker(axis) def test_bad_plot_lines(axis): """Is an error thrown when there are lines rather than points plotted?""" # first just try for a single set of points x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0) with pytest.raises(InvalidPlotError): ScatterPlotChecker(axis) def test_bad_plot_no_markers(axis): """Is an error thrown when there are no markers plotted?""" # first just try for a single set of points x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0, linestyle='', marker='') with pytest.raises(InvalidPlotError): ScatterPlotChecker(axis) def test_num_points(axis): """Are the number of points correct?""" # first just try for a single set of points x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0, 'o') pc = ScatterPlotChecker(axis) pc.assert_num_points(4) # now plot another line x1 = [2, 3.17, 4.3, 5, 6] y1 = [1.5, 2.25, 3.4, 4, 7] axis.plot(x1, y1, 'o') pc = ScatterPlotChecker(axis) pc.assert_num_points(9) # do it with scatter x2 = [4.9, 0, 1] y2 = [10, 20, 30] axis.scatter(x2, y2) pc = ScatterPlotChecker(axis) pc.assert_num_points(12) # plot some more things with scatter x3 = [2, 3.17, 4.3, 12] y3 = [1.5, 2.25, 3.4, 23] axis.scatter(x3, y3) pc = ScatterPlotChecker(axis) pc.assert_num_points(16) # and now two more lines (six points), plotted at the same time x4 = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y4 = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x4.T, y4.T, 'o') pc = ScatterPlotChecker(axis) pc.assert_num_points(22) with pytest.raises(AssertionError): pc.assert_num_points(16) def test_data(axis): """Are the x and y values correct?""" # first just try for a single set of points x0 = [1, 2.17, 3.3, 4] y0 = [2.5, 3.25, 4.4, 5] axis.plot(x0, y0, 'o') pc = ScatterPlotChecker(axis) pc.assert_x_data_equal(x0) pc.assert_y_data_equal(y0) # now plot another line x1 = [2, 3.17, 4.3, 5, 6] y1 = [1.5, 2.25, 3.4, 4, 7] axis.plot(x1, y1, 'o') pc = ScatterPlotChecker(axis) pc.assert_x_data_equal(np.concatenate([x0, x1])) pc.assert_y_data_equal(np.concatenate([y0, y1])) # do it with scatter x2 = [4.9, 0, 1] y2 = [10, 20, 30] axis.scatter(x2, y2) pc = ScatterPlotChecker(axis) pc.assert_x_data_equal(np.concatenate([x0, x1, x2])) pc.assert_y_data_equal(np.concatenate([y0, y1, y2])) # plot some more things with scatter x3 = [2, 3.17, 4.3, 12] y3 = [1.5, 2.25, 3.4, 23] axis.scatter(x3, y3) pc = ScatterPlotChecker(axis) pc.assert_x_data_equal(np.concatenate([x0, x1, x2, x3])) pc.assert_y_data_equal(np.concatenate([y0, y1, y2, y3])) # and now two more lines (six points), plotted at the same time x4 = np.array([[4.3, 5, 6], [5.3, 6, 7]]) y4 = np.array([[3.4, 4, 7], [10.2, 9, 8]]) axis.plot(x4.T, y4.T, 'o') pc = ScatterPlotChecker(axis) pc.assert_x_data_equal(np.concatenate([x0, x1, x4.ravel(), x2, x3])) pc.assert_y_data_equal(np.concatenate([y0, y1, y4.ravel(), y2, y3])) def test_data_allclose(axis): """Are the x and y values almost correct?""" err = 1e-12 x0 = np.array([1, 2.17, 3.3, 4]) y0 = np.array([2.5, 3.25, 4.4, 5]) axis.plot(x0 + err, y0 + err, 'o') pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_x_data_equal(x0) with pytest.raises(AssertionError): pc.assert_y_data_equal(y0) with pytest.raises(AssertionError): pc.assert_x_data_allclose(x0, rtol=1e-13) with pytest.raises(AssertionError): pc.assert_y_data_allclose(y0, rtol=1e-13) pc.assert_x_data_allclose(x0) pc.assert_y_data_allclose(y0) def test_colors(axis): x = np.random.rand(10) y = np.random.rand(10) c = np.random.rand(10, 3) for i in range(5): axis.plot(x[i], y[i], 'o', color=c[i]) for i in range(5, 10): axis.scatter(x[i], y[i], c=c[i]) pc = ScatterPlotChecker(axis) pc.assert_colors_equal(c) def test_colors_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) c = np.round(np.random.rand(10, 3), decimals=3) c[c < 1e-3] = 1e-3 for i in range(5): axis.plot(x[i], y[i], 'o', color=c[i] + err) for i in range(5, 10): axis.scatter(x[i], y[i], c=c[i] + err) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_colors_equal(c) with pytest.raises(AssertionError): pc.assert_colors_allclose(c, rtol=1e-13) pc.assert_colors_allclose(c) def test_alphas(axis): x = np.random.rand(10) y = np.random.rand(10) alphas = np.round(np.random.rand(10), decimals=3) alphas[alphas < 1e-3] = 1e-3 for i in range(5): axis.plot(x[i], y[i], 'o', alpha=alphas[i]) for i in range(5, 10): axis.scatter(x[i], y[i], alpha=alphas[i]) pc = ScatterPlotChecker(axis) pc.assert_alphas_equal(alphas) def test_alphas_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) alphas = np.round(np.random.rand(10), decimals=3) alphas[alphas < 1e-3] = 1e-3 for i in range(5): axis.plot(x[i], y[i], 'o', alpha=alphas[i] + err) for i in range(5, 10): axis.scatter(x[i], y[i], alpha=alphas[i] + err) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_alphas_equal(alphas) with pytest.raises(AssertionError): pc.assert_alphas_allclose(alphas, rtol=1e-13) pc.assert_alphas_allclose(alphas) def test_edgecolors(axis): x = np.random.rand(10) y = np.random.rand(10) c = np.random.rand(10, 3) for i in range(5): axis.plot(x[i], y[i], 'o', markeredgecolor=list(c[i])) for i in range(5, 10): axis.scatter(x[i], y[i], edgecolor=list(c[i])) pc = ScatterPlotChecker(axis) pc.assert_edgecolors_equal(c) def test_edgecolors_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) c = np.round(np.random.rand(10, 3), decimals=3) c[c < 1e-3] = 1e-3 for i in range(5): axis.plot(x[i], y[i], 'o', markeredgecolor=list(c[i] + err)) for i in range(5, 10): axis.scatter(x[i], y[i], edgecolor=list(c[i] + err)) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_edgecolors_equal(c) with pytest.raises(AssertionError): pc.assert_edgecolors_allclose(c, rtol=1e-13) pc.assert_edgecolors_allclose(c) def test_edgewidths(axis): x = np.random.rand(10) y = np.random.rand(10) w = np.arange(1, 11) for i in range(5): axis.plot(x[i], y[i], 'o', markeredgewidth=w[i]) for i in range(5, 10): axis.scatter(x[i], y[i], linewidth=w[i]) pc = ScatterPlotChecker(axis) pc.assert_edgewidths_equal(w) def test_edgewidths_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) edgewidths = np.arange(1, 11) for i in range(5): axis.plot(x[i], y[i], 'o', markeredgewidth=edgewidths[i] + err) for i in range(5, 10): axis.scatter(x[i], y[i], linewidth=edgewidths[i] + err) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_edgewidths_equal(edgewidths) with pytest.raises(AssertionError): pc.assert_edgewidths_allclose(edgewidths, rtol=1e-13) pc.assert_edgewidths_allclose(edgewidths) def test_sizes(axis): x = np.random.rand(10) y = np.random.rand(10) sizes = np.arange(1, 11).astype('float') for i in range(5): axis.plot(x[i], y[i], 'o', markersize=sizes[i]) for i in range(5, 10): axis.scatter(x[i], y[i], s=sizes[i] ** 2) pc = ScatterPlotChecker(axis) pc.assert_sizes_equal(sizes ** 2) def test_sizes_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) sizes = np.arange(1, 11) for i in range(5): axis.plot(x[i], y[i], 'o', markersize=sizes[i] + err) for i in range(5, 10): axis.scatter(x[i], y[i], s=(sizes[i] ** 2) + err) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_sizes_equal(sizes ** 2) with pytest.raises(AssertionError): pc.assert_sizes_allclose(sizes ** 2, rtol=1e-13) pc.assert_sizes_allclose(sizes ** 2) def test_markersizes(axis): x = np.random.rand(10) y = np.random.rand(10) markersizes = np.arange(1, 11).astype('float') for i in range(5): axis.plot(x[i], y[i], 'o', markersize=markersizes[i]) for i in range(5, 10): axis.scatter(x[i], y[i], s=markersizes[i] ** 2) pc = ScatterPlotChecker(axis) pc.assert_markersizes_equal(markersizes) def test_markersizes_allclose(axis): err = 1e-12 x = np.random.rand(10) y = np.random.rand(10) markersizes = np.arange(1, 11) for i in range(5): axis.plot(x[i], y[i], 'o', markersize=markersizes[i] + err) for i in range(5, 10): axis.scatter(x[i], y[i], s=(markersizes[i] ** 2) + err) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_markersizes_equal(markersizes) with pytest.raises(AssertionError): pc.assert_markersizes_allclose(markersizes, rtol=1e-13) pc.assert_markersizes_allclose(markersizes) @pytest.mark.xfail(reason="markers are unrecoverable from scatter plots") def test_markers(axis): x = np.random.rand(10) y = np.random.rand(10) m = ['o', '.', 's', 'D', 'v', '^', '<', '>', 'H', '+'] for i in range(5): axis.plot(x[i], y[i], marker=m[i]) for i in range(5, 10): axis.scatter(x[i], y[i], marker=m[i]) pc = ScatterPlotChecker(axis) pc.assert_markers_equal(m) def test_example_1(axes): x = np.random.rand(20) y = np.random.rand(20) # create a scatter plot with plot axes[0].plot(x, y, 'o', color='b', ms=5, alpha=0.8) # create a scatter plot with scatter axes[1].scatter(x, y, s=25, c='b', alpha=0.8) # create a scatter plot with plot *and* scatter! axes[2].plot(x[:10], y[:10], 'o', color='b', ms=5, alpha=0.8) axes[2].scatter(x[10:], y[10:], s=25, c='b', alpha=0.8) for ax in axes: pc = ScatterPlotChecker(ax) pc.assert_x_data_equal(x) pc.assert_y_data_equal(y) pc.assert_colors_equal('b') pc.assert_edgecolors_equal('b') pc.assert_edgewidths_equal(1) pc.assert_sizes_equal(25) pc.assert_markersizes_equal(5) pc.assert_alphas_equal(0.8) def test_example_2(axes): x = np.random.rand(20) y = np.random.rand(20) # choose some random colors and sizes colors = np.random.rand(20, 4) sizes = np.random.rand(20) * 5 # create a scatter plot with plot, using a loop for i in range(20): axes[0].plot(x[i], y[i], 'o', color=colors[i], ms=sizes[i]) # create a scatter plot with scatter axes[1].scatter(x, y, c=colors, s=sizes ** 2) # create a scatter plot with scatter, using a loop for i in range(20): axes[2].scatter(x[i], y[i], c=colors[i], s=sizes[i] ** 2) for ax in axes: pc = ScatterPlotChecker(ax) pc.assert_x_data_equal(x) pc.assert_y_data_equal(y) pc.assert_colors_equal(colors) pc.assert_edgecolors_equal(colors) pc.assert_edgewidths_equal(1) pc.assert_sizes_equal(sizes ** 2) pc.assert_markersizes_equal(sizes) pc.assert_alphas_equal(colors[:, 3]) def test_bad_colors_and_sizes(axis): x = np.random.rand(10) y = np.random.rand(10) c = np.random.rand(10, 3) s = np.random.rand(10) * 5 for i in range(10): axis.scatter(x[i], y[i], c=c, s=s) pc = ScatterPlotChecker(axis) with pytest.raises(AssertionError): pc.assert_colors_equal(c) with pytest.raises(AssertionError): pc.assert_sizes_equal(s) pc.assert_colors_equal(c[[0]]) pc.assert_sizes_equal(s[0]) PKTFwR<3#plotchecker-0.2.0.dist-info/LICENSECopyright (c) 2015, Jessica B. Hamrick All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of plotchecker nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PK!HxyUb!plotchecker-0.2.0.dist-info/WHEEL HM K-*ϳR03rOK-J,/RH,Q034 /, (-JLR()*M ILR(4KM̫#DPK!H $plotchecker-0.2.0.dist-info/METADATAVMs8 W!'QdOdL&2`DjIʶ>P-~Deښx%ײKTA\9~/ۦkLx Dt&/f։@>h3 Y6BaouLfƐKZqyBs&KrZ=Ҋç??|NΚPX7ZIq_t@T{ڔ&(%f39;krdHLTxyŇw⬮]緗gNVu%ͼAl"MZ+~}kga)s"ҙ{MI>H5ڑ?>Li}Uy\eZprҩu6.)58}w+TWf rYPO9Kn `w8y((0'L_&9.:֝ Mmxd;e$?j 3(M.0$ 76 aǃ^XSTQzVX  -JKծ&TbPrJ(Rv, qq} 2M; /v&CRxc0t>hR=ΝmLXHv]Q ^FF bg+ةr("@ s`3H>Δ2vdz\cu:&D+Yz_9j## n { x'B]Ƭ,d!؄垇)|ma{ x-ī.CG}=7NG9 OA3B`ٜF%j<& oT& H,io^t ȗwV>Ш1og }-E N˞M!ԯ’%hpO ivro_eDM>uk/q\c1km:"ԌD#"rpt{&I;7|*fwȲ> Zi"0$V"3a{Ӟ5QYC#w 2`dg7PK!H+)"plotchecker-0.2.0.dist-info/RECORD}K: wX!-rQaC F@sJؽI%}+Gݥ9J/EUtqhS鞛tǬ eS-0/d^h_#7uG$ KrdLY%"'IOMqvvnP (Adu'(=np699D(T2ӏ .Gox;#T6 ZCޞmeBlm۷R`#=ǵMumse}vVw:?A))4hj9%mGw,,`H$5eUk=.:cs[^`7Z3 )0wb*A PKQL+B--plotchecker/__init__.pyPKQLRQ5HHbplotchecker/_version.pyPKQLQ7Q7plotchecker/barplot.pyPKvQLܧ//d9plotchecker/base.pyPKQL᜹fQfQXiplotchecker/lineplot.pyPKQLM@GGplotchecker/scatterplot.pyPKQLplotchecker/tests/__init__.pyPKQL}ыLplotchecker/tests/conftest.pyPKvQL-b!!!plotchecker/tests/test_barplot.pyPKQL&plotchecker/tests/test_base.pyPKvQLEE"9plotchecker/tests/test_lineplot.pyPKvQL;Glz}0}0%plotchecker/tests/test_scatterplot.pyPKTFwR<3#plotchecker-0.2.0.dist-info/LICENSEPK!HxyUb!plotchecker-0.2.0.dist-info/WHEELPK!H $Nplotchecker-0.2.0.dist-info/METADATAPK!H+)"lplotchecker-0.2.0.dist-info/RECORDPK