syd 0.2.0__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
syd-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,219 @@
1
+ Metadata-Version: 2.4
2
+ Name: syd
3
+ Version: 1.0.0
4
+ Summary: A Python package for making GUIs for data science easy.
5
+ Project-URL: Homepage, https://github.com/landoskape/syd
6
+ Author-email: Andrew Landau <andrew+tyler+landau+getridofthisanddtheplusses@gmail.com>
7
+ License-Expression: GPL-3.0-or-later
8
+ License-File: LICENSE
9
+ Keywords: data-science,gui,interactive,jupyter,machine-learning,notebook,python
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: flask
22
+ Requires-Dist: ipykernel
23
+ Requires-Dist: ipympl
24
+ Requires-Dist: ipywidgets
25
+ Requires-Dist: matplotlib
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
28
+ Requires-Dist: pytest>=7.0.0; extra == 'test'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Syd
32
+
33
+ [![PyPI version](https://badge.fury.io/py/syd.svg)](https://badge.fury.io/py/syd)
34
+ [![Tests](https://github.com/landoskape/syd/actions/workflows/tests.yml/badge.svg)](https://github.com/landoskape/syd/actions/workflows/tests.yml)
35
+ [![Documentation Status](https://readthedocs.org/projects/shareyourdata/badge/?version=stable)](https://shareyourdata.readthedocs.io/en/stable/?badge=stable)
36
+ [![codecov](https://codecov.io/gh/landoskape/syd/branch/main/graph/badge.svg)](https://codecov.io/gh/landoskape/syd)
37
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
38
+
39
+
40
+ A package to help you share your data!
41
+
42
+ Have you ever wanted to look through all your data really quickly interactively? Of course you have. Mo data mo problems, but only if you don't know what to do with it. And that's why Syd stands for show your data!
43
+
44
+ Syd is a system for creating a data viewing GUI that you can view in a jupyter notebook or in a web browser. And guess what? Since it can open in a web browser, you can even open it on any other computer on your local network! For example, your PI's computer. Gone are the days of single random examples that they make infinitely stubborn conclusions about. Now, you can look at all the examples, quickly and easily, on their computer. And that's why Syd stands for share your data!
45
+
46
+ Okay, so what is it? Syd is an automated system to convert some basic python plotting code into an interactive GUI. This means you only have to think about _**what**_ you want to plot and _**which**_ parameters you want to be interactive. Syd handles all the behind-the-scenes action required to make an interface. And do you know what that means? It means you get to spend your time _thinking_ about your data, rather than writing code to look at it. And that's why Syd stands for Science, Yes! Dayummmm!
47
+
48
+ ## Installation
49
+ It's easy, just use pip install. The dependencies are light so it should work in most environments.
50
+ ```bash
51
+ pip install syd
52
+ ```
53
+
54
+ ## Documentation
55
+ The full documentation is available at [shareyourdata.readthedocs.io](https://shareyourdata.readthedocs.io/). It includes a quick start guide, a comprehensive tutorial, and an API reference for the different elements of Syd. If you have any questions or want to suggest improvements to the docs, please let us know on the [github issues page](https://github.com/landoskape/syd/issues)!
56
+
57
+ ## Quick Start
58
+ This is an example of a sine wave viewer which is about as simple as it gets. You can choose which env to use - if you use ``env="notebook"`` then the GUI will deploy as the output of a jupyter cell (this only works in jupyter!). If you use ``env="browser"`` then the GUI will open a page in your default web browser and you can interact with the data there (works in jupyter notebooks and also from python scripts!).
59
+ ```python
60
+ import matplotlib.pyplot as plt
61
+ import numpy as np
62
+ from syd import make_viewer
63
+ def plot(viewer, state):
64
+ fig, ax = plt.subplots()
65
+ x = np.linspace(0, 10, 1000)
66
+ y = state['amplitude'] * np.sin(state['frequency'] * x)
67
+ ax.plot(x, y)
68
+ return fig
69
+
70
+ viewer = make_viewer()
71
+ viewer.set_plot(plot)
72
+ viewer.add_float('amplitude', value=1.0, min=0, max=2)
73
+ viewer.add_float('frequency', value=1.0, min=0.1, max=5)
74
+
75
+ # env = "browser" # for viewing in a web browser
76
+ env = "notebook" # for viewing within a jupyter notebook
77
+ viewer.deploy(env=env)
78
+ ```
79
+
80
+ ### More Examples
81
+ We have several examples of more complex viewers with detailed explanations in the comments. Here are the links and descriptions to each of them:
82
+
83
+ | Example | Description | Try It! |
84
+ |---------|-------------|---------------|
85
+ | [Basic Tutorial](examples/1-simple_example.ipynb) | A good starting point with detailed explanations of how to use the core elements of Syd. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/1-simple_example.ipynb) |
86
+ | [Comprehensive](examples/2a-complex_example.ipynb) | Showcases just about everything you can do with Syd. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/2a-complex_example.ipynb) |
87
+ | [Making a Viewer Class](examples/2b-subclass_example.ipynb) | Rewrites the comprehensive example as a class, which is useful when you have complex data processing or callbacks. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/2b-subclass_example.ipynb) |
88
+ | [Data Loading](examples/3-data_loading.ipynb) | Showcases different ways to get your data into a Syd viewer. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/3-data_loading.ipynb) |
89
+ | [Hierarchical Callbacks](examples/4-hierarchical_callbacks.ipynb) | Demonstrates how to handle complicated callback situations. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/4-hierarchical_callbacks.ipynb) |
90
+
91
+
92
+ ### Data loading
93
+ Thinking about how to get data into a Syd viewer can be non-intuitive. For some examples that showcase different ways to get your data into a Syd viewer, check out the [data loading example](examples/3-data_loading.ipynb). Or, if you just want a quick example, check this out:
94
+ ```python
95
+ import numpy as np
96
+ from matplotlib import pyplot as plt
97
+ from syd import make_viewer
98
+
99
+ # Suppose you computed some data somewhere (in a script or in a jupyter notebook)
100
+ data = np.random.randn(100, 1000)
101
+
102
+ # When you write a plot function like this, it'll be able to access the data variable
103
+ def plot(state):
104
+ fig = plt.figure()
105
+ ax = fig.add_subplot(111)
106
+
107
+ # plot indexes to the data that you created outside the plot function
108
+ ax.imshow(data[state["index"]])
109
+ return fig
110
+
111
+ # Since plot "knows" about the data variable, all you need to do is pass the plot
112
+ # function to the syd viewer and it'll be able to access the data once deployed!
113
+ viewer = make_viewer(plot)
114
+ viewer.deploy(env="browser")
115
+ ```
116
+
117
+ ### Handling Hierarchical Callbacks
118
+ Syd dramatically reduces the amount of work you need to do to build a GUI for viewing your data. However, it can still be a bit complicated to think about callbacks. Below is a quick demonstration, to try it yourself, check out the full example [here](examples/4-hierarchical_callbacks.ipynb).
119
+
120
+ For example, suppose your dataset is composed of electrophysiology recordings from 3 mice, where each mouse has a different number of sesssions, and each session has a different number of neurons. You want to build a viewer to choose the mouse, then choose the session, and then view a particular neuron from within that session. But the viewer will break if you try to index to session 5 for mouse 2 but mouse 2 only has 4 sessions!
121
+
122
+ This is where hierarchical callbacks come in. There's a straightforward pattern to handling this kind of situation that you can follow. You can write a callback for each **level** of the hierarchy. Then, each callback can call the next callback in the hierarchy. It looks like this:
123
+ ```python
124
+ import numpy as np
125
+ from syd import Viewer # Much easier to build a Viewer class for hierarchical callbacks
126
+
127
+ class MouseViewer(Viewer):
128
+ def __init__(self, mice_names):
129
+ self.mice_names = mice_names
130
+
131
+ self.add_selection("mouse", options=list(mice_names))
132
+
133
+ # We don't know how many sessions or neurons to pick from yet!
134
+ self.add_integer("session", min=0, max=1)
135
+ self.add_integer("neuron", min=0, max=1)
136
+
137
+ # Any time the mouse changes, update the sessions to pick from
138
+ self.on_change("mouse", self.update_mouse)
139
+
140
+ # Any time the session changes, update the neurons to pick from
141
+ self.on_change("session", self.update_session)
142
+
143
+ # Since we built callbacks for setting the range of the session
144
+ # and neuron parameters, we can use them here!
145
+ # To get the state, we can use self.state, which is the current
146
+ # state of the viewer (in the init function, it'll just be the
147
+ # default value for each parameter you've added already).
148
+ self.update_mouse(self.state)
149
+
150
+ def update_mouse(self, state):
151
+ # Pseudo code for getting the number of sessions for a given mouse
152
+ num_sessions = get_num_sessions(state["mouse"])
153
+
154
+ # Now we update the number of sessions to pick from
155
+ self.update_integer("session", max=num_sessions - 1)
156
+
157
+ # Now we need to update the neurons to choose from ....
158
+ # But! Updating the session parameter might trigger a change to the
159
+ # session value. So, instead of using the state dictionary that was
160
+ # passed into the function, we can get the ~NEW~ state dictionary like this:
161
+ new_state = self.state
162
+
163
+ # Then perform the session update callback!
164
+ self.update_session(new_state)
165
+
166
+ def update_session(self, state):
167
+ # Pseudo code for getting the number of neurons for a given mouse and session
168
+ num_neurons = get_num_neurons(state["mouse"], state["session"])
169
+
170
+ # Now we update the number of neurons to pick from
171
+ self.update_integer("neuron", max=num_neurons - 1)
172
+
173
+ def plot(self, state):
174
+ # Pseudo code for plotting the data
175
+ data = get_data(state["mouse"], state["session"], state["neuron"])
176
+ fig = plot_the_data(data)
177
+ return fig
178
+
179
+ # Now we can create a viewer and deploy it
180
+ viewer = MouseViewer(["Mouse 1", "Mouse 2", "Mouse 3"])
181
+ viewer.deploy(env="browser")
182
+ ```
183
+
184
+ ## License
185
+
186
+ This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
187
+
188
+ ## Contributing
189
+
190
+ Contributions are welcome! Here's how you can help:
191
+
192
+ 1. Fork the repository
193
+ 2. Create a new branch (`git checkout -b feature/amazing-feature`)
194
+ 3. Make your changes
195
+ 4. Run the tests (`pytest`)
196
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
197
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
198
+ 7. Open a Pull Request online
199
+
200
+ Please make sure to update tests as appropriate and adhere to the existing coding style (black, line-length=88, other style guidelines not capture by black, generally following pep8 guidelines).
201
+
202
+
203
+ ## To-Do List
204
+ - Layout controls
205
+ - [ ] Improve the display and make it look better
206
+ - [ ] Add a "save" button that saves the current state of the viewer to a json file
207
+ - [ ] Add a "load" button that loads the viewer state from a json file
208
+ - [ ] Add a "freeze" button that allows the user to update state variables without updating the plot until unfreezing
209
+ - [ ] Add a window for capturing any error messages that might be thrown by the plot function. Maybe we could have a little interface for looking at each one (up to a point) and the user could press a button to throw an error for the traceback.
210
+ - [ ] Consider "app_deployed" context for each deployer...
211
+ - [ ] Consider adding a step to the integer parameters...
212
+ - Idea for figure management:
213
+ - [ ] We could make fig=?, ax=? arguments optional for the plot function and add a
214
+ "recycle_figure: bool = False" flag be part of the deploy API. This way, an
215
+ advanced user that wants snappy responsivity or complex figure management can
216
+ do so, but the default is for the user to generate a new figure object each time.
217
+ - Export options:
218
+ - [ ] Export lite: export the viewer as a HTML/Java package that contains an incomplete set of renderings of figures -- using a certain set of parameters.
219
+ - [ ] Export full: export the viewer in a way that contains the data to give full functionality.
syd-1.0.0/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # Syd
2
+
3
+ [![PyPI version](https://badge.fury.io/py/syd.svg)](https://badge.fury.io/py/syd)
4
+ [![Tests](https://github.com/landoskape/syd/actions/workflows/tests.yml/badge.svg)](https://github.com/landoskape/syd/actions/workflows/tests.yml)
5
+ [![Documentation Status](https://readthedocs.org/projects/shareyourdata/badge/?version=stable)](https://shareyourdata.readthedocs.io/en/stable/?badge=stable)
6
+ [![codecov](https://codecov.io/gh/landoskape/syd/branch/main/graph/badge.svg)](https://codecov.io/gh/landoskape/syd)
7
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
8
+
9
+
10
+ A package to help you share your data!
11
+
12
+ Have you ever wanted to look through all your data really quickly interactively? Of course you have. Mo data mo problems, but only if you don't know what to do with it. And that's why Syd stands for show your data!
13
+
14
+ Syd is a system for creating a data viewing GUI that you can view in a jupyter notebook or in a web browser. And guess what? Since it can open in a web browser, you can even open it on any other computer on your local network! For example, your PI's computer. Gone are the days of single random examples that they make infinitely stubborn conclusions about. Now, you can look at all the examples, quickly and easily, on their computer. And that's why Syd stands for share your data!
15
+
16
+ Okay, so what is it? Syd is an automated system to convert some basic python plotting code into an interactive GUI. This means you only have to think about _**what**_ you want to plot and _**which**_ parameters you want to be interactive. Syd handles all the behind-the-scenes action required to make an interface. And do you know what that means? It means you get to spend your time _thinking_ about your data, rather than writing code to look at it. And that's why Syd stands for Science, Yes! Dayummmm!
17
+
18
+ ## Installation
19
+ It's easy, just use pip install. The dependencies are light so it should work in most environments.
20
+ ```bash
21
+ pip install syd
22
+ ```
23
+
24
+ ## Documentation
25
+ The full documentation is available at [shareyourdata.readthedocs.io](https://shareyourdata.readthedocs.io/). It includes a quick start guide, a comprehensive tutorial, and an API reference for the different elements of Syd. If you have any questions or want to suggest improvements to the docs, please let us know on the [github issues page](https://github.com/landoskape/syd/issues)!
26
+
27
+ ## Quick Start
28
+ This is an example of a sine wave viewer which is about as simple as it gets. You can choose which env to use - if you use ``env="notebook"`` then the GUI will deploy as the output of a jupyter cell (this only works in jupyter!). If you use ``env="browser"`` then the GUI will open a page in your default web browser and you can interact with the data there (works in jupyter notebooks and also from python scripts!).
29
+ ```python
30
+ import matplotlib.pyplot as plt
31
+ import numpy as np
32
+ from syd import make_viewer
33
+ def plot(viewer, state):
34
+ fig, ax = plt.subplots()
35
+ x = np.linspace(0, 10, 1000)
36
+ y = state['amplitude'] * np.sin(state['frequency'] * x)
37
+ ax.plot(x, y)
38
+ return fig
39
+
40
+ viewer = make_viewer()
41
+ viewer.set_plot(plot)
42
+ viewer.add_float('amplitude', value=1.0, min=0, max=2)
43
+ viewer.add_float('frequency', value=1.0, min=0.1, max=5)
44
+
45
+ # env = "browser" # for viewing in a web browser
46
+ env = "notebook" # for viewing within a jupyter notebook
47
+ viewer.deploy(env=env)
48
+ ```
49
+
50
+ ### More Examples
51
+ We have several examples of more complex viewers with detailed explanations in the comments. Here are the links and descriptions to each of them:
52
+
53
+ | Example | Description | Try It! |
54
+ |---------|-------------|---------------|
55
+ | [Basic Tutorial](examples/1-simple_example.ipynb) | A good starting point with detailed explanations of how to use the core elements of Syd. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/1-simple_example.ipynb) |
56
+ | [Comprehensive](examples/2a-complex_example.ipynb) | Showcases just about everything you can do with Syd. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/2a-complex_example.ipynb) |
57
+ | [Making a Viewer Class](examples/2b-subclass_example.ipynb) | Rewrites the comprehensive example as a class, which is useful when you have complex data processing or callbacks. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/2b-subclass_example.ipynb) |
58
+ | [Data Loading](examples/3-data_loading.ipynb) | Showcases different ways to get your data into a Syd viewer. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/3-data_loading.ipynb) |
59
+ | [Hierarchical Callbacks](examples/4-hierarchical_callbacks.ipynb) | Demonstrates how to handle complicated callback situations. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/landoskape/syd/blob/main/examples/4-hierarchical_callbacks.ipynb) |
60
+
61
+
62
+ ### Data loading
63
+ Thinking about how to get data into a Syd viewer can be non-intuitive. For some examples that showcase different ways to get your data into a Syd viewer, check out the [data loading example](examples/3-data_loading.ipynb). Or, if you just want a quick example, check this out:
64
+ ```python
65
+ import numpy as np
66
+ from matplotlib import pyplot as plt
67
+ from syd import make_viewer
68
+
69
+ # Suppose you computed some data somewhere (in a script or in a jupyter notebook)
70
+ data = np.random.randn(100, 1000)
71
+
72
+ # When you write a plot function like this, it'll be able to access the data variable
73
+ def plot(state):
74
+ fig = plt.figure()
75
+ ax = fig.add_subplot(111)
76
+
77
+ # plot indexes to the data that you created outside the plot function
78
+ ax.imshow(data[state["index"]])
79
+ return fig
80
+
81
+ # Since plot "knows" about the data variable, all you need to do is pass the plot
82
+ # function to the syd viewer and it'll be able to access the data once deployed!
83
+ viewer = make_viewer(plot)
84
+ viewer.deploy(env="browser")
85
+ ```
86
+
87
+ ### Handling Hierarchical Callbacks
88
+ Syd dramatically reduces the amount of work you need to do to build a GUI for viewing your data. However, it can still be a bit complicated to think about callbacks. Below is a quick demonstration, to try it yourself, check out the full example [here](examples/4-hierarchical_callbacks.ipynb).
89
+
90
+ For example, suppose your dataset is composed of electrophysiology recordings from 3 mice, where each mouse has a different number of sesssions, and each session has a different number of neurons. You want to build a viewer to choose the mouse, then choose the session, and then view a particular neuron from within that session. But the viewer will break if you try to index to session 5 for mouse 2 but mouse 2 only has 4 sessions!
91
+
92
+ This is where hierarchical callbacks come in. There's a straightforward pattern to handling this kind of situation that you can follow. You can write a callback for each **level** of the hierarchy. Then, each callback can call the next callback in the hierarchy. It looks like this:
93
+ ```python
94
+ import numpy as np
95
+ from syd import Viewer # Much easier to build a Viewer class for hierarchical callbacks
96
+
97
+ class MouseViewer(Viewer):
98
+ def __init__(self, mice_names):
99
+ self.mice_names = mice_names
100
+
101
+ self.add_selection("mouse", options=list(mice_names))
102
+
103
+ # We don't know how many sessions or neurons to pick from yet!
104
+ self.add_integer("session", min=0, max=1)
105
+ self.add_integer("neuron", min=0, max=1)
106
+
107
+ # Any time the mouse changes, update the sessions to pick from
108
+ self.on_change("mouse", self.update_mouse)
109
+
110
+ # Any time the session changes, update the neurons to pick from
111
+ self.on_change("session", self.update_session)
112
+
113
+ # Since we built callbacks for setting the range of the session
114
+ # and neuron parameters, we can use them here!
115
+ # To get the state, we can use self.state, which is the current
116
+ # state of the viewer (in the init function, it'll just be the
117
+ # default value for each parameter you've added already).
118
+ self.update_mouse(self.state)
119
+
120
+ def update_mouse(self, state):
121
+ # Pseudo code for getting the number of sessions for a given mouse
122
+ num_sessions = get_num_sessions(state["mouse"])
123
+
124
+ # Now we update the number of sessions to pick from
125
+ self.update_integer("session", max=num_sessions - 1)
126
+
127
+ # Now we need to update the neurons to choose from ....
128
+ # But! Updating the session parameter might trigger a change to the
129
+ # session value. So, instead of using the state dictionary that was
130
+ # passed into the function, we can get the ~NEW~ state dictionary like this:
131
+ new_state = self.state
132
+
133
+ # Then perform the session update callback!
134
+ self.update_session(new_state)
135
+
136
+ def update_session(self, state):
137
+ # Pseudo code for getting the number of neurons for a given mouse and session
138
+ num_neurons = get_num_neurons(state["mouse"], state["session"])
139
+
140
+ # Now we update the number of neurons to pick from
141
+ self.update_integer("neuron", max=num_neurons - 1)
142
+
143
+ def plot(self, state):
144
+ # Pseudo code for plotting the data
145
+ data = get_data(state["mouse"], state["session"], state["neuron"])
146
+ fig = plot_the_data(data)
147
+ return fig
148
+
149
+ # Now we can create a viewer and deploy it
150
+ viewer = MouseViewer(["Mouse 1", "Mouse 2", "Mouse 3"])
151
+ viewer.deploy(env="browser")
152
+ ```
153
+
154
+ ## License
155
+
156
+ This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
157
+
158
+ ## Contributing
159
+
160
+ Contributions are welcome! Here's how you can help:
161
+
162
+ 1. Fork the repository
163
+ 2. Create a new branch (`git checkout -b feature/amazing-feature`)
164
+ 3. Make your changes
165
+ 4. Run the tests (`pytest`)
166
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
167
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
168
+ 7. Open a Pull Request online
169
+
170
+ Please make sure to update tests as appropriate and adhere to the existing coding style (black, line-length=88, other style guidelines not capture by black, generally following pep8 guidelines).
171
+
172
+
173
+ ## To-Do List
174
+ - Layout controls
175
+ - [ ] Improve the display and make it look better
176
+ - [ ] Add a "save" button that saves the current state of the viewer to a json file
177
+ - [ ] Add a "load" button that loads the viewer state from a json file
178
+ - [ ] Add a "freeze" button that allows the user to update state variables without updating the plot until unfreezing
179
+ - [ ] Add a window for capturing any error messages that might be thrown by the plot function. Maybe we could have a little interface for looking at each one (up to a point) and the user could press a button to throw an error for the traceback.
180
+ - [ ] Consider "app_deployed" context for each deployer...
181
+ - [ ] Consider adding a step to the integer parameters...
182
+ - Idea for figure management:
183
+ - [ ] We could make fig=?, ax=? arguments optional for the plot function and add a
184
+ "recycle_figure: bool = False" flag be part of the deploy API. This way, an
185
+ advanced user that wants snappy responsivity or complex figure management can
186
+ do so, but the default is for the user to generate a new figure object each time.
187
+ - Export options:
188
+ - [ ] Export lite: export the viewer as a HTML/Java package that contains an incomplete set of renderings of figures -- using a certain set of parameters.
189
+ - [ ] Export full: export the viewer in a way that contains the data to give full functionality.
@@ -1,7 +1,7 @@
1
1
  from typing import Callable, Optional
2
2
  from .viewer import Viewer
3
3
 
4
- __version__ = "0.2.0"
4
+ __version__ = "1.0.0"
5
5
 
6
6
 
7
7
  def make_viewer(plot_func: Optional[Callable] = None):
@@ -0,0 +1 @@
1
+