diff --git a/Orange/widgets/visualize/owscatterplotgraph.py b/Orange/widgets/visualize/owscatterplotgraph.py index 96783a0a95d..b15d97f3abc 100644 --- a/Orange/widgets/visualize/owscatterplotgraph.py +++ b/Orange/widgets/visualize/owscatterplotgraph.py @@ -6,7 +6,7 @@ import numpy as np -from AnyQt.QtCore import Qt, QRectF, QSize +from AnyQt.QtCore import Qt, QRectF, QSize, QTimer from AnyQt.QtGui import ( QStaticText, QColor, QPen, QBrush, QPainterPath, QTransform, QPainter ) @@ -405,6 +405,8 @@ def __init__(self, scatter_widget, parent=None, view_box=ViewBox): self.plot_widget.scene().installEventFilter(self._tooltip_delegate) self.view_box.sigTransformChanged.connect(self.update_density) + self.__timer = QTimer() + def _create_legend(self, anchor): legend = LegendItem() legend.setParentItem(self.plot_widget.getViewBox()) @@ -721,12 +723,46 @@ def update_sizes(self): back to widget for imputing (`master.impute_sizes`). """ if self.scatterplot_item: + master = self.master size_data = self.get_sizes() size_imputer = getattr( self.master, "impute_sizes", self.default_impute_sizes) size_imputer(size_data) - self.scatterplot_item.setSize(size_data) - self.scatterplot_item_sel.setSize(size_data + SELECTION_WIDTH) + + if self.__timer.isActive(): + self.__timer.stop() + master.setBlocking(False) + + current_size_data = self.scatterplot_item.data["size"] + diff = size_data - current_size_data + + class Timeout: + n_iter = 5 + + def __init__(self, diff_=diff, item=self.scatterplot_item, + item_sel=self.scatterplot_item_sel): + self._counter = 0 + self._step = diff_ / self.n_iter + self._scatter_item, self._scatter_item_sel = item, item_sel + + def __call__(self): + self._counter += 1 + size = current_size_data + self._step + if self.n_iter == self._counter: + tmr.stop() + master.setBlocking(False) + size = size_data + self._scatter_item.setSize(size) + self._scatter_item_sel.setSize(size + SELECTION_WIDTH) + + if np.sum(current_size_data) / self.n_valid != -1 and np.sum(diff): + self.__timer = tmr = QTimer(self.scatterplot_item, interval=50) + self.__timer.timeout.connect(Timeout()) + self.__timer.start() + master.setBlocking(True) + else: + self.scatterplot_item.setSize(size_data) + self.scatterplot_item_sel.setSize(size_data + SELECTION_WIDTH) update_point_size = update_sizes # backward compatibility (needed?!) update_size = update_sizes diff --git a/Orange/widgets/visualize/tests/test_owscatterplotbase.py b/Orange/widgets/visualize/tests/test_owscatterplotbase.py index e966a4fc664..34b8f9f2bf6 100644 --- a/Orange/widgets/visualize/tests/test_owscatterplotbase.py +++ b/Orange/widgets/visualize/tests/test_owscatterplotbase.py @@ -5,6 +5,7 @@ from AnyQt.QtCore import QRectF, Qt from AnyQt.QtGui import QColor +from AnyQt.QtTest import QSignalSpy from pyqtgraph import mkPen @@ -16,6 +17,9 @@ from Orange.widgets.widget import OWWidget +DEFAULT_TIMEOUT = 5000 + + class MockWidget(OWWidget): name = "Mock" @@ -160,6 +164,9 @@ def test_sampling(self): master.get_label_data = lambda: \ np.array([str(x) for x in d], dtype=object) graph.reset_graph() + if self.master.isBlocking(): + spy = QSignalSpy(self.master.blockingStateChanged) + self.assertTrue(spy.wait(DEFAULT_TIMEOUT)) # Check proper sampling scatterplot_item = graph.scatterplot_item @@ -187,6 +194,9 @@ def test_sampling(self): # Check that sample is extended when sample size is changed graph.set_sample_size(4) + if self.master.isBlocking(): + spy = QSignalSpy(self.master.blockingStateChanged) + self.assertTrue(spy.wait(DEFAULT_TIMEOUT)) scatterplot_item = graph.scatterplot_item x, y = scatterplot_item.getData() data = scatterplot_item.data @@ -226,6 +236,9 @@ def test_sampling(self): # Enable sampling when data is already present and not sampled graph.set_sample_size(3) + if self.master.isBlocking(): + spy = QSignalSpy(self.master.blockingStateChanged) + self.assertTrue(spy.wait(DEFAULT_TIMEOUT)) scatterplot_item = graph.scatterplot_item x, y = scatterplot_item.getData() data = scatterplot_item.data @@ -261,6 +274,9 @@ def test_sampling(self): np.arange(100, 105, dtype=float)) d = self.xy[0] - 100 graph.reset_graph() + if self.master.isBlocking(): + spy = QSignalSpy(self.master.blockingStateChanged) + self.assertTrue(spy.wait(DEFAULT_TIMEOUT)) scatterplot_item = graph.scatterplot_item x, y = scatterplot_item.getData() self.assertEqual(len(x), 3) @@ -365,6 +381,9 @@ def test_size_with_nans(self): d[4] = np.nan graph.update_sizes() + if self.master.isBlocking(): + spy = QSignalSpy(self.master.blockingStateChanged) + self.assertTrue(spy.wait(DEFAULT_TIMEOUT)) sizes2 = scatterplot_item.data["size"] self.assertEqual(sizes[1] - sizes[0], sizes2[1] - sizes2[0])