diff --git a/src/tikzplotlib/_axes.py b/src/tikzplotlib/_axes.py index fa84db2f..be881eb3 100644 --- a/src/tikzplotlib/_axes.py +++ b/src/tikzplotlib/_axes.py @@ -17,24 +17,26 @@ def __init__(self, data, obj): # noqa: C901 """Returns the PGFPlots code for an axis environment.""" self.content = [] - # Are we dealing with an axis that hosts a colorbar? Skip then, those are - # treated implicitily by the associated axis. - self.is_colorbar = _is_colorbar_heuristic(obj) - if self.is_colorbar: - return - # instantiation self.nsubplots = 1 self.subplot_index = 0 self.is_subplot = False - if isinstance(obj, mpl.axes.Subplot): + self.axis_options = [] + + # Are we dealing with an axis that hosts a colorbar? Skip then, those are + # treated implicitily by the associated axis. + self.is_colorbar = _is_colorbar_heuristic(obj) + + if isinstance(obj, mpl.axes.Subplot) and not self.is_colorbar: self._subplot(obj, data) self.axis_options = [] + self.is_visible = obj.get_visible() # check if axes need to be displayed at all - if not obj.axison: + # unassociated colorbars should have hidden axes; colorbars associated to axes will be printed by the axis + if not (obj.axison and self.is_visible) or self.is_colorbar: self.axis_options.append("hide x axis") self.axis_options.append("hide y axis") @@ -153,10 +155,9 @@ def __init__(self, data, obj): # noqa: C901 if col != "white": self.axis_options.append(f"axis background/.style={{fill={col}}}") - # find color bar - colorbar = _find_associated_colorbar(obj) - if colorbar: - self._colorbar(colorbar, data) + self.colorbar = _find_associated_colorbar(obj) + if self.colorbar: + self._colorbar(self.colorbar, data) if self.is_subplot: self.content.append("\n\\nextgroupplot") @@ -800,7 +801,7 @@ def _handle_listed_color_map(cmap, data): if cmap.N is None or cmap.N == len(cmap.colors): colors = [ f"rgb({k}{unit})=({rgb[0]:{ff}},{rgb[1]:{ff}},{rgb[2]:{ff}})" - for k, rgb in enumerate(cmap.colors) + for k, rgb in enumerate(map(mpl.colors.to_rgb, cmap.colors)) ] else: reps = int(float(cmap.N) / len(cmap.colors) - 0.5) + 1 @@ -858,6 +859,12 @@ def _find_associated_colorbar(obj): next axis environment, and see if it is de facto a color bar; if yes, return the color bar object. """ + try: + cbar = obj._colorbar + if cbar is not None: + return cbar + except AttributeError: + pass for child in obj.get_children(): try: cbar = child.colorbar diff --git a/src/tikzplotlib/_save.py b/src/tikzplotlib/_save.py index d89cadfa..b55b12ed 100644 --- a/src/tikzplotlib/_save.py +++ b/src/tikzplotlib/_save.py @@ -328,6 +328,9 @@ def _recurse(data, obj): """Iterates over all children of the current object, gathers the contents contributing to the resulting PGFPlots file, and returns those. """ + # bound_colorbars holds colorbars that are associated to axes + # we don't add axes from colorbars if they come after the axis to which they were associated + bound_colorbars = [] content = _ContentManager() for child in obj.get_children(): # Some patches are Spines, too; skip those entirely. @@ -338,9 +341,12 @@ def _recurse(data, obj): if isinstance(child, mpl.axes.Axes): ax = _axes.Axes(data, child) - if ax.is_colorbar: + if ax.is_colorbar and any(ax.colorbar is cb for cb in bound_colorbars): continue + if not ax.is_colorbar and ax.colorbar is not None: + bound_colorbars.append(ax.colorbar) + # add extra axis options if data["extra axis options [base]"]: ax.axis_options.extend(data["extra axis options [base]"]) @@ -348,8 +354,12 @@ def _recurse(data, obj): data["current mpl axes obj"] = child data["current axes"] = ax - # Run through the child objects, gather the content. - data, children_content = _recurse(data, child) + if ax.is_visible and not ax.is_colorbar: + # Run through the child objects, gather the content. + data, children_content = _recurse(data, child) + else: + # we may still display the colorbar + children_content = [] # populate content and add axis environment if desired if data["add axis environment"]: diff --git a/tests/test_colorbars.py b/tests/test_colorbars.py index 3d384f1f..8fb7e730 100644 --- a/tests/test_colorbars.py +++ b/tests/test_colorbars.py @@ -4,7 +4,7 @@ def plot(): # Make a figure and axes with dimensions as desired. - fig, ax = plt.subplots(3) + fig, ax = plt.subplots(4) # Set the colormap and norm to correspond to the data for which the colorbar will be # used. @@ -69,6 +69,16 @@ def plot(): ) cb3.set_label("Custom extension lengths, some other units") + # Set the colormap and norm to correspond to the data for which the colorbar will be + # used. This time attach the colorbar to axes. + cmap = mpl.cm.cool + norm = mpl.colors.Normalize(vmin=-5, vmax=10) + + img = ax[3].imshow([[0, 1]], cmap=cmap) + ax[3].set_visible(False) + cax = fig.add_axes([0.1, 1, 0.8, 0.1]) + cb4 = fig.colorbar(img, cax=cax, orientation="horizontal", label="Some Units") + return fig diff --git a/tests/test_colorbars_reference.tex b/tests/test_colorbars_reference.tex index dec2184e..304db4e6 100644 --- a/tests/test_colorbars_reference.tex +++ b/tests/test_colorbars_reference.tex @@ -1,3 +1,92 @@ \begin{tikzpicture} +\definecolor{darkgray176}{RGB}{176,176,176} + +\begin{axis}[ +colorbar horizontal, +colormap={mymap}{[1pt] + rgb(0pt)=(0,1,1); + rgb(1pt)=(1,0,1) +}, +hide x axis, +hide y axis, +point meta max=10, +point meta min=-5, +tick align=outside, +tick pos=left, +x grid style={darkgray176}, +xlabel={Some Units}, +xmin=-5, xmax=10, +xtick style={color=black}, +ymin=0, ymax=1 +] +\end{axis} + +\begin{axis}[ +colorbar horizontal, +colormap={mymap}{[1pt] + rgb(0pt)=(1,0,0); + rgb(1pt)=(0,0.5,0); + rgb(2pt)=(0,0,1); + rgb(3pt)=(0,0.75,0.75) +}, +hide x axis, +hide y axis, +point meta max=8, +point meta min=1, +tick align=outside, +tick pos=left, +x grid style={darkgray176}, +xlabel={Discrete intervals, some other units}, +xmin=1, xmax=8, +xtick style={color=black}, +ymin=0, ymax=1 +] +\end{axis} + +\begin{axis}[ +colorbar horizontal, +colormap={mymap}{[1pt] + rgb(0pt)=(0,0.4,1); + rgb(1pt)=(0,0.8,1); + rgb(2pt)=(1,0.8,0); + rgb(3pt)=(1,0.4,0) +}, +hide x axis, +hide y axis, +point meta max=1, +point meta min=-1, +tick align=outside, +tick pos=left, +x grid style={darkgray176}, +xlabel={Custom extension lengths, some other units}, +xmin=-1, xmax=1, +xtick style={color=black}, +ymin=0, ymax=1 +] +\end{axis} + +\begin{groupplot}[group style={group size=1 by 4}] +\nextgroupplot[ +colorbar horizontal, +colormap={mymap}{[1pt] + rgb(0pt)=(0,1,1); + rgb(1pt)=(1,0,1) +}, +hide x axis, +hide y axis, +point meta max=1, +point meta min=0, +tick align=outside, +tick pos=left, +x grid style={darkgray176}, +xmin=-0.5, xmax=1.5, +xtick style={color=black}, +y dir=reverse, +y grid style={darkgray176}, +ymin=-0.5, ymax=0.5, +ytick style={color=black} +] +\end{groupplot} + \end{tikzpicture}