Skip to content

Commit ab63d9d

Browse files
committed
Added state patch for translating Qt sessions to Jupyter sessions, add test and fix translation for basic plots
1 parent d795baf commit ab63d9d

File tree

10 files changed

+1010
-9
lines changed

10 files changed

+1010
-9
lines changed

glue_jupyter/app.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -641,11 +641,17 @@ def restore_session(path):
641641
finally:
642642
os.chdir(start_dir)
643643

644+
def __gluestate__(self, context):
645+
viewers = [context.id(v) for v in self.viewers]
646+
data = self.session.data_collection
647+
from glue.main import _loaded_plugins
648+
return dict(session=context.id(self.session), viewers=viewers,
649+
data=context.id(data), plugins=_loaded_plugins)
650+
644651
@classmethod
645652
def __setgluestate__(cls, rec, context):
646653
self = super(JupyterApplication, cls).__setgluestate__(rec, context)
647-
for tab in rec['viewers']:
648-
for v in tab:
649-
viewer = context.object(v)
650-
self._viewer_refs.append(weakref.ref(viewer))
654+
for v in rec['viewers']:
655+
viewer = context.object(v)
656+
self._viewer_refs.append(weakref.ref(viewer))
651657
return self

glue_jupyter/bqplot/histogram/tests/test_viewer.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from itertools import permutations, product
22
from glue.core.subset import SubsetState
3+
from glue.core.tests.test_state import clone
34

45

56
def test_non_hex_colors(app, dataxyz):
@@ -66,3 +67,13 @@ def test_zorder(app, data_volume, dataxz, dataxyz):
6667
vol.state.zorder, xz.state.zorder, xyz.state.zorder = p
6768
it = iter(s.figure.marks)
6869
assert all(layer.bars in it for layer in s.layers)
70+
71+
72+
def test_session(app, dataxz, dataxyz):
73+
74+
# Test that the viewer can be saved and restored from a session file
75+
76+
v = app.histogram1d(data=dataxyz)
77+
v.add_data(dataxz)
78+
app.data_collection.new_subset_group(subset_state=dataxz.id['x'] > 1, label='subset')
79+
clone(app)

glue_jupyter/bqplot/image/state.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ class BqplotImageLayerState(ImageLayerState):
3333

3434
def __init__(self, *args, **kwargs):
3535

36-
super(BqplotImageLayerState, self).__init__(*args, **kwargs)
37-
3836
BqplotImageLayerState.level_mode.set_choices(self, ['Linear', 'Custom'])
3937
percentile_display = {100: 'Min/Max',
4038
99.5: '99.5%',
@@ -46,6 +44,9 @@ def __init__(self, *args, **kwargs):
4644
BqplotImageLayerState.contour_percentile.set_choices(self, [100, 99.5, 99, 95, 90,
4745
'Custom'])
4846
BqplotImageLayerState.contour_percentile.set_display_func(self, percentile_display.get)
47+
48+
super(BqplotImageLayerState, self).__init__(*args, **kwargs)
49+
4950
self.contour_lim_helper = StateAttributeLimitsHelper(self, attribute='attribute',
5051
percentile='contour_percentile',
5152
lower='c_min', upper='c_max')

glue_jupyter/bqplot/image/tests/test_viewer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import glue_jupyter.state_traitlets_helpers
2+
from glue.core.tests.test_state import clone
23

34

45
def test_non_hex_colors(app, data_image):
@@ -118,3 +119,11 @@ def test_add_markers_zoom(app, data_image, data_volume, dataxyz):
118119
assert im.state.x_max == 63.5
119120
assert im.state.y_min == -0.5
120121
assert im.state.y_max == 63.5
122+
123+
124+
def test_session(app, data_image):
125+
126+
# Test that the viewer can be saved and restored from a session file
127+
128+
v = app.imshow(data=data_image)
129+
clone(app)

glue_jupyter/bqplot/image/viewer.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ class BqplotImageView(BqplotBaseView):
3434
tools = ['bqplot:home', 'bqplot:panzoom', 'bqplot:rectangle', 'bqplot:circle',
3535
'bqplot:ellipse', 'bqplot:polygon', 'bqplot:lasso']
3636

37-
def __init__(self, session):
38-
39-
super(BqplotImageView, self).__init__(session)
37+
def __init__(self, *args, **kwargs):
38+
super().__init__(*args, **kwargs)
4039

4140
self.shape = None
4241

glue_jupyter/bqplot/profile/tests/test_viewer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from glue.core.subset import AndState, InvertState, RangeSubsetState
1313
from glue.config import unit_converter, settings
1414
from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink
15+
from glue.core.tests.test_state import clone
1516

1617

1718
def setup_function(func):
@@ -238,3 +239,11 @@ def test_composite_yrange(app):
238239
assert isinstance(sbst.state1, RangeSubsetState)
239240
assert (isinstance(sbst.state2, InvertState) and
240241
isinstance(sbst.state2.state1, RangeSubsetState))
242+
243+
244+
def test_session(app, data_volume):
245+
246+
# Test that the viewer can be saved and restored from a session file
247+
248+
v = app.scatter2d(data=data_volume)
249+
clone(app)

glue_jupyter/bqplot/scatter/tests/test_viewer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from itertools import permutations
2+
from glue.core.tests.test_state import clone
23

34

45
def test_scatter2d_nd(app, data_4d):
@@ -106,3 +107,11 @@ def test_incompatible_data(app):
106107

107108
assert len(s.layers) == 1
108109
assert s.layers[0].enabled
110+
111+
112+
def test_session(app, dataxyz):
113+
114+
# Test that the viewer can be saved and restored from a session file
115+
116+
v = app.scatter2d(data=dataxyz)
117+
clone(app)

glue_jupyter/session.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from itertools import chain
2+
from glue.config import session_patch
3+
from glue_jupyter.app import JupyterApplication
4+
5+
TRANSLATION = {
6+
"glue_qt.viewers.histogram.data_viewer.HistogramViewer": "glue_jupyter.bqplot.histogram.BqplotHistogramView",
7+
"glue_qt.viewers.image.data_viewer.ImageViewer": "glue_jupyter.bqplot.image.BqplotImageView",
8+
"glue_qt.viewers.profile.data_viewer.ProfileViewer": "glue_jupyter.bqplot.profile.BqplotProfileView",
9+
"glue_qt.viewers.scatter.data_viewer.ScatterViewer": "glue_jupyter.bqplot.scatter.BqplotScatterView",
10+
"glue.viewers.image.layer_artist.ImageLayerArtist": "glue_jupyter.bqplot.image.BqplotImageLayerArtist",
11+
"glue.viewers.image.layer_artist.ImageSubsetLayerArtist": "glue_jupyter.bqplot.image.BqplotImageSubsetLayerArtist",
12+
"glue_qt.viewers.profile.layer_artist.QThreadedProfileLayerArtist": "glue_jupyter.bqplot.profile.BqplotProfileLayerArtist",
13+
"glue_qt.viewers.histogram.layer_artist.QThreadedHistogramLayerArtist": "glue_jupyter.bqplot.histogram.BqplotHistogramLayerArtist",
14+
"glue.viewers.scatter.layer_artist.ScatterLayerArtist": "glue_jupyter.bqplot.scatter.BqplotScatterLayerArtist",
15+
"glue.viewers.image.state.ImageLayerState": "glue_jupyter.bqplot.image.state.BqplotImageLayerState",
16+
"glue.viewers.image.state.ImageViewerState": "glue_jupyter.bqplot.image.state.BqplotImageViewerState",
17+
}
18+
19+
20+
@session_patch()
21+
def translate_qt_to_jupyter_session(session):
22+
23+
session["__main__"]["_type"] = "glue_jupyter.app.JupyterApplication"
24+
session["__main__"]["viewers"] = list(chain(*session["__main__"]["viewers"]))
25+
26+
for key in session:
27+
original_type = session[key]["_type"]
28+
if original_type in TRANSLATION:
29+
session[key]["_type"] = TRANSLATION[original_type]
30+
31+
if "layers" in session[key]:
32+
layers = session[key]["layers"]
33+
for layer in layers:
34+
if layer["_type"] in TRANSLATION:
35+
layer["_type"] = TRANSLATION[layer["_type"]]

0 commit comments

Comments
 (0)