Repository: silx-kit/silx
Issue: Issue with histogram item and stats widget

There is apparently an issue with histogram items and the Stats widget.

To reproduce:
```
from silx import sx                                                     
w = sx.plot()                                                           
w.addHistogram((1, 2, 3), (1, 2, 3))  
```
Then click on "Options"

```
Traceback (most recent call last):
  File "silx/gui/plot/PlotWindow.py", line 466, in _customControlButtonMenu
    controlMenu.addAction(self.getStatsAction())
  File "silx/gui/plot/PlotWindow.py", line 655, in getStatsAction
    self._statsAction.setChecked(self.getStatsWidget().parent().isVisible())
  File "silx/gui/plot/PlotWindow.py", line 585, in getStatsWidget
    statsWidget = BasicStatsWidget(parent=self, plot=self)
  File "silx/gui/plot/StatsWidget.py", line 1285, in __init__
    stats=DEFAULT_STATS)
  File "silx/gui/plot/StatsWidget.py", line 1168, in __init__
    self.setStats(stats)
  File "silx/gui/plot/StatsWidget.py", line 1211, in setStats
    return self._getStatsTable().setStats(statsHandler=statsHandler)
  File "silx/gui/plot/StatsWidget.py", line 635, in setStats
    self._updateItemObserve()
  File "silx/gui/plot/StatsWidget.py", line 666, in _updateItemObserve
    self._addItem(item)
  File "silx/gui/plot/StatsWidget.py", line 817, in _addItem
    self._updateStats(item, data_changed=True)
  File "silx/gui/plot/StatsWidget.py", line 873, in _updateStats
    data_changed=data_changed, roi_changed=roi_changed)
  File "silx/gui/plot/stats/statshandler.py", line 199, in calculate
    data_changed=data_changed, roi_changed=roi_changed)
  File "silx/gui/plot/stats/stats.py", line 104, in calculate
    roi=roi)
  File "silx/gui/plot/stats/stats.py", line 423, in clipData
    self.values = numpy.ma.array(yData, mask=mask)
  File "numpy/ma/core.py", line 6562, in array
    ndmin=ndmin, shrink=shrink, order=order)
  File "numpy/ma/core.py", line 2909, in __new__
    raise MaskError(msg % (nd, nm))
numpy.ma.core.MaskError: Mask and data not compatible: data size is 3, mask size is 6.
```

Changed files:
silx/gui/plot/stats/stats.py

diff --git a/silx/gui/plot/stats/stats.py b/silx/gui/plot/stats/stats.py
index 755b18561..f91c25ede 100644
--- a/silx/gui/plot/stats/stats.py
+++ b/silx/gui/plot/stats/stats.py
@@ -1,7 +1,7 @@
 # coding: utf-8
 # /*##########################################################################
 #
-# Copyright (c) 2017-2020 European Synchrotron Radiation Facility
+# Copyright (c) 2017-2021 European Synchrotron Radiation Facility
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -193,19 +193,6 @@ class _StatsContext(object):
 
         self.clipData(item, plot, onlimits, roi=roi)
 
-    def clipData(self, item, plot, onlimits, roi):
-        """
-        Clip the data to the current mask to have accurate statistics
-
-        :param item: item for whiwh we want to clip data
-        :param plot: plot containing the item
-        :param onlimits: do we want to apply statistic only on
-                         visible data.
-        :param roi: Region of interest for computing the statistics.
-        :type roi: Union[None,:class:`_RegionOfInterestBase`]
-        """
-        raise NotImplementedError()
-
     def clear_mask(self):
         """
         Remove the mask to force recomputation of it on next iteration
@@ -232,7 +219,8 @@ class _StatsContext(object):
         raise NotImplementedError("Base class")
 
     def clipData(self, item, plot, onlimits, roi):
-        """
+        """Clip the data to the current mask to have accurate statistics
+
         Function called before computing each statistics associated to this
         context. It will insure the context for the (item, plot, onlimits, roi)
         is created.
@@ -399,11 +387,13 @@ class _HistogramContext(_ScatterCurveHistoMixInContext):
 
         if onlimits:
             minX, maxX = plot.getXAxis().getLimits()
-            if self.is_mask_valid(onlimits, from_=minX, to_=maxX):
+            if self.is_mask_valid(onlimits=onlimits, from_=minX, to_=maxX):
                 mask = self.mask
             else:
                 mask = (minX <= xData) & (xData <= maxX)
-                self._set_mask_validity(onlimits=True, from_=minX, to_=maxX)
+            yData = yData[mask]
+            xData = xData[mask]
+            mask = numpy.zeros_like(yData)
         elif roi:
             if self.is_mask_valid(onlimits, from_=roi._fromdata, to_=roi._todata):
                 mask = self.mask
@@ -413,11 +403,7 @@ class _HistogramContext(_ScatterCurveHistoMixInContext):
                 self._set_mask_validity(onlimits=True, from_=roi._fromdata,
                                         to_=roi._todata)
         else:
-            mask = numpy.zeros_like(self.data)
-
-        if onlimits:
-            yData = yData[mask]
-            xData = xData[mask]
+            mask = numpy.zeros_like(yData)
 
         self.data = (xData, yData)
         self.values = numpy.ma.array(yData, mask=mask)