Skip to content

Commit e2eb1c8

Browse files
author
Caitlin Lewis
committed
line collection, fixing feature event names
1 parent 0517d5c commit e2eb1c8

9 files changed

Lines changed: 247 additions & 35 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "f02f7349-ac1a-49b7-b304-d5b701723e0f",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"%load_ext autoreload\n",
11+
"%autoreload 2"
12+
]
13+
},
14+
{
15+
"cell_type": "code",
16+
"execution_count": 1,
17+
"id": "d9f54448-7718-4212-ac6d-163a2d3be146",
18+
"metadata": {},
19+
"outputs": [],
20+
"source": [
21+
"import numpy as np\n",
22+
"from fastplotlib.graphics import LineGraphic, LineCollection, ImageGraphic\n",
23+
"from fastplotlib.plot import Plot\n",
24+
"import pickle"
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": 2,
30+
"id": "b683c6d1-d926-43e3-a221-4ec6450e3677",
31+
"metadata": {},
32+
"outputs": [],
33+
"source": [
34+
"contours = pickle.load(open(\"/home/caitlin/Downloads/contours.pickle\", \"rb\"))"
35+
]
36+
},
37+
{
38+
"cell_type": "code",
39+
"execution_count": 3,
40+
"id": "26ced005-c52f-4696-903d-a6974ae6cefc",
41+
"metadata": {},
42+
"outputs": [
43+
{
44+
"data": {
45+
"application/vnd.jupyter.widget-view+json": {
46+
"model_id": "2bc75fa52d484cd1b03006a6530f10b3",
47+
"version_major": 2,
48+
"version_minor": 0
49+
},
50+
"text/plain": [
51+
"RFBOutputContext()"
52+
]
53+
},
54+
"metadata": {},
55+
"output_type": "display_data"
56+
},
57+
{
58+
"name": "stderr",
59+
"output_type": "stream",
60+
"text": [
61+
"MESA-INTEL: warning: Performance support disabled, consider sysctl dev.i915.perf_stream_paranoid=0\n",
62+
"\n"
63+
]
64+
}
65+
],
66+
"source": [
67+
"plot = Plot()"
68+
]
69+
},
70+
{
71+
"cell_type": "code",
72+
"execution_count": 4,
73+
"id": "1aea0a61-db63-41e1-b330-5a922da4bac5",
74+
"metadata": {},
75+
"outputs": [],
76+
"source": [
77+
"line_collection = LineCollection(contours, cmap=\"Oranges\")"
78+
]
79+
},
80+
{
81+
"cell_type": "code",
82+
"execution_count": 5,
83+
"id": "310fd5b3-49f2-4dbb-831e-cb9f369d58c8",
84+
"metadata": {},
85+
"outputs": [],
86+
"source": [
87+
"plot.add_graphic(line_collection)"
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": 6,
93+
"id": "661a5991-0de3-44d7-a626-2ae72704dcec",
94+
"metadata": {},
95+
"outputs": [],
96+
"source": [
97+
"image = ImageGraphic(data=np.ones((180, 180)))"
98+
]
99+
},
100+
{
101+
"cell_type": "code",
102+
"execution_count": 7,
103+
"id": "816f6382-f4ea-4cd4-b9f3-2dc5c232b0a5",
104+
"metadata": {},
105+
"outputs": [],
106+
"source": [
107+
"plot.add_graphic(image)"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": null,
113+
"id": "8187fd25-18e1-451f-b2fe-8cd2e7785c8b",
114+
"metadata": {},
115+
"outputs": [],
116+
"source": [
117+
"plot.show()"
118+
]
119+
},
120+
{
121+
"cell_type": "code",
122+
"execution_count": null,
123+
"id": "d5ddd3c4-84e2-44a3-a14f-74871aa0bb8f",
124+
"metadata": {},
125+
"outputs": [],
126+
"source": [
127+
"black = np.array([0.0, 0.0, 0.0, 1.0])"
128+
]
129+
},
130+
{
131+
"cell_type": "code",
132+
"execution_count": null,
133+
"id": "6ac64f1c-21e0-4c21-b968-3953e7858848",
134+
"metadata": {},
135+
"outputs": [],
136+
"source": [
137+
"from typing import *"
138+
]
139+
},
140+
{
141+
"cell_type": "code",
142+
"execution_count": null,
143+
"id": "d0d0c971-aac9-4c77-b88c-de9d79c7d74e",
144+
"metadata": {},
145+
"outputs": [],
146+
"source": [
147+
"def callback_function(source: Any, target: Any, event, new_data: Any):\n",
148+
" # calculate coms of line collection\n",
149+
" indices = np.array(event.pick_info[\"index\"])\n",
150+
" \n",
151+
" coms = list()\n",
152+
"\n",
153+
" for contour in target.items:\n",
154+
" coors = contour.data.feature_data[~np.isnan(contour.data.feature_data).any(axis=1)]\n",
155+
" com = coors.mean(axis=0)\n",
156+
" coms.append(com)\n",
157+
"\n",
158+
" # euclidean distance to find closest index of com \n",
159+
" indices = np.append(indices, [0])\n",
160+
" \n",
161+
" ix = np.linalg.norm((coms - indices), axis=1).argsort()[0]\n",
162+
" \n",
163+
" ix = int(ix)\n",
164+
" \n",
165+
" print(ix)\n",
166+
" \n",
167+
" target._set_feature(feature=\"colors\", new_data=new_data, indices=ix)\n",
168+
" \n",
169+
" return None"
170+
]
171+
},
172+
{
173+
"cell_type": "code",
174+
"execution_count": null,
175+
"id": "1a46d148-3007-4c7a-bf2b-91057eba855d",
176+
"metadata": {},
177+
"outputs": [],
178+
"source": [
179+
"image.link(event_type=\"click\", target=line_collection, feature=\"colors\", new_data=black, callback_function=callback_function)"
180+
]
181+
},
182+
{
183+
"cell_type": "code",
184+
"execution_count": null,
185+
"id": "8040456e-24a5-423b-8822-99a20e7ea470",
186+
"metadata": {},
187+
"outputs": [],
188+
"source": []
189+
}
190+
],
191+
"metadata": {
192+
"kernelspec": {
193+
"display_name": "Python 3 (ipykernel)",
194+
"language": "python",
195+
"name": "python3"
196+
},
197+
"language_info": {
198+
"codemirror_mode": {
199+
"name": "ipython",
200+
"version": 3
201+
},
202+
"file_extension": ".py",
203+
"mimetype": "text/x-python",
204+
"name": "python",
205+
"nbconvert_exporter": "python",
206+
"pygments_lexer": "ipython3",
207+
"version": "3.9.2"
208+
}
209+
},
210+
"nbformat": 4,
211+
"nbformat_minor": 5
212+
}

fastplotlib/graphics/_base.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ def event_handler(self, event):
114114
if target_info.callback_function is not None:
115115
# if callback_function is not None, then callback function should handle the entire event
116116
target_info.callback_function(source=self, target=target_info.target, event=event, new_data=target_info.new_data)
117-
elif isinstance(target_info.target, GraphicCollection):
117+
elif isinstance(self, GraphicCollection):
118118
# if target is a GraphicCollection, then indices will be stored in collection_index
119-
indices = event.pick_info["collection_index"]
120-
target_info.target._set_feature(feature=target_info.feature, new_data=target_info.new_data, indices=indices)
119+
# indices = event.pick_info["collection_index"]
120+
# target_info.target._set_feature(feature=target_info.feature, new_data=target_info.new_data, indices=indices)
121+
print(event.pick_info)
121122
else:
122123
# if target is a single graphic, then indices do not matter
123124
target_info.target._set_feature(feature=target_info.feature, new_data=target_info.new_data,
@@ -140,10 +141,14 @@ class PreviouslyModifiedData:
140141

141142

142143
class GraphicCollection(BaseGraphic):
144+
pygfx_events = [
145+
"click"
146+
]
143147
"""Graphic Collection base class"""
144148
def __init__(self, name: str = None):
145149
self.name = name
146150
self._items: List[Graphic] = list()
151+
self.registered_callbacks = dict()
147152

148153
@property
149154
def world_object(self) -> Group:

fastplotlib/graphics/features/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class FeatureEvent:
1111
"""
12-
type: <feature_name>-<changed>, example: "color-changed"
12+
type: <feature_name>, example: "colors"
1313
pick_info: dict in the form:
1414
{
1515
"index": indices where feature data was changed, ``range`` object or List[int],

fastplotlib/graphics/features/_colors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def _feature_changed(self, key, new_data):
189189
"new_data": new_data,
190190
}
191191

192-
event_data = FeatureEvent(type="color-changed", pick_info=pick_info)
192+
event_data = FeatureEvent(type="color", pick_info=pick_info)
193193

194194
self._call_event_handlers(event_data)
195195

@@ -241,6 +241,6 @@ def _feature_changed(self, key, new_data):
241241
"new_data": new_data
242242
}
243243

244-
event_data = FeatureEvent(type="cmap-changed", pick_info=pick_info)
244+
event_data = FeatureEvent(type="cmap", pick_info=pick_info)
245245

246246
self._call_event_handlers(event_data)

fastplotlib/graphics/features/_data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def _feature_changed(self, key, new_data):
8888
"new_data": new_data
8989
}
9090

91-
event_data = FeatureEvent(type="data-changed", pick_info=pick_info)
91+
event_data = FeatureEvent(type="data", pick_info=pick_info)
9292

9393
self._call_event_handlers(event_data)
9494

@@ -145,6 +145,6 @@ def _feature_changed(self, key, new_data):
145145
"new_data": new_data
146146
}
147147

148-
event_data = FeatureEvent(type="data-changed", pick_info=pick_info)
148+
event_data = FeatureEvent(type="data", pick_info=pick_info)
149149

150150
self._call_event_handlers(event_data)

fastplotlib/graphics/features/_present.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,6 @@ def _feature_changed(self, key, new_data):
5050
"new_data": new_data
5151
}
5252

53-
event_data = FeatureEvent(type="present-changed", pick_info=pick_info)
53+
event_data = FeatureEvent(type="present", pick_info=pick_info)
5454

5555
self._call_event_handlers(event_data)

fastplotlib/graphics/image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class ImageGraphic(Graphic, Interaction):
1111
feature_events = [
1212
"data",
13-
"cmap",
13+
"colors",
1414
]
1515
def __init__(
1616
self,

fastplotlib/graphics/line.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class LineGraphic(Graphic, Interaction):
1111
feature_events = [
1212
"data",
1313
"colors",
14-
"cmap",
1514
]
1615
def __init__(
1716
self,

fastplotlib/graphics/linecollection.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
from .line import LineGraphic
77
from ..utils import get_colors
88
from typing import *
9+
from copy import deepcopy
910

1011

1112
class LineCollection(GraphicCollection, Interaction):
1213
"""Line Collection graphic"""
1314
child_type = LineGraphic
1415
feature_events = [
15-
"data-changed",
16-
"color-changed",
17-
"cmap-changed",
16+
"data",
17+
"colors",
1818
]
1919
def __init__(
2020
self,
@@ -118,34 +118,30 @@ def __init__(
118118

119119
self.add_graphic(lg, reset_index=False)
120120

121-
def _set_feature(self, feature: str, new_data: Any, indices: Union[int, range]):
121+
def _set_feature(self, feature: str, new_data: Any, indices: Any):
122122
if not hasattr(self, "_previous_data"):
123-
self._previous_data = {}
123+
self._previous_data = dict()
124124
elif hasattr(self, "_previous_data"):
125125
self._reset_feature(feature)
126-
#if feature in # need a way to check if feature is in
127-
feature_instance = getattr(self, feature)
128-
if indices is not None:
129-
previous = feature_instance[indices].copy()
130-
feature_instance[indices] = new_data
131-
else:
132-
previous = feature_instance[:].copy()
133-
feature_instance[:] = new_data
126+
127+
coll_feature = getattr(self[indices], feature)
128+
129+
data = list()
130+
for cf in coll_feature:
131+
data += cf
132+
data = np.array(data)
133+
134+
previous = data
135+
coll_feature._set(new_data)
136+
134137
if feature in self._previous_data.keys():
135138
self._previous_data[feature].previous_data = previous
136139
self._previous_data[feature].previous_indices = indices
137140
else:
138141
self._previous_data[feature] = PreviouslyModifiedData(previous_data=previous, previous_indices=indices)
139-
# else:
140-
# raise ValueError("name arg is not a valid feature")
141142

142143
def _reset_feature(self, feature: str):
143-
if feature not in self._previous_data.keys():
144-
raise ValueError("no previous data registered for this feature")
145-
else:
146-
feature_instance = getattr(self, feature)
147-
if self._previous_data[feature].previous_indices is not None:
148-
feature_instance[self._previous_data[feature].previous_indices] = self._previous_data[
149-
feature].previous_data
150-
else:
151-
feature_instance[:] = self._previous_data[feature].previous_data
144+
# implemented for a single index at moment
145+
prev_ixs = self._previous_data[feature].previous_indices
146+
coll_feature = getattr(self[prev_ixs], feature)
147+
coll_feature._set(self._previous_data[feature].previous_data)

0 commit comments

Comments
 (0)