Skip to content

Commit d0b617a

Browse files
committed
BasePlot: rewrote plotpy v1 auto scale exclude mgt
Using weak references to items excluded from auto-scale Do not change a class attribute! (very bad) New method to remove excluded items (weird to be able to add them without being able to remove them)
1 parent 2eba771 commit d0b617a

File tree

2 files changed

+66
-38
lines changed

2 files changed

+66
-38
lines changed

plotpy/plot/base.py

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import pickle
1919
import sys
2020
import warnings
21+
import weakref
2122
from dataclasses import dataclass
2223
from math import fabs
2324
from typing import TYPE_CHECKING
@@ -146,7 +147,6 @@ class BasePlot(qwt.QwtPlot):
146147
DEFAULT_ACTIVE_YAXIS = Y_LEFT
147148

148149
AUTOSCALE_TYPES = (CurveItem, BaseImageItem, PolygonMapItem)
149-
AUTOSCALE_EXCLUDES: list[itf.IBasePlotItem] = []
150150

151151
#: Signal emitted by plot when an IBasePlotItem object was moved
152152
#:
@@ -277,6 +277,7 @@ def __init__(
277277
super().__init__(parent)
278278
self.options = options = options if options is not None else BasePlotOptions()
279279

280+
self.__autoscale_excluded_items: list[itf.IBasePlotItem] = []
280281
self.lock_aspect_ratio = options.lock_aspect_ratio
281282
self.__autoLockAspectRatio = False
282283
if self.lock_aspect_ratio is None:
@@ -1872,6 +1873,52 @@ def edit_axis_parameters(self, axis_id: int) -> None:
18721873
param.update_axis(self, axis_id)
18731874
self.replot()
18741875

1876+
def add_autoscale_types(self, item_types: tuple[type]) -> None:
1877+
"""
1878+
Add item types to autoscale list
1879+
1880+
Args:
1881+
item_types (tuple[type]): the item types
1882+
"""
1883+
self.AUTOSCALE_TYPES += item_types
1884+
1885+
def add_autoscale_excludes(self, items: list[itf.IBasePlotItem]) -> None:
1886+
"""Add items to autoscale excludes list
1887+
1888+
Args:
1889+
items (list[IBasePlotItem]): the items
1890+
"""
1891+
current_list = self.get_auto_scale_excludes()
1892+
for item in items:
1893+
if item not in current_list:
1894+
self.__autoscale_excluded_items.append(weakref.ref(item))
1895+
1896+
def remove_autoscale_excludes(self, items: list[itf.IBasePlotItem]) -> None:
1897+
"""Remove items from autoscale excludes list
1898+
1899+
Args:
1900+
items (list[IBasePlotItem]): the items
1901+
"""
1902+
current_list = self.get_auto_scale_excludes()
1903+
for item in items:
1904+
if item in current_list:
1905+
self.__autoscale_excluded_items.remove(weakref.ref(item))
1906+
1907+
def get_auto_scale_excludes(self) -> list[itf.IBasePlotItem]:
1908+
"""Return autoscale excludes
1909+
1910+
Returns:
1911+
list[IBasePlotItem]: the items
1912+
"""
1913+
# Update the list of excluded items, removing the items that have been
1914+
# deleted since the last call to this method
1915+
self.__autoscale_excluded_items = [
1916+
item_ref
1917+
for item_ref in self.__autoscale_excluded_items
1918+
if item_ref() is not None
1919+
]
1920+
return [item_ref() for item_ref in self.__autoscale_excluded_items]
1921+
18751922
def do_autoscale(self, replot: bool = True, axis_id: int | None = None) -> None:
18761923
"""Do autoscale on all axes
18771924
@@ -1891,7 +1938,7 @@ def do_autoscale(self, replot: bool = True, axis_id: int | None = None) -> None:
18911938
isinstance(item, self.AUTOSCALE_TYPES)
18921939
and not item.is_empty()
18931940
and item.isVisible()
1894-
and item not in self.AUTOSCALE_EXCLUDES
1941+
and item not in self.get_auto_scale_excludes()
18951942
):
18961943
bounds = item.boundingRect()
18971944
if axis_id == item.xAxis():
@@ -2106,25 +2153,6 @@ def get_plot_limits(
21062153
y0, y1 = self.get_axis_limits(yaxis)
21072154
return x0, x1, y0, y1
21082155

2109-
def add_autoscale_types(self, item_types: tuple[type]) -> None:
2110-
"""
2111-
Add item types to autoscale list
2112-
2113-
Args:
2114-
item_types (tuple[type]): the item types
2115-
"""
2116-
self.AUTOSCALE_TYPES += item_types
2117-
2118-
def add_autoscale_excludes(self, items: list[itf.IBasePlotItem]) -> None:
2119-
"""Add items to autoscale excludes list
2120-
2121-
Args:
2122-
items (list[IBasePlotItem]): the items
2123-
"""
2124-
for item in items:
2125-
if item not in self.AUTOSCALE_EXCLUDES:
2126-
self.AUTOSCALE_EXCLUDES.append(item)
2127-
21282156
# ---- Image scale/aspect ratio -related API -------------------------------
21292157
def get_current_aspect_ratio(self) -> float:
21302158
"""Return current aspect ratio
@@ -2247,6 +2275,13 @@ def update_colormap_axis(self, item: itf.IColormapImageItemType) -> None:
22472275
)
22482276
self.updateAxes()
22492277

2278+
# # Keep this around to debug too many replots
2279+
# def replot(self):
2280+
# import traceback
2281+
2282+
# traceback.print_stack()
2283+
# qwt.QwtPlot.replot(self)
2284+
22502285
@classmethod
22512286
def register_autoscale_type(cls, type_):
22522287
"""Add *type_* to the list of types used to check if an item is
@@ -2262,22 +2297,13 @@ def register_autoscale_type(cls, type_):
22622297
cls.AUTOSCALE_TYPES += (type_,)
22632298

22642299

2265-
# Register PolygonShape and annotated shape.
2300+
# Register PolygonShape and annotated shape classes.
22662301
# It's not possible to simply register AnnotatedShape class
22672302
# because their is no warranty that SHAPE_CLASS implements all methods.
2268-
for shape in (
2269-
PolygonShape,
2270-
annotations.AnnotatedRectangle,
2271-
annotations.AnnotatedCircle,
2272-
annotations.AnnotatedEllipse,
2273-
annotations.AnnotatedObliqueRectangle,
2274-
annotations.AnnotatedSegment,
2275-
annotations.AnnotatedPoint,
2276-
):
2277-
BasePlot.register_autoscale_type(shape)
2278-
2279-
# Keep this around to debug too many replots
2280-
# def replot(self):
2281-
# import traceback
2282-
# traceback.print_stack()
2283-
# QwtPlot.replot(self)
2303+
BasePlot.register_autoscale_type(PolygonShape)
2304+
BasePlot.register_autoscale_type(annotations.AnnotatedRectangle)
2305+
BasePlot.register_autoscale_type(annotations.AnnotatedCircle)
2306+
BasePlot.register_autoscale_type(annotations.AnnotatedEllipse)
2307+
BasePlot.register_autoscale_type(annotations.AnnotatedObliqueRectangle)
2308+
BasePlot.register_autoscale_type(annotations.AnnotatedSegment)
2309+
BasePlot.register_autoscale_type(annotations.AnnotatedPoint)

plotpy/tests/gui/test_autoscale_shapes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ def test_autoscale_shapes():
7676
# Add an annotated rectangle
7777
rect = make.annotated_rectangle(2.5, 1, 4, 1.2, "Annotated rectangle")
7878
plot.add_item(rect)
79+
plot.add_autoscale_excludes([rect])
80+
plot.remove_autoscale_excludes([rect]) # Just to test the method
7981

8082
# Add an annotated rectangle excluded
8183
rect = make.annotated_rectangle(

0 commit comments

Comments
 (0)