5
5
import glue .core .hub
6
6
import glue .core .message as msg
7
7
import glue_jupyter as gj
8
- import glue_jupyter .app
9
8
import glue_jupyter .bqplot .histogram
10
9
import glue_jupyter .bqplot .image
11
10
import glue_jupyter .bqplot .scatter
15
14
from glue .viewers .common .viewer import Viewer
16
15
from glue_jupyter .data import require_data
17
16
from glue_jupyter .registries import viewer_registry
17
+ from glue_jupyter .utils import validate_data_argument
18
18
from solara import Reactive
19
19
20
20
from .hooks import ClosedMessage , use_glue_watch , use_glue_watch_close , use_layers_watch
23
23
from .viewers import GridViewers , MdiViewers , TabbedViewers
24
24
from .viewers .mdi import MDI_HEADER_SIZES , MdiWindow
25
25
26
+ # Initialize our viewer, since it isn't a 'proper' plugin (yet)
27
+ if "xr" not in viewer_registry .members :
28
+ from .viewers .xr import setup as xr_setup
29
+
30
+ xr_setup ()
31
+
32
+
33
+ class JupyterApplicationWithXR (gj .JupyterApplication ):
34
+ def xr_scatter3d (self , * , data = None , x = None , y = None , z = None , widget = "xr" , show = True ):
35
+ """
36
+ Open an interactive 3d scatter plot viewer.
37
+
38
+ Parameters
39
+ ----------
40
+ data : str or `~glue.core.data.Data`, optional
41
+ The initial dataset to show in the viewer. Additional
42
+ datasets can be added later using the ``add_data`` method on
43
+ the viewer object.
44
+ x : str or `~glue.core.component_id.ComponentID`, optional
45
+ The attribute to show on the x axis.
46
+ y : str or `~glue.core.component_id.ComponentID`, optional
47
+ The attribute to show on the y axis.
48
+ z : str or `~glue.core.component_id.ComponentID`, optional
49
+ The attribute to show on the z axis.
50
+ widget : {'ipyvolume', 'vispy', 'xr'}
51
+ Whether to use ipyvolume, VisPy, or ThreeJS as the front-end.
52
+ show : bool, optional
53
+ Whether to show the view immediately (`True`) or whether to only
54
+ show it later if the ``show()`` method is called explicitly
55
+ (`False`).
56
+ """
57
+
58
+ if widget == "ipyvolume" :
59
+ from glue_jupyter .ipyvolume import IpyvolumeScatterView
60
+
61
+ viewer_cls = IpyvolumeScatterView
62
+ elif widget == "vispy" :
63
+ from glue_vispy_viewers .scatter .jupyter import JupyterVispyScatterViewer
64
+
65
+ viewer_cls = JupyterVispyScatterViewer
66
+ elif widget == "xr" :
67
+ from glue_solara .viewers .xr .viewer import XRBaseView
68
+
69
+ viewer_cls = XRBaseView
70
+ else :
71
+ raise ValueError ("widget= should be 'ipyvolume', 'vispy', or 'xr'" )
72
+
73
+ data = validate_data_argument (self .data_collection , data )
74
+
75
+ view = self .new_data_viewer (viewer_cls , data = data , show = show )
76
+ if x is not None :
77
+ x = data .id [x ]
78
+ view .state .x_att = x
79
+ if y is not None :
80
+ y = data .id [y ]
81
+ view .state .y_att = y
82
+ if z is not None :
83
+ z = data .id [z ]
84
+ view .state .z_att = z
85
+
86
+ if data .label == "boston_planes_6h" :
87
+ view .state .x_att = data .id ["x" ]
88
+ view .state .y_att = data .id ["y" ]
89
+ view .state .z_att = data .id ["altitude" ]
90
+
91
+ if data .label == "w5_psc" :
92
+ view .state .x_att = data .id ["RAJ2000" ]
93
+ view .state .y_att = data .id ["DEJ2000" ]
94
+ view .state .z_att = data .id ["Jmag" ]
95
+
96
+ return view
97
+
98
+
26
99
# logging.basicConfig(level="INFO", force=True)
27
100
# logging.getLogger("glue").setLevel("DEBUG")
28
101
29
102
if not Path ("w5.fits" ).exists ():
30
103
require_data ("Astronomy/W5/w5.fits" )
31
104
if not Path ("w5_psc.csv" ).exists ():
32
105
require_data ("Astronomy/W5/w5_psc.csv" )
33
-
106
+ if not Path ("boston_planes_6h.csv" ).exists ():
107
+ require_data ("Planes/boston_planes_6h.csv" )
34
108
35
109
main_color = "#d0413e"
36
110
nice_colors = [
49
123
50
124
VIEWER_TYPES = list (map (lambda k : k .title (), viewer_registry .members .keys ()))
51
125
52
- VIEWER_METHODS = {"Histogram" : "histogram1d" , "Scatter" : "scatter2d" , "Image" : "imshow" }
126
+ VIEWER_METHODS = {
127
+ "Histogram" : "histogram1d" ,
128
+ "Scatter" : "scatter2d" ,
129
+ "Image" : "imshow" ,
130
+ "Xr" : "xr_scatter3d" ,
131
+ }
53
132
54
133
TITLE_TRANSLATIONS = {
55
134
"BqplotScatterView" : "2d Scatter" ,
@@ -70,7 +149,7 @@ def Page():
70
149
"""This component is used by default in solara server (standalone app)"""
71
150
72
151
def create_glue_application () -> gj .JupyterApplication :
73
- app = glue_jupyter . app . JupyterApplication ()
152
+ app = JupyterApplicationWithXR ()
74
153
return app
75
154
76
155
# make the app only once
@@ -422,6 +501,19 @@ def LoadData(app: gj.JupyterApplication):
422
501
)
423
502
solara .Button ("Upload data" , text = True , icon_name = "mdi-cloud-upload" , disabled = True )
424
503
504
+ def add_plane_data ():
505
+ path = "boston_planes_6h.csv"
506
+ data_image = app .load_data (path )
507
+ data_image .style .color = "blue"
508
+
509
+ solara .Button (
510
+ "Add Boston planes data" ,
511
+ on_click = add_plane_data ,
512
+ text = True ,
513
+ icon_name = "mdi-airplane" ,
514
+ style = {"width" : "100%" , "justify-content" : "left" },
515
+ )
516
+
425
517
def add_w5 ():
426
518
data_image = app .load_data ("w5.fits" )
427
519
data_catalog = app .load_data ("w5_psc.csv" )
0 commit comments