Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8919d7c

Browse files
authored
legends, part 1 (#406)
* start legends, not functional yet * add faq (#400) * fix bug when remove_graphic() is used (#405) * add 'Deleted' as a graphic feature (#404) * very basic adding line legends works * use OrderedDict for legend items * allow accessing legend items via Graphic, updating colors works * legend mesh resizes properly * remove legend items and reorder works * enforce all legend labels to be unique * add legends property to PlotArea * checks for Graphic name * highlight linegraphic when legend item is clicked * legend is moveable * remove weird characters that were committed for some reason * progress on legend grid placement, not yet working * max_rows works for legend * just allow max_rows kwarg for legends, no cols * line that snuck in from another branch * small changes
1 parent 481c5ea commit 8919d7c

File tree

6 files changed

+530
-8
lines changed

6 files changed

+530
-8
lines changed

fastplotlib/__init__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from .layouts import Plot, GridPlot
44
from .graphics import *
55
from .graphics.selectors import *
6-
from .utils import _notebook_print_banner, config
6+
from .legends import *
77

88
from wgpu.gui.auto import run
99

@@ -23,14 +23,13 @@
2323
"No WGPU adapters found, fastplotlib will not work."
2424
)
2525

26-
_notebook_print_banner()
27-
2826
with open(Path(__file__).parent.joinpath("VERSION"), "r") as f:
2927
__version__ = f.read().split("\n")[0]
3028

3129
__all__ = [
3230
"Plot",
3331
"GridPlot",
3432
"run",
35-
"ImageWidget"
33+
"ImageWidget",
34+
"Legend",
3635
]

fastplotlib/graphics/_base.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Graphic(BaseGraphic):
4848
feature_events = {}
4949

5050
def __init_subclass__(cls, **kwargs):
51+
super().__init_subclass__(**kwargs)
5152
# all graphics give off a feature event when deleted
5253
cls.feature_events = {*cls.feature_events, "deleted"}
5354

@@ -62,14 +63,16 @@ def __init__(
6263
Parameters
6364
----------
6465
name: str, optional
65-
name this graphic, makes it indexable within plots
66+
name this graphic to use it as a key to access from the plot
6667
6768
metadata: Any, optional
6869
metadata attached to this Graphic, this is for the user to manage
6970
7071
"""
72+
if (name is not None) and (not isinstance(name, str)):
73+
raise TypeError("Graphic `name` must be of type <str>")
7174

72-
self.name = name
75+
self._name = name
7376
self.metadata = metadata
7477
self.collection_index = collection_index
7578
self.registered_callbacks = dict()
@@ -80,6 +83,20 @@ def __init__(
8083

8184
self.deleted = Deleted(self, False)
8285

86+
self._plot_area = None
87+
88+
@property
89+
def name(self) -> Union[str, None]:
90+
"""str name reference for this item"""
91+
return self._name
92+
93+
@name.setter
94+
def name(self, name: str):
95+
if not isinstance(name, str):
96+
raise TypeError("`Graphic` name must be of type <str>")
97+
if self._plot_area is not None:
98+
self._plot_area._check_graphic_name_exists(name)
99+
83100
@property
84101
def world_object(self) -> WorldObject:
85102
"""Associated pygfx WorldObject. Always returns a proxy, real object cannot be accessed directly."""

fastplotlib/layouts/_plot_area.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ._utils import create_camera, create_controller
1313
from ..graphics._base import Graphic
1414
from ..graphics.selectors._base_selector import BaseSelector
15+
from ..legends import Legend
1516

1617
# dict to store Graphic instances
1718
# this is the only place where the real references to Graphics are stored in a Python session
@@ -62,7 +63,7 @@ def __init__(
6263
6364
name: str, optional
6465
name this ``subplot`` or ``plot``
65-
66+
6667
"""
6768

6869
self._parent: PlotArea = parent
@@ -208,6 +209,8 @@ def graphics(self) -> Tuple[Graphic, ...]:
208209
proxies = list()
209210
for loc in self._graphics:
210211
p = weakref.proxy(GRAPHICS[loc])
212+
if p.__class__.__name__ == "Legend":
213+
continue
211214
proxies.append(p)
212215

213216
return tuple(proxies)
@@ -222,6 +225,17 @@ def selectors(self) -> Tuple[BaseSelector, ...]:
222225

223226
return tuple(proxies)
224227

228+
@property
229+
def legends(self) -> Tuple[Legend, ...]:
230+
"""Legends in the plot area."""
231+
proxies = list()
232+
for loc in self._graphics:
233+
p = weakref.proxy(GRAPHICS[loc])
234+
if p.__class__.__name__ == "Legend":
235+
proxies.append(p)
236+
237+
return tuple(proxies)
238+
225239
@property
226240
def name(self) -> Any:
227241
"""The name of this plot area"""
@@ -486,6 +500,9 @@ def _check_graphic_name_exists(self, name):
486500
for s in self.selectors:
487501
graphic_names.append(s.name)
488502

503+
for l in self.legends:
504+
graphic_names.append(l.name)
505+
489506
if name in graphic_names:
490507
raise ValueError(
491508
f"graphics must have unique names, current graphic names are:\n {graphic_names}"
@@ -666,6 +683,10 @@ def __getitem__(self, name: str):
666683
if selector.name == name:
667684
return selector
668685

686+
for legend in self.legends:
687+
if legend.name == name:
688+
return legend
689+
669690
graphic_names = list()
670691
for g in self.graphics:
671692
graphic_names.append(g.name)
@@ -681,7 +702,7 @@ def __getitem__(self, name: str):
681702
)
682703

683704
def __contains__(self, item: Union[str, Graphic]):
684-
to_check = [*self.graphics, *self.selectors]
705+
to_check = [*self.graphics, *self.selectors, *self.legends]
685706

686707
if isinstance(item, Graphic):
687708
if item in to_check:

fastplotlib/legends/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .legend import Legend
2+
3+
__all__ = ["Legend"]

0 commit comments

Comments
 (0)