Skip to content

Surprising exception when plotting a boolean array #474

@jokasimr

Description

@jokasimr

This code produces the figure below:

m = sc.zeros(sizes={'x': 10, 'y': 10}, dtype='bool')
m['x', 0]['y', 0] = True
m.plot()
Image

But this code raises an exception:

m = sc.zeros(sizes={'x': 10, 'y': 10}, dtype='bool')
m['x', 0]['y', 0] = False  # <--- changed from True to False
m.plot()
# DTypeError: 'subtract' does not support dtypes 'bool', 'float64',
See full error message
---------------------------------------------------------------------------
DTypeError                                Traceback (most recent call last)
Cell In[60], line 3
      1 m = sc.zeros(sizes={'x': 10, 'y': 10}, dtype='bool')
      2 m['x', 0]['y', 0] = False
----> 3 m.plot()

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/scipp/plotting.py:14, in plot(*args, **kwargs)
8 """
9 Wrapper function to plot data.
10 See https://scipp.github.io/plopp/ for details.
11 """
12 from plopp import plot as _plot
---> 14 return _plot(*args, **kwargs)

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/plotting/plot.py:123, in plot(obj, aspect, cbar, coords, errorbars, figsize, grid, ignore_size, mask_color, norm, scale, title, vmin, vmax, legend, **kwargs)
121 if len(nodes) > 1:
122 raise_multiple_inputs_for_2d_plot_error(origin='plot')
--> 123 return imagefigure(*nodes, cbar=cbar, **common_args)
124 else:
125 raise ValueError(
126 'The plot function can only plot 1d and 2d data, got input '
127 f'with {ndim} dimensions'
128 )

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/figures.py:42, in imagefigure(*nodes, **kwargs)
34 def imagefigure(*nodes: Node, **kwargs) -> FigureLike:
35 view_maker = partial(
36 GraphicalView,
37 dims={'y': None, 'x': None},
(...)
40 colormapper=True,
41 )
---> 42 return backends.get(group='2d', name='figure')(view_maker, *nodes, **kwargs)

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/backends/matplotlib/figure.py:195, in Figure(*args, **kwargs)
192 from .utils import is_interactive_backend
194 if is_interactive_backend():
--> 195 return InteractiveFigure(*args, **kwargs)
196 else:
197 return StaticFigure(*args, **kwargs)

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/backends/matplotlib/figure.py:136, in InteractiveFigure.init(self, View, *args, **kwargs)
133 def init(self, View, *args, **kwargs):
134 from ...widgets import HBar, VBar, make_toolbar_canvas2d
--> 136 self.init_figure(View, *args, **kwargs)
137 self.interactive = True
138 self.toolbar = make_toolbar_canvas2d(view=self.view)

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/backends/matplotlib/figure.py:24, in MplBaseFig.init_figure(self, View, *args, **kwargs)
23 def init_figure(self, View, *args, **kwargs):
---> 24 self.view = View(*args, **kwargs)
25 # Saving the following is necessary for making copies of the figure
26 self._view_maker = View

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/graphicalview.py:114, in GraphicalView.init(self, dims, canvas_maker, artist_maker, colormapper, cmap, mask_cmap, cbar, norm, vmin, vmax, scale, aspect, grid, title, figsize, format, legend, camera, autoscale, ax, cax, *nodes, **kwargs)
112 if len(self._dims) == 1:
113 self.canvas.yscale = norm
--> 114 self.render()

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/graphicalview.py:250, in GraphicalView.render(self)
248 self._autoscale = False
249 super().render()
--> 250 self.fit_to_data()
251 self.canvas.draw()
252 self._autoscale = old

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/graphicalview.py:235, in GraphicalView.fit_to_data(self)
233 return
234 if self.colormapper is not None:
--> 235 self.colormapper.autoscale()
236 self.autoscale()

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/colormapper.py:174, in ColorMapper.autoscale(self)
169 def autoscale(self):
170 """
171 Re-compute the global min and max range of values by iterating over all the
172 artists and adjust the limits.
173 """
--> 174 limits = [
175 fix_empty_range(find_limits(artist._data, scale=self.norm))
176 for artist in self.artists.values()
177 ]
178 vmin = reduce(min, [v[0] for v in limits])
179 vmax = reduce(max, [v[1] for v in limits])

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/graphics/colormapper.py:175, in (.0)
169 def autoscale(self):
170 """
171 Re-compute the global min and max range of values by iterating over all the
172 artists and adjust the limits.
173 """
174 limits = [
--> 175 fix_empty_range(find_limits(artist._data, scale=self.norm))
176 for artist in self.artists.values()
177 ]
178 vmin = reduce(min, [v[0] for v in limits])
179 vmax = reduce(max, [v[1] for v in limits])

File ~/.local/share/mamba/envs/esssans/lib/python3.10/site-packages/plopp/core/limits.py:111, in fix_empty_range(lims)
108 else:
109 # We decompose value and unit to avoid operation exceptions when unit=None.
110 dx = sc.scalar(0.5 * abs(lims[0].value), unit=lims[0].unit)
--> 111 return (lims[0] - dx, lims[1] + dx)

DTypeError: 'subtract' does not support dtypes 'bool', 'float64',

The following code runs fine and produces the expected figure:

m = sc.zeros(sizes={'x': 10, 'y': 10})  # <--- dtype argument removed
m['x', 0]['y', 0] = False
m.plot()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions