# Buggy code
def __init__(
    self,
    data,
    *,
    rgb=None,
    is_pyramid=None,
    colormap="gray",
    contrast_limits=None,
    interpolation="nearest",
    rendering="mip",
    name=None,
    metadata=None,
    scale=None,
    translate=None,
    opacity=1,
    blending="translucent",
    visible=True,
):
    ndim, rgb, is_pyramid, data_pyramid = get_pyramid_and_rgb(
        data, pyramid=is_pyramid, rgb=rgb
    )

    super().__init__(
        ndim,
        name=name,
        metadata=metadata,
        scale=scale,
        translate=translate,
        opacity=opacity,
        blending=blending,
        visible=visible,
    )

    self.events.add(
        contrast_limits=Event,
        colormap=Event,
        interpolation=Event,
        rendering=Event,
    )

    # Set data
    self.is_pyramid = is_pyramid
    self.rgb = rgb
    self._data = data
    self._data_pyramid = data_pyramid
    self._top_left = np.zeros(ndim, dtype=int)
    if self.is_pyramid:
        self._data_level = len(data_pyramid) - 1
    else:
        self._data_level = 0

    # Intitialize image views and thumbnails with zeros
    if self.rgb:
        self._data_view = np.zeros((1,) * self.dims.ndisplay + (self.shape[-1],))
    else:
        self._data_view = np.zeros((1,) * self.dims.ndisplay)
    self._data_thumbnail = self._data_view

    # Set contrast_limits and colormaps
    self._colormap_name = ""
    self._contrast_limits_msg = ""
    if contrast_limits is None:
        if self.is_pyramid:
            input_data = self._data_pyramid[-1]
        else:
            input_data = self.data
        self._contrast_limits_range = calc_data_range(input_data)
    else:
        self._contrast_limits_range = contrast_limits
    self._contrast_limits = copy(self._contrast_limits_range)
    self.colormap = colormap
    self.contrast_limits = self._contrast_limits
    self.interpolation = interpolation
    self.rendering = rendering

    # Trigger generation of view slice and thumbnail
    self._update_dims()


# Traceback (ValueError)
regions
<xarray.Regions 'array-baa123768d7ef2a6d2cdfa885e8f3eaa' (x_region: 31725, y_region: 51669)>
array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int16)
Dimensions without coordinates: x_region, y_region
Attributes:
assay:             osmFISH
authors:           ['Simone Codeluppi', 'Lars E. Borm', 'Amit Zeisel', 'G...
organism:          mouse
publication_name:  Spatial organization of the somatosensory cortex revea...
publication_url:   https://www.nature.com/articles/s41592-018-0175-z
sample_type:       somatosensory cortex
year:              2018

pyramid = tuple(pyramid_gaussian(regions), multichannel=False)

[i.shape for i in pyramid]
[(31725, 51669),
(15863, 25835),
(7932, 12918),
(3966, 6459),
(1983, 3230),
(992, 1615),
(496, 808),
(248, 404),
(124, 202),
(62, 101),
(31, 51),
(16, 26),
(8, 13),
(4, 7),
(2, 4),
(1, 2),
(1, 1)]

viewer = napari.Viewer()

viewer.add_image(np.asarray(pyramid), is_pyramid=True)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-665dfea0cb05> in <module>
----> 1 viewer.add_image(np.asarray(pyramid), is_pyramid=True)

/usr/local/lib/python3.7/site-packages/napari/components/viewer_model.py in add_image(self, data, rgb, is_pyramid, colormap, contrast_limits, interpolation, rendering, name, metadata, scale, translate, opacity, blending, visible)
426             opacity=opacity,
427             blending=blending,
--> 428             visible=visible,
429         )
430         self.add_layer(layer)

/usr/local/lib/python3.7/site-packages/napari/layers/image/image.py in __init__(self, data, rgb, is_pyramid, colormap, contrast_limits, interpolation, rendering, name, metadata, scale, translate, opacity, blending, visible)
185             else:
186                 input_data = self.data
--> 187             self._contrast_limits_range = calc_data_range(input_data)
188         else:
189             self._contrast_limits_range = contrast_limits

/usr/local/lib/python3.7/site-packages/napari/util/misc.py in calc_data_range(data)
268         reduced_data = data
269
--> 270     min_val = reduced_data.min()
271     max_val = reduced_data.max()
272

/usr/local/lib/python3.7/site-packages/numpy/core/_methods.py in _amin(a, axis, out, keepdims, initial)
30 def _amin(a, axis=None, out=None, keepdims=False,
31           initial=_NoValue):
---> 32     return umr_minimum(a, axis, None, out, keepdims, initial)
33
34 def _sum(a, axis=None, dtype=None, out=None, keepdims=False,

ValueError: operands could not be broadcast together with shapes (31725,51669) (15863,25835)

# Fixed code
def __init__(
    self,
    data,
    *,
    rgb=None,
    is_pyramid=None,
    colormap="gray",
    contrast_limits=None,
    interpolation="nearest",
    rendering="mip",
    name=None,
    metadata=None,
    scale=None,
    translate=None,
    opacity=1,
    blending="translucent",
    visible=True,
):
    if isinstance(data, types.GeneratorType):
        data = list(data)

    ndim, rgb, is_pyramid, data_pyramid = get_pyramid_and_rgb(
        data, pyramid=is_pyramid, rgb=rgb
    )

    super().__init__(
        ndim,
        name=name,
        metadata=metadata,
        scale=scale,
        translate=translate,
        opacity=opacity,
        blending=blending,
        visible=visible,
    )

    self.events.add(
        contrast_limits=Event,
        colormap=Event,
        interpolation=Event,
        rendering=Event,
    )

    # Set data
    self.is_pyramid = is_pyramid
    self.rgb = rgb
    self._data = data
    self._data_pyramid = data_pyramid
    self._top_left = np.zeros(ndim, dtype=int)
    if self.is_pyramid:
        self._data_level = len(data_pyramid) - 1
    else:
        self._data_level = 0

    # Intitialize image views and thumbnails with zeros
    if self.rgb:
        self._data_view = np.zeros((1,) * self.dims.ndisplay + (self.shape[-1],))
    else:
        self._data_view = np.zeros((1,) * self.dims.ndisplay)
    self._data_thumbnail = self._data_view

    # Set contrast_limits and colormaps
    self._colormap_name = ""
    self._contrast_limits_msg = ""
    if contrast_limits is None:
        if self.is_pyramid:
            input_data = self._data_pyramid[-1]
        else:
            input_data = self.data
        self._contrast_limits_range = calc_data_range(input_data)
    else:
        self._contrast_limits_range = contrast_limits
    self._contrast_limits = copy(self._contrast_limits_range)
    self.colormap = colormap
    self.contrast_limits = self._contrast_limits
    self.interpolation = interpolation
    self.rendering = rendering

    # Trigger generation of view slice and thumbnail
    self._update_dims()