syd 0.2.0__tar.gz → 1.0.1__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.1/PKG-INFO ADDED
@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.4
2
+ Name: syd
3
+ Version: 1.0.1
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
+ <div>
41
+ <img src="./docs/assets/syd-logo-white.png" alt="Syd" width="350" align="right"/>
42
+ </div>
43
+
44
+ A package to help you share your data!
45
+
46
+ 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!
47
+
48
+ 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!
49
+
50
+ 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 guess what? That 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!
51
+
52
+ ## Installation
53
+ It's easy, just use pip install. The dependencies are light so it should work in most environments.
54
+ ```bash
55
+ pip install syd
56
+ ```
57
+
58
+ ## Documentation
59
+ 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)!
60
+
61
+ ## Quick Start
62
+ <!-- <div style="float: right; margin-left: 100px; margin-bottom: 10px;">
63
+ <img src="./docs/assets/viewer_screenshots/readme_example_gif.gif" alt="Syd" width="300" align="right"/>
64
+ </div> -->
65
+
66
+ 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!).
67
+
68
+ ```python
69
+ import numpy as np
70
+ import matplotlib.pyplot as plt
71
+ from syd import make_viewer
72
+ def plot(state):
73
+ # Here's a simple plot function that plots a sine wave
74
+ fig = plt.figure()
75
+ t = np.linspace(0, 2 * np.pi, 1000)
76
+ ax = plt.gca()
77
+ ax.plot(t, state["amplitude"] * np.sin(state["frequency"] * t), color=state["color"])
78
+ return fig
79
+
80
+ viewer = make_viewer(plot)
81
+ viewer.add_float("amplitude", value=1.0, min=0.1, max=2.0)
82
+ viewer.add_float("frequency", value=1.0, min=0.1, max=5.0)
83
+ viewer.add_selection("color", value="red", options=["red", "blue", "green", "black"])
84
+
85
+ # env = "browser" # for viewing in a web browser (accessible via an IP address)
86
+ env = "notebook" # for viewing within a jupyter notebook
87
+ viewer = viewer.deploy(env=env)
88
+ ```
89
+
90
+ ![Quick Start Viewer](./docs/assets/viewer_screenshots/readme_example_gif.gif)
91
+ ### More Examples
92
+ We have several examples of more complex viewers with detailed explanations in the comments. Here are the links and descriptions to each of them:
93
+
94
+ | Example | Description | Try It! |
95
+ |---------|-------------|---------------|
96
+ | [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) |
97
+ | [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) |
98
+ | [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) |
99
+ | [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) |
100
+ | [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) |
101
+
102
+
103
+ ### Data loading
104
+ 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:
105
+ ```python
106
+ import numpy as np
107
+ from matplotlib import pyplot as plt
108
+ from syd import make_viewer
109
+
110
+ # Suppose you computed some data somewhere (in a script or in a jupyter notebook)
111
+ data = np.random.randn(100, 1000)
112
+
113
+ # When you write a plot function like this, it'll be able to access the data variable
114
+ def plot(state):
115
+ fig = plt.figure()
116
+ ax = fig.add_subplot(111)
117
+
118
+ # plot indexes to the data that you created outside the plot function
119
+ ax.imshow(data[state["index"]])
120
+ return fig
121
+
122
+ # Since plot "knows" about the data variable, all you need to do is pass the plot
123
+ # function to the syd viewer and it'll be able to access the data once deployed!
124
+ viewer = make_viewer(plot)
125
+ viewer.deploy(env="browser")
126
+ ```
127
+
128
+ ### Handling Hierarchical Callbacks
129
+ 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).
130
+
131
+ 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!
132
+
133
+ 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:
134
+ ```python
135
+ import numpy as np
136
+ from syd import Viewer # Much easier to build a Viewer class for hierarchical callbacks
137
+
138
+ class MouseViewer(Viewer):
139
+ def __init__(self, mice_names):
140
+ self.mice_names = mice_names
141
+
142
+ self.add_selection("mouse", options=list(mice_names))
143
+
144
+ # We don't know how many sessions or neurons to pick from yet!
145
+ self.add_integer("session", min=0, max=1)
146
+ self.add_integer("neuron", min=0, max=1)
147
+
148
+ # Any time the mouse changes, update the sessions to pick from
149
+ self.on_change("mouse", self.update_mouse)
150
+
151
+ # Any time the session changes, update the neurons to pick from
152
+ self.on_change("session", self.update_session)
153
+
154
+ # Since we built callbacks for setting the range of the session
155
+ # and neuron parameters, we can use them here!
156
+ # To get the state, we can use self.state, which is the current
157
+ # state of the viewer (in the init function, it'll just be the
158
+ # default value for each parameter you've added already).
159
+ self.update_mouse(self.state)
160
+
161
+ def update_mouse(self, state):
162
+ # Pseudo code for getting the number of sessions for a given mouse
163
+ num_sessions = get_num_sessions(state["mouse"])
164
+
165
+ # Now we update the number of sessions to pick from
166
+ self.update_integer("session", max=num_sessions - 1)
167
+
168
+ # Now we need to update the neurons to choose from ....
169
+ # But! Updating the session parameter might trigger a change to the
170
+ # session value. So, instead of using the state dictionary that was
171
+ # passed into the function, we can get the ~NEW~ state dictionary like this:
172
+ new_state = self.state
173
+
174
+ # Then perform the session update callback!
175
+ self.update_session(new_state)
176
+
177
+ def update_session(self, state):
178
+ # Pseudo code for getting the number of neurons for a given mouse and session
179
+ num_neurons = get_num_neurons(state["mouse"], state["session"])
180
+
181
+ # Now we update the number of neurons to pick from
182
+ self.update_integer("neuron", max=num_neurons - 1)
183
+
184
+ def plot(self, state):
185
+ # Pseudo code for plotting the data
186
+ data = get_data(state["mouse"], state["session"], state["neuron"])
187
+ fig = plot_the_data(data)
188
+ return fig
189
+
190
+ # Now we can create a viewer and deploy it
191
+ viewer = MouseViewer(["Mouse 1", "Mouse 2", "Mouse 3"])
192
+ viewer.deploy(env="browser")
193
+ ```
194
+
195
+ ## License
196
+
197
+ This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
198
+
199
+ ## Contributing
200
+
201
+ Contributions are welcome! Here's how you can help:
202
+
203
+ 1. Fork the repository
204
+ 2. Create a new branch (`git checkout -b feature/amazing-feature`)
205
+ 3. Make your changes
206
+ 4. Run the tests (`pytest`)
207
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
208
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
209
+ 7. Open a Pull Request online
210
+
211
+ 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). Try to make the code coverage report improve or stay the same rather than decrease (right now the deployment system isn't covered by tests). I don't have any precommit hooks or anything so you're responsible for checking this yourself. You can process the code with black as follows:
212
+ ```bash
213
+ pip install black
214
+ black . # from the root directory of the repo
215
+ ```
216
+
217
+ ## To-Do List
218
+ - Layout controls
219
+ - [ ] Improve the display and make it look better
220
+ - [ ] Add a "save" button that saves the current state of the viewer to a json file
221
+ - [ ] Add a "load" button that loads the viewer state from a json file
222
+ - [ ] Add a "freeze" button that allows the user to update state variables without updating the plot until unfreezing
223
+ - [ ] 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.
224
+ - [ ] Consider "app_deployed" context for each deployer...
225
+ - Export options:
226
+ - [ ] 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.
227
+ - [ ] Export full: export the viewer in a way that contains the data to give full functionality.
228
+ - [ ] Keep deploy() for backwards compatibility, but deprecate it in favor of show() and share() (for notebook and browser, respectively)
syd-1.0.1/README.md ADDED
@@ -0,0 +1,198 @@
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
+ <div>
11
+ <img src="./docs/assets/syd-logo-white.png" alt="Syd" width="350" align="right"/>
12
+ </div>
13
+
14
+ A package to help you share your data!
15
+
16
+ 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!
17
+
18
+ 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!
19
+
20
+ 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 guess what? That 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!
21
+
22
+ ## Installation
23
+ It's easy, just use pip install. The dependencies are light so it should work in most environments.
24
+ ```bash
25
+ pip install syd
26
+ ```
27
+
28
+ ## Documentation
29
+ 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)!
30
+
31
+ ## Quick Start
32
+ <!-- <div style="float: right; margin-left: 100px; margin-bottom: 10px;">
33
+ <img src="./docs/assets/viewer_screenshots/readme_example_gif.gif" alt="Syd" width="300" align="right"/>
34
+ </div> -->
35
+
36
+ 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!).
37
+
38
+ ```python
39
+ import numpy as np
40
+ import matplotlib.pyplot as plt
41
+ from syd import make_viewer
42
+ def plot(state):
43
+ # Here's a simple plot function that plots a sine wave
44
+ fig = plt.figure()
45
+ t = np.linspace(0, 2 * np.pi, 1000)
46
+ ax = plt.gca()
47
+ ax.plot(t, state["amplitude"] * np.sin(state["frequency"] * t), color=state["color"])
48
+ return fig
49
+
50
+ viewer = make_viewer(plot)
51
+ viewer.add_float("amplitude", value=1.0, min=0.1, max=2.0)
52
+ viewer.add_float("frequency", value=1.0, min=0.1, max=5.0)
53
+ viewer.add_selection("color", value="red", options=["red", "blue", "green", "black"])
54
+
55
+ # env = "browser" # for viewing in a web browser (accessible via an IP address)
56
+ env = "notebook" # for viewing within a jupyter notebook
57
+ viewer = viewer.deploy(env=env)
58
+ ```
59
+
60
+ ![Quick Start Viewer](./docs/assets/viewer_screenshots/readme_example_gif.gif)
61
+ ### More Examples
62
+ We have several examples of more complex viewers with detailed explanations in the comments. Here are the links and descriptions to each of them:
63
+
64
+ | Example | Description | Try It! |
65
+ |---------|-------------|---------------|
66
+ | [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) |
67
+ | [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) |
68
+ | [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) |
69
+ | [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) |
70
+ | [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) |
71
+
72
+
73
+ ### Data loading
74
+ 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:
75
+ ```python
76
+ import numpy as np
77
+ from matplotlib import pyplot as plt
78
+ from syd import make_viewer
79
+
80
+ # Suppose you computed some data somewhere (in a script or in a jupyter notebook)
81
+ data = np.random.randn(100, 1000)
82
+
83
+ # When you write a plot function like this, it'll be able to access the data variable
84
+ def plot(state):
85
+ fig = plt.figure()
86
+ ax = fig.add_subplot(111)
87
+
88
+ # plot indexes to the data that you created outside the plot function
89
+ ax.imshow(data[state["index"]])
90
+ return fig
91
+
92
+ # Since plot "knows" about the data variable, all you need to do is pass the plot
93
+ # function to the syd viewer and it'll be able to access the data once deployed!
94
+ viewer = make_viewer(plot)
95
+ viewer.deploy(env="browser")
96
+ ```
97
+
98
+ ### Handling Hierarchical Callbacks
99
+ 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).
100
+
101
+ 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!
102
+
103
+ 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:
104
+ ```python
105
+ import numpy as np
106
+ from syd import Viewer # Much easier to build a Viewer class for hierarchical callbacks
107
+
108
+ class MouseViewer(Viewer):
109
+ def __init__(self, mice_names):
110
+ self.mice_names = mice_names
111
+
112
+ self.add_selection("mouse", options=list(mice_names))
113
+
114
+ # We don't know how many sessions or neurons to pick from yet!
115
+ self.add_integer("session", min=0, max=1)
116
+ self.add_integer("neuron", min=0, max=1)
117
+
118
+ # Any time the mouse changes, update the sessions to pick from
119
+ self.on_change("mouse", self.update_mouse)
120
+
121
+ # Any time the session changes, update the neurons to pick from
122
+ self.on_change("session", self.update_session)
123
+
124
+ # Since we built callbacks for setting the range of the session
125
+ # and neuron parameters, we can use them here!
126
+ # To get the state, we can use self.state, which is the current
127
+ # state of the viewer (in the init function, it'll just be the
128
+ # default value for each parameter you've added already).
129
+ self.update_mouse(self.state)
130
+
131
+ def update_mouse(self, state):
132
+ # Pseudo code for getting the number of sessions for a given mouse
133
+ num_sessions = get_num_sessions(state["mouse"])
134
+
135
+ # Now we update the number of sessions to pick from
136
+ self.update_integer("session", max=num_sessions - 1)
137
+
138
+ # Now we need to update the neurons to choose from ....
139
+ # But! Updating the session parameter might trigger a change to the
140
+ # session value. So, instead of using the state dictionary that was
141
+ # passed into the function, we can get the ~NEW~ state dictionary like this:
142
+ new_state = self.state
143
+
144
+ # Then perform the session update callback!
145
+ self.update_session(new_state)
146
+
147
+ def update_session(self, state):
148
+ # Pseudo code for getting the number of neurons for a given mouse and session
149
+ num_neurons = get_num_neurons(state["mouse"], state["session"])
150
+
151
+ # Now we update the number of neurons to pick from
152
+ self.update_integer("neuron", max=num_neurons - 1)
153
+
154
+ def plot(self, state):
155
+ # Pseudo code for plotting the data
156
+ data = get_data(state["mouse"], state["session"], state["neuron"])
157
+ fig = plot_the_data(data)
158
+ return fig
159
+
160
+ # Now we can create a viewer and deploy it
161
+ viewer = MouseViewer(["Mouse 1", "Mouse 2", "Mouse 3"])
162
+ viewer.deploy(env="browser")
163
+ ```
164
+
165
+ ## License
166
+
167
+ This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
168
+
169
+ ## Contributing
170
+
171
+ Contributions are welcome! Here's how you can help:
172
+
173
+ 1. Fork the repository
174
+ 2. Create a new branch (`git checkout -b feature/amazing-feature`)
175
+ 3. Make your changes
176
+ 4. Run the tests (`pytest`)
177
+ 5. Commit your changes (`git commit -m 'Add amazing feature'`)
178
+ 6. Push to the branch (`git push origin feature/amazing-feature`)
179
+ 7. Open a Pull Request online
180
+
181
+ 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). Try to make the code coverage report improve or stay the same rather than decrease (right now the deployment system isn't covered by tests). I don't have any precommit hooks or anything so you're responsible for checking this yourself. You can process the code with black as follows:
182
+ ```bash
183
+ pip install black
184
+ black . # from the root directory of the repo
185
+ ```
186
+
187
+ ## To-Do List
188
+ - Layout controls
189
+ - [ ] Improve the display and make it look better
190
+ - [ ] Add a "save" button that saves the current state of the viewer to a json file
191
+ - [ ] Add a "load" button that loads the viewer state from a json file
192
+ - [ ] Add a "freeze" button that allows the user to update state variables without updating the plot until unfreezing
193
+ - [ ] 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.
194
+ - [ ] Consider "app_deployed" context for each deployer...
195
+ - Export options:
196
+ - [ ] 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.
197
+ - [ ] Export full: export the viewer in a way that contains the data to give full functionality.
198
+ - [ ] Keep deploy() for backwards compatibility, but deprecate it in favor of show() and share() (for notebook and browser, respectively)
@@ -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.1"
5
5
 
6
6
 
7
7
  def make_viewer(plot_func: Optional[Callable] = None):
@@ -0,0 +1 @@
1
+