Skip to content

Commit 16b7993

Browse files
committed
Implementing blitting for colorbar indicators
1 parent df7599c commit 16b7993

1 file changed

Lines changed: 74 additions & 7 deletions

File tree

openmc_plotter/plotgui.py

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,15 @@ def __init__(self, model: PlotModel, parent, main_window):
4747
self.colorbar = None
4848
self.data_indicator = None
4949
self.tally_data_indicator = None
50+
self.tally_colorbar = None
51+
self.tally_image = None
5052
self.image = None
5153

54+
self._data_colorbar_bg = None
55+
self._tally_colorbar_bg = None
56+
self._last_tally_indicator_value = None
57+
self._last_data_indicator_value = None
58+
5259
self.menu = QMenu(self)
5360

5461
def enterEvent(self, event):
@@ -538,6 +545,7 @@ def updatePixmap(self):
538545
linewidth=3.,
539546
color='blue',
540547
clip_on=True)
548+
self.data_indicator.set_animated(True)
541549
self.colorbar.ax.add_line(self.data_indicator)
542550
self.colorbar.ax.margins(0.0, 0.0)
543551
self.updateDataIndicatorVisibility()
@@ -626,6 +634,7 @@ def updatePixmap(self):
626634
linewidth=3.,
627635
color='blue',
628636
clip_on=True)
637+
self.tally_data_indicator.set_animated(True)
629638
self.tally_colorbar.ax.add_line(self.tally_data_indicator)
630639
self.tally_colorbar.ax.margins(0.0, 0.0)
631640

@@ -655,6 +664,9 @@ def updatePixmap(self):
655664
self.ax.dataLim.y1 = data_bounds[3]
656665

657666
self.draw()
667+
self._cache_colorbar_backgrounds()
668+
self._blit_indicator(self.data_indicator, self.colorbar)
669+
self._blit_indicator(self.tally_data_indicator, self.tally_colorbar)
658670
return "Done"
659671

660672
def current_view_data_bounds(self):
@@ -740,21 +752,63 @@ def parseContoursLine(line):
740752
def updateColorbarScale(self):
741753
self.updatePixmap()
742754

755+
def _cache_colorbar_backgrounds(self):
756+
"""Cache colorbar backgrounds for fast indicator blitting."""
757+
self._data_colorbar_bg = None
758+
self._tally_colorbar_bg = None
759+
760+
if self.colorbar and self.data_indicator:
761+
self._data_colorbar_bg = self.copy_from_bbox(
762+
self.colorbar.ax.bbox)
763+
764+
if self.tally_colorbar and self.tally_data_indicator:
765+
self._tally_colorbar_bg = self.copy_from_bbox(
766+
self.tally_colorbar.ax.bbox)
767+
768+
def _blit_indicator(self, indicator, colorbar):
769+
"""Blit a single indicator line onto its colorbar if possible."""
770+
if colorbar is None or indicator is None:
771+
return False
772+
773+
if not indicator.get_visible():
774+
return False
775+
776+
if colorbar is self.colorbar:
777+
background = self._data_colorbar_bg
778+
else:
779+
background = self._tally_colorbar_bg
780+
781+
if background is None:
782+
return False
783+
784+
self.restore_region(background)
785+
colorbar.ax.draw_artist(indicator)
786+
self.blit(colorbar.ax.bbox)
787+
return True
788+
743789
def updateTallyDataIndicatorValue(self, y_val):
744790
cv = self.model.currentView
745791

746792
if not cv.tallyDataVisible or not cv.tallyDataIndicator:
747793
return
748794

749-
if self.tally_data_indicator is not None:
750-
data = self.tally_data_indicator.get_data()
795+
if self.tally_data_indicator is not None and self.tally_image is not None:
751796
# use norm to get axis value if log scale
752797
if cv.tallyDataLogScale:
753798
y_val = self.tally_image.norm(y_val)
799+
800+
# If indicator value hasn't changed, skip update
801+
if self._last_tally_indicator_value == y_val:
802+
return
803+
self._last_tally_indicator_value = y_val
804+
805+
data = self.tally_data_indicator.get_data()
754806
self.tally_data_indicator.set_data([data[0], [y_val, y_val]])
755807
dl_color = invert_rgb(self.tally_image.get_cmap()(y_val), True)
756808
self.tally_data_indicator.set_c(dl_color)
757-
self.draw()
809+
810+
if not self._blit_indicator(self.tally_data_indicator, self.tally_colorbar):
811+
self.draw_idle()
758812

759813
def updateDataIndicatorValue(self, y_val):
760814
cv = self.model.currentView
@@ -763,28 +817,39 @@ def updateDataIndicatorValue(self, y_val):
763817
not cv.data_indicator_enabled[cv.colorby]:
764818
return
765819

766-
if self.data_indicator:
767-
data = self.data_indicator.get_data()
820+
if self.data_indicator and self.image is not None:
768821
# use norm to get axis value if log scale
769822
if cv.color_scale_log[cv.colorby]:
770823
y_val = self.image.norm(y_val)
824+
825+
# If indicator value hasn't changed, skip update
826+
if self._last_data_indicator_value == y_val:
827+
return
828+
self._last_data_indicator_value = y_val
829+
830+
data = self.data_indicator.get_data()
771831
self.data_indicator.set_data([data[0], [y_val, y_val]])
772832
dl_color = invert_rgb(self.image.get_cmap()(y_val), True)
773833
self.data_indicator.set_c(dl_color)
774-
self.draw()
834+
835+
if not self._blit_indicator(self.data_indicator, self.colorbar):
836+
self.draw_idle()
775837

776838
def updateDataIndicatorVisibility(self):
777839
cv = self.model.currentView
778840
if self.data_indicator and cv.colorby in _MODEL_PROPERTIES:
779841
val = cv.data_indicator_enabled[cv.colorby]
780842
self.data_indicator.set_visible(val)
781-
self.draw()
843+
if not self._blit_indicator(self.data_indicator, self.colorbar):
844+
self.draw_idle()
782845

783846
def updateColorMap(self, colormap_name, property_type):
784847
if self.colorbar and property_type == self.model.activeView.colorby:
785848
self.image.set_cmap(colormap_name)
786849
self.figure.draw_without_rendering()
787850
self.draw()
851+
self._cache_colorbar_backgrounds()
852+
self._blit_indicator(self.data_indicator, self.colorbar)
788853

789854
def updateColorMinMax(self, property_type):
790855
av = self.model.activeView
@@ -795,6 +860,8 @@ def updateColorMinMax(self, property_type):
795860
(0.0, 0.0))
796861
self.figure.draw_without_rendering()
797862
self.draw()
863+
self._cache_colorbar_backgrounds()
864+
self._blit_indicator(self.data_indicator, self.colorbar)
798865

799866

800867
class ColorDialog(QDialog):

0 commit comments

Comments
 (0)