figpack 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl

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.

Potentially problematic release.


This version of figpack might be problematic. Click here for more details.

Files changed (31) hide show
  1. figpack/__init__.py +5 -1
  2. figpack/cli.py +2 -118
  3. figpack/core/_bundle_utils.py +5 -6
  4. figpack/core/_save_figure.py +31 -0
  5. figpack/core/_server_manager.py +0 -2
  6. figpack/core/_show_view.py +22 -22
  7. figpack/core/_upload_bundle.py +61 -22
  8. figpack/core/_view_figure.py +138 -0
  9. figpack/core/figpack_view.py +74 -25
  10. figpack/{figpack-gui-dist/assets/index-CuFseOGX.js → figpack-figure-dist/assets/index-HXdk2TtM.js} +58 -58
  11. figpack/{figpack-gui-dist → figpack-figure-dist}/index.html +1 -1
  12. figpack/spike_sorting/views/Autocorrelograms.py +29 -19
  13. figpack/spike_sorting/views/CrossCorrelograms.py +29 -19
  14. figpack/spike_sorting/views/UnitsTable.py +27 -8
  15. figpack/views/Gallery.py +88 -0
  16. figpack/views/GalleryItem.py +47 -0
  17. figpack/views/Image.py +37 -0
  18. figpack/views/Markdown.py +12 -2
  19. figpack/views/MatplotlibFigure.py +26 -3
  20. figpack/views/PlotlyFigure.py +18 -2
  21. figpack/views/__init__.py +2 -0
  22. figpack-0.2.6.dist-info/METADATA +96 -0
  23. figpack-0.2.6.dist-info/RECORD +53 -0
  24. figpack-0.2.4.dist-info/METADATA +0 -168
  25. figpack-0.2.4.dist-info/RECORD +0 -49
  26. /figpack/{figpack-gui-dist → figpack-figure-dist}/assets/index-Cmae55E4.css +0 -0
  27. /figpack/{figpack-gui-dist → figpack-figure-dist}/assets/neurosift-logo-CLsuwLMO.png +0 -0
  28. {figpack-0.2.4.dist-info → figpack-0.2.6.dist-info}/WHEEL +0 -0
  29. {figpack-0.2.4.dist-info → figpack-0.2.6.dist-info}/entry_points.txt +0 -0
  30. {figpack-0.2.4.dist-info → figpack-0.2.6.dist-info}/licenses/LICENSE +0 -0
  31. {figpack-0.2.4.dist-info → figpack-0.2.6.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/png" href="./assets/neurosift-logo-CLsuwLMO.png" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>figpack figure</title>
8
- <script type="module" crossorigin src="./assets/index-CuFseOGX.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-HXdk2TtM.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-Cmae55E4.css">
10
10
  </head>
11
11
  <body>
@@ -77,32 +77,42 @@ class Autocorrelograms(FigpackView):
77
77
  group.attrs["view_type"] = "Autocorrelograms"
78
78
 
79
79
  # Store the number of autocorrelograms
80
- group.attrs["num_autocorrelograms"] = len(self.autocorrelograms)
80
+ num_autocorrelograms = len(self.autocorrelograms)
81
+ group.attrs["num_autocorrelograms"] = num_autocorrelograms
81
82
 
82
- # Store metadata for each autocorrelogram
83
+ if num_autocorrelograms == 0:
84
+ return
85
+
86
+ # Get dimensions from first autocorrelogram
87
+ num_bins = len(self.autocorrelograms[0].bin_counts)
88
+
89
+ # Store bin edges (same for all autocorrelograms)
90
+ group.create_dataset(
91
+ "bin_edges_sec",
92
+ data=self.autocorrelograms[0].bin_edges_sec,
93
+ dtype=np.float32,
94
+ )
95
+
96
+ # Create 2D array for all bin counts
97
+ bin_counts = np.zeros((num_autocorrelograms, num_bins), dtype=np.int32)
98
+
99
+ # Store metadata for each autocorrelogram and populate bin counts array
83
100
  autocorrelogram_metadata = []
84
101
  for i, autocorr in enumerate(self.autocorrelograms):
85
- autocorr_name = f"autocorrelogram_{i}"
86
-
87
- # Store metadata
88
102
  metadata = {
89
- "name": autocorr_name,
90
103
  "unit_id": str(autocorr.unit_id),
91
- "num_bins": len(autocorr.bin_counts),
104
+ "index": i, # Store index to map to bin_counts array
105
+ "num_bins": num_bins,
92
106
  }
93
107
  autocorrelogram_metadata.append(metadata)
94
-
95
- # Create arrays for this autocorrelogram
96
- group.create_dataset(
97
- f"{autocorr_name}/bin_edges_sec",
98
- data=autocorr.bin_edges_sec,
99
- dtype=np.float32,
100
- )
101
- group.create_dataset(
102
- f"{autocorr_name}/bin_counts",
103
- data=autocorr.bin_counts,
104
- dtype=np.int32,
105
- )
108
+ bin_counts[i] = autocorr.bin_counts
109
+
110
+ # Store the bin counts as a single 2D dataset
111
+ group.create_dataset(
112
+ "bin_counts",
113
+ data=bin_counts,
114
+ dtype=np.int32,
115
+ )
106
116
 
107
117
  # Store the autocorrelogram metadata
108
118
  group.attrs["autocorrelograms"] = autocorrelogram_metadata
@@ -90,33 +90,43 @@ class CrossCorrelograms(FigpackView):
90
90
  group.attrs["hide_unit_selector"] = self.hide_unit_selector
91
91
 
92
92
  # Store the number of cross-correlograms
93
- group.attrs["num_cross_correlograms"] = len(self.cross_correlograms)
93
+ num_cross_correlograms = len(self.cross_correlograms)
94
+ group.attrs["num_cross_correlograms"] = num_cross_correlograms
94
95
 
95
- # Store metadata for each cross-correlogram
96
+ if num_cross_correlograms == 0:
97
+ return
98
+
99
+ # Get dimensions from first cross-correlogram
100
+ num_bins = len(self.cross_correlograms[0].bin_counts)
101
+
102
+ # Store bin edges (same for all cross-correlograms)
103
+ group.create_dataset(
104
+ "bin_edges_sec",
105
+ data=self.cross_correlograms[0].bin_edges_sec,
106
+ dtype=np.float32,
107
+ )
108
+
109
+ # Create 2D array for all bin counts
110
+ bin_counts = np.zeros((num_cross_correlograms, num_bins), dtype=np.int32)
111
+
112
+ # Store metadata for each cross-correlogram and populate bin counts array
96
113
  cross_correlogram_metadata = []
97
114
  for i, cross_corr in enumerate(self.cross_correlograms):
98
- cross_corr_name = f"cross_correlogram_{i}"
99
-
100
- # Store metadata
101
115
  metadata = {
102
- "name": cross_corr_name,
103
116
  "unit_id1": str(cross_corr.unit_id1),
104
117
  "unit_id2": str(cross_corr.unit_id2),
105
- "num_bins": len(cross_corr.bin_counts),
118
+ "index": i, # Store index to map to bin_counts array
119
+ "num_bins": num_bins,
106
120
  }
107
121
  cross_correlogram_metadata.append(metadata)
108
-
109
- # Create arrays for this cross-correlogram
110
- group.create_dataset(
111
- f"{cross_corr_name}/bin_edges_sec",
112
- data=cross_corr.bin_edges_sec,
113
- dtype=np.float32,
114
- )
115
- group.create_dataset(
116
- f"{cross_corr_name}/bin_counts",
117
- data=cross_corr.bin_counts,
118
- dtype=np.int32,
119
- )
122
+ bin_counts[i] = cross_corr.bin_counts
123
+
124
+ # Store the bin counts as a single 2D dataset
125
+ group.create_dataset(
126
+ "bin_counts",
127
+ data=bin_counts,
128
+ dtype=np.int32,
129
+ )
120
130
 
121
131
  # Store the cross-correlogram metadata
122
132
  group.attrs["cross_correlograms"] = cross_correlogram_metadata
@@ -3,6 +3,7 @@ UnitsTable view for figpack - displays a table of units with their properties
3
3
  """
4
4
 
5
5
  from typing import List, Optional
6
+ import json
6
7
 
7
8
  import numpy as np
8
9
  import zarr
@@ -58,13 +59,31 @@ class UnitsTable(FigpackView):
58
59
  columns_metadata = [col.to_dict() for col in self.columns]
59
60
  group.attrs["columns"] = columns_metadata
60
61
 
61
- # Store rows metadata
62
- rows_metadata = [row.to_dict() for row in self.rows]
63
- group.attrs["rows"] = rows_metadata
62
+ # Store rows data in a zarr array
63
+ rows_data = [row.to_dict() for row in self.rows]
64
+ rows_json = json.dumps(rows_data).encode("utf-8")
65
+ rows_array = np.frombuffer(rows_json, dtype=np.uint8)
66
+ group.create_dataset(
67
+ "rows_data",
68
+ data=rows_array,
69
+ dtype=np.uint8,
70
+ chunks=True,
71
+ compressor=zarr.Blosc(cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE),
72
+ )
73
+ group.attrs["rows_data_size"] = len(rows_json)
64
74
 
65
- # Store similarity scores if provided
75
+ # Store similarity scores in a zarr array
66
76
  if self.similarity_scores:
67
- similarity_scores_metadata = [
68
- score.to_dict() for score in self.similarity_scores
69
- ]
70
- group.attrs["similarityScores"] = similarity_scores_metadata
77
+ scores_data = [score.to_dict() for score in self.similarity_scores]
78
+ scores_json = json.dumps(scores_data).encode("utf-8")
79
+ scores_array = np.frombuffer(scores_json, dtype=np.uint8)
80
+ group.create_dataset(
81
+ "similarity_scores_data",
82
+ data=scores_array,
83
+ dtype=np.uint8,
84
+ chunks=True,
85
+ compressor=zarr.Blosc(
86
+ cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE
87
+ ),
88
+ )
89
+ group.attrs["similarity_scores_data_size"] = len(scores_json)
@@ -0,0 +1,88 @@
1
+ """
2
+ Gallery view for figpack - a gallery layout container that handles other views with separate timeseries contexts
3
+ """
4
+
5
+ from typing import Any, Dict, List, Optional
6
+
7
+ import zarr
8
+
9
+ from ..core.figpack_view import FigpackView
10
+ from .GalleryItem import GalleryItem
11
+
12
+
13
+ class Gallery(FigpackView):
14
+ """
15
+ A gallery layout container view that arranges other views in a gallery format.
16
+
17
+ The Gallery view is functionally similar to TabLayout, but with a key difference:
18
+ each gallery item maintains its own independent timeseries selection context.
19
+ This means that time range selections, current time, and visible time ranges
20
+ are isolated between different gallery items, allowing for independent navigation
21
+ and analysis of timeseries data in each item.
22
+
23
+ This is particularly useful when comparing different datasets or views that
24
+ should not share the same time selection state.
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ *,
30
+ items: List[GalleryItem],
31
+ initial_item_index: int = 0,
32
+ ):
33
+ """
34
+ Initialize a Gallery view
35
+
36
+ Args:
37
+ items: List of GalleryItem objects containing the child views.
38
+ Each item will have its own independent timeseries selection context.
39
+ initial_item_index: Index of the initially selected gallery item (default: 0).
40
+ Will be clamped to valid range if out of bounds.
41
+ """
42
+ self.items = items
43
+ # Ensure initial_item_index is within valid bounds
44
+ self.initial_item_index = (
45
+ max(0, min(initial_item_index, len(items) - 1)) if items else 0
46
+ )
47
+
48
+ def _write_to_zarr_group(self, group: zarr.Group) -> None:
49
+ """
50
+ Write the Gallery data to a Zarr group
51
+
52
+ This method serializes the gallery structure and all its child views
53
+ into a Zarr group format that can be read by the frontend components.
54
+ Each gallery item's view is written to its own subgroup within the
55
+ main gallery group.
56
+
57
+ Args:
58
+ group: Zarr group to write data into
59
+ """
60
+ # Set the view type identifier for the frontend
61
+ group.attrs["view_type"] = "Gallery"
62
+
63
+ # Store gallery-specific properties
64
+ group.attrs["initial_item_index"] = self.initial_item_index
65
+
66
+ # Create a list to store metadata for all gallery items
67
+ items_metadata = []
68
+
69
+ # Process each gallery item
70
+ for i, item in enumerate(self.items):
71
+ # Generate a unique name for this item's subgroup
72
+ item_name = f"gallery_item_{i}"
73
+
74
+ # Store item metadata (label, etc.) for the frontend
75
+ item_metadata = item.to_dict()
76
+ item_metadata["name"] = item_name
77
+ items_metadata.append(item_metadata)
78
+
79
+ # Create a subgroup for this gallery item's view
80
+ item_group = group.create_group(item_name)
81
+
82
+ # Recursively write the child view to the subgroup
83
+ # This allows any figpack view to be contained within a gallery item
84
+ item.view._write_to_zarr_group(item_group)
85
+
86
+ # Store the complete items metadata in the group attributes
87
+ # This will be used by the frontend to render the gallery structure
88
+ group.attrs["items"] = items_metadata
@@ -0,0 +1,47 @@
1
+ """
2
+ GalleryItem class for figpack Gallery view - represents an item in a gallery layout container
3
+ """
4
+
5
+ from typing import Optional
6
+
7
+ from ..core.figpack_view import FigpackView
8
+
9
+
10
+ class GalleryItem:
11
+ """
12
+ Represents an item in a Gallery with a label and view.
13
+
14
+ Similar to TabLayoutItem, but designed for gallery layouts where each item
15
+ maintains its own independent timeseries selection context.
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ view: FigpackView,
21
+ *,
22
+ label: str,
23
+ ):
24
+ """
25
+ Initialize a GalleryItem
26
+
27
+ Args:
28
+ view: The figpack view to be contained in this gallery item
29
+ label: The label text to display for this gallery item
30
+ """
31
+ self.view = view
32
+ self.label = label
33
+
34
+ def to_dict(self) -> dict:
35
+ """
36
+ Convert the GalleryItem to a dictionary for serialization
37
+
38
+ This method is used when writing the gallery data to Zarr format.
39
+ The dictionary contains metadata about the item that will be stored
40
+ in the Zarr group attributes.
41
+
42
+ Returns:
43
+ Dictionary representation of the GalleryItem containing the label
44
+ """
45
+ return {
46
+ "label": self.label,
47
+ }
figpack/views/Image.py CHANGED
@@ -32,6 +32,43 @@ class Image(FigpackView):
32
32
 
33
33
  self.image_path_or_data = image_path_or_data
34
34
 
35
+ @staticmethod
36
+ def from_image_file(image_path: str) -> "Image":
37
+ """
38
+ Create an Image view from a file path
39
+
40
+ Args:
41
+ image_path: Path to the image file
42
+
43
+ Returns:
44
+ An Image view instance
45
+ """
46
+ return Image(image_path)
47
+
48
+ @staticmethod
49
+ def from_image_url(image_url: str) -> "Image":
50
+ """
51
+ Create an Image view from an image URL by downloading the image
52
+
53
+ Args:
54
+ image_url: URL of the image to download
55
+
56
+ Returns:
57
+ An Image view instance
58
+
59
+ Raises:
60
+ ValueError: If the image cannot be downloaded
61
+ """
62
+ import requests
63
+
64
+ try:
65
+ response = requests.get(image_url)
66
+ response.raise_for_status()
67
+ image_data = response.content
68
+ return Image(image_data)
69
+ except Exception as e:
70
+ raise ValueError(f"Failed to download image from URL: {str(e)}")
71
+
35
72
  def _write_to_zarr_group(self, group: zarr.Group) -> None:
36
73
  """
37
74
  Write the image data to a Zarr group
figpack/views/Markdown.py CHANGED
@@ -2,6 +2,7 @@
2
2
  Markdown view for figpack - displays markdown content
3
3
  """
4
4
 
5
+ import numpy as np
5
6
  import zarr
6
7
 
7
8
  from ..core.figpack_view import FigpackView
@@ -31,5 +32,14 @@ class Markdown(FigpackView):
31
32
  # Set the view type
32
33
  group.attrs["view_type"] = "Markdown"
33
34
 
34
- # Store the markdown content
35
- group.attrs["content"] = self.content
35
+ # Convert string content to numpy array of bytes
36
+ content_bytes = self.content.encode("utf-8")
37
+ content_array = np.frombuffer(content_bytes, dtype=np.uint8)
38
+
39
+ # Store the markdown content as a zarr array
40
+ group.create_dataset(
41
+ "content_data", data=content_array, dtype=np.uint8, chunks=True
42
+ )
43
+
44
+ # Store content size in attrs
45
+ group.attrs["data_size"] = len(content_bytes)
@@ -3,6 +3,7 @@ MatplotlibFigure view for figpack - displays matplotlib figures
3
3
  """
4
4
 
5
5
  import io
6
+ import numpy as np
6
7
  from typing import Any, Union
7
8
 
8
9
  import zarr
@@ -47,8 +48,18 @@ class MatplotlibFigure(FigpackView):
47
48
  svg_string = svg_buffer.getvalue()
48
49
  svg_buffer.close()
49
50
 
50
- # Store the SVG data
51
- group.attrs["svg_data"] = svg_string
51
+ # Convert SVG string to numpy array and store in zarr array
52
+ svg_bytes = svg_string.encode("utf-8")
53
+ svg_array = np.frombuffer(svg_bytes, dtype=np.uint8)
54
+ group.create_dataset(
55
+ "svg_data",
56
+ data=svg_array,
57
+ dtype=np.uint8,
58
+ chunks=True,
59
+ compressor=zarr.Blosc(
60
+ cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE
61
+ ),
62
+ )
52
63
 
53
64
  # Store figure dimensions for reference
54
65
  fig_width, fig_height = self.fig.get_size_inches()
@@ -58,10 +69,22 @@ class MatplotlibFigure(FigpackView):
58
69
  # Store DPI for reference
59
70
  group.attrs["figure_dpi"] = float(self.fig.dpi)
60
71
 
72
+ # Store data size for reference
73
+ group.attrs["data_size"] = len(svg_bytes)
74
+
61
75
  except Exception as e:
62
76
  # If SVG export fails, store error information
63
- group.attrs["svg_data"] = ""
77
+ group.create_dataset(
78
+ "svg_data",
79
+ data=np.array([], dtype=np.uint8),
80
+ dtype=np.uint8,
81
+ chunks=True,
82
+ compressor=zarr.Blosc(
83
+ cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE
84
+ ),
85
+ )
64
86
  group.attrs["error"] = f"Failed to export matplotlib figure: {str(e)}"
65
87
  group.attrs["figure_width_inches"] = 6.0
66
88
  group.attrs["figure_height_inches"] = 4.0
67
89
  group.attrs["figure_dpi"] = 100.0
90
+ group.attrs["data_size"] = 0
@@ -56,5 +56,21 @@ class PlotlyFigure(FigpackView):
56
56
  # Convert the plotly figure to a dictionary
57
57
  fig_dict = self.fig.to_dict()
58
58
 
59
- # Store the figure data as JSON string using custom encoder
60
- group.attrs["figure_data"] = json.dumps(fig_dict, cls=CustomJSONEncoder)
59
+ # Convert figure data to JSON string using custom encoder
60
+ json_string = json.dumps(fig_dict, cls=CustomJSONEncoder)
61
+
62
+ # Convert JSON string to bytes and store in numpy array
63
+ json_bytes = json_string.encode("utf-8")
64
+ json_array = np.frombuffer(json_bytes, dtype=np.uint8)
65
+
66
+ # Store the figure data as compressed array
67
+ group.create_dataset(
68
+ "figure_data",
69
+ data=json_array,
70
+ dtype=np.uint8,
71
+ chunks=True,
72
+ compressor=zarr.Blosc(cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE),
73
+ )
74
+
75
+ # Store data size for reference
76
+ group.attrs["data_size"] = len(json_bytes)
figpack/views/__init__.py CHANGED
@@ -1,4 +1,6 @@
1
1
  from .Box import Box
2
+ from .Gallery import Gallery
3
+ from .GalleryItem import GalleryItem
2
4
  from .Image import Image
3
5
  from .LayoutItem import LayoutItem
4
6
  from .Markdown import Markdown
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: figpack
3
+ Version: 0.2.6
4
+ Summary: A Python package for creating shareable, interactive visualizations in the browser
5
+ Author-email: Jeremy Magland <jmagland@flatironinstitute.org>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/flatironinstitute/figpack
8
+ Project-URL: Repository, https://github.com/flatironinstitute/figpack
9
+ Project-URL: Documentation, https://flatironinstitute.github.io/figpack
10
+ Project-URL: Bug Tracker, https://github.com/flatironinstitute/figpack/issues
11
+ Keywords: visualization,plotting,timeseries,interactive
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Scientific/Engineering :: Visualization
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: numpy
28
+ Requires-Dist: zarr<3
29
+ Requires-Dist: requests
30
+ Requires-Dist: psutil
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest>=7.0; extra == "test"
33
+ Requires-Dist: pytest-cov>=4.0; extra == "test"
34
+ Requires-Dist: pytest-mock>=3.10; extra == "test"
35
+ Requires-Dist: spikeinterface; extra == "test"
36
+ Requires-Dist: matplotlib; extra == "test"
37
+ Requires-Dist: plotly; extra == "test"
38
+ Requires-Dist: Pillow; extra == "test"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=7.0; extra == "dev"
41
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
42
+ Requires-Dist: pytest-mock>=3.10; extra == "dev"
43
+ Requires-Dist: black>=24.0; extra == "dev"
44
+ Requires-Dist: pre-commit>=3.0; extra == "dev"
45
+ Provides-Extra: docs
46
+ Requires-Dist: sphinx>=7.0; extra == "docs"
47
+ Requires-Dist: myst-parser>=2.0; extra == "docs"
48
+ Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
49
+ Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "docs"
50
+ Requires-Dist: linkify-it-py>=2.0; extra == "docs"
51
+ Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
52
+ Dynamic: license-file
53
+
54
+ # figpack
55
+
56
+ [![Tests](https://github.com/flatironinstitute/figpack/actions/workflows/test.yml/badge.svg)](https://github.com/flatironinstitute/figpack/actions/workflows/test.yml)
57
+ [![codecov](https://codecov.io/gh/flatironinstitute/figpack/branch/main/graph/badge.svg)](https://codecov.io/gh/flatironinstitute/figpack)
58
+ [![PyPI version](https://badge.fury.io/py/figpack.svg)](https://badge.fury.io/py/figpack)
59
+
60
+ A Python package for creating shareable, interactive visualizations in the browser.
61
+
62
+ ## Documentation
63
+
64
+ For detailed guidance, tutorials, and API reference, visit our **[documentation](https://flatironinstitute.github.io/figpack)**.
65
+
66
+ ## Quick Start
67
+
68
+ Want to jump right in? Here's how to get started:
69
+
70
+ ```bash
71
+ pip install figpack
72
+ ```
73
+
74
+ ```python
75
+ import numpy as np
76
+ import figpack.views as vv
77
+
78
+ # Create a timeseries graph
79
+ graph = vv.TimeseriesGraph(y_label="Signal")
80
+
81
+ # Add some data
82
+ t = np.linspace(0, 10, 1000)
83
+ y = np.sin(2 * np.pi * t)
84
+ graph.add_line_series(name="sine wave", t=t, y=y, color="blue")
85
+
86
+ # Display the visualization in your browser
87
+ graph.show(open_in_browser=True, title="Quick Start Example")
88
+ ```
89
+
90
+ ## License
91
+
92
+ Apache-2.0
93
+
94
+ ## Contributing
95
+
96
+ Visit the [GitHub repository](https://github.com/flatironinstitute/figpack) for issues, contributions, and the latest updates.
@@ -0,0 +1,53 @@
1
+ figpack/__init__.py,sha256=0qLJ7E5m_1HlQz2yVbgdZj__rO56AZjWGC3NDzswq7U,181
2
+ figpack/cli.py,sha256=xWF7J2BxUqOLvPu-Kje7Q6oGukTroXsLq8WN8vJgyw0,8321
3
+ figpack/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ figpack/core/_bundle_utils.py,sha256=JBZh2LJyu0oYHQBBVw5fF3uUNQJY_2bxVf6V7CN10FM,1884
5
+ figpack/core/_save_figure.py,sha256=52ny-m1ThGgxY4ZgMn7m33n8A2OCyezj8H8TMvw0Y8Q,1043
6
+ figpack/core/_server_manager.py,sha256=BTLeZtSbaJtAmtslAfgvp9C-SV0aJnn4WCpUJzd1Mlg,10997
7
+ figpack/core/_show_view.py,sha256=-5HT1MYSeVuEoaL3RNNyoCjYsZy4Jy9XLjljUqLuvV4,5146
8
+ figpack/core/_upload_bundle.py,sha256=54hdWayJJdRZdx7N9V2aH_X33KkR6hImMjN6tkBTLi8,14894
9
+ figpack/core/_view_figure.py,sha256=o1x1I2VKFrp2W_TStUS3fQblRW8AvGbu7Uy7MgVjofA,4186
10
+ figpack/core/config.py,sha256=oOR7SlP192vuFhYlS-h14HnG-kd_3gaz0vshXch2RNc,173
11
+ figpack/core/figpack_view.py,sha256=peJFkoP6HIqyNATzyucxAIq9HuCnK7SRO_-gE_rbEvg,6130
12
+ figpack/figpack-figure-dist/index.html,sha256=yRCsTBF07s2OLoSIlkMFUSA5Vp94yR7oh_SX6uXT8d8,486
13
+ figpack/figpack-figure-dist/assets/index-Cmae55E4.css,sha256=Yg0apcYehJwQvSQIUH13S7tsfqWQDevpJsAho0dDf0g,5499
14
+ figpack/figpack-figure-dist/assets/index-HXdk2TtM.js,sha256=GhqJkoATKYiprLAbc3V5CYUt-MtKteWLx7KUh1fjA_0,1598198
15
+ figpack/figpack-figure-dist/assets/neurosift-logo-CLsuwLMO.png,sha256=g5m-TwrGh5f6-9rXtWV-znH4B0nHgc__0GWclRDLUHs,9307
16
+ figpack/franklab/__init__.py,sha256=HkehqGImJE_sE2vbPDo-HbgtEYaMICb9-230xTYvRTU,56
17
+ figpack/franklab/views/TrackAnimation.py,sha256=3Jv1Ri4FIwTyqNahinqhHsBH1Bv_iZrEGx12w6diJ2M,5636
18
+ figpack/franklab/views/__init__.py,sha256=XXZ9QJLh9KAeeLgKbi6ogYOyfTgHP-N6o3u981NFwx8,116
19
+ figpack/spike_sorting/__init__.py,sha256=09njqh-oFaCTdZUsc4HAOFTliUYV9DClddfZ0Q_dm0I,61
20
+ figpack/spike_sorting/views/AutocorrelogramItem.py,sha256=qHmvIdHpbfVA_utPb5N2oP3hSP2cGnlT8VLaxOXV4UM,738
21
+ figpack/spike_sorting/views/Autocorrelograms.py,sha256=6MXOYJKUNEhJokiyOs8SGJVF9U9N6sHuQNYz7IEssqc,3677
22
+ figpack/spike_sorting/views/AverageWaveforms.py,sha256=mvMkS3wf6MpI95tlGqKxBjxZlHqJr4aqG7SZvHigIsI,5193
23
+ figpack/spike_sorting/views/CrossCorrelogramItem.py,sha256=uSd0i2hupteuILi_aKp7bYPYpL_PdC3CUDRMOEKUEM0,880
24
+ figpack/spike_sorting/views/CrossCorrelograms.py,sha256=OGQq_5t_T1zq4eFCpuTAvUIhZQu7ef7LVexKNdByMvo,4415
25
+ figpack/spike_sorting/views/RasterPlot.py,sha256=gFdfH9SEm-tf8Ptqw4M1Q7IHRytUOULpBZfM2TdMfZQ,2215
26
+ figpack/spike_sorting/views/RasterPlotItem.py,sha256=iW7fuDEjSfvf5YMIwrF_6cmKvD76oCigOUMHtGgBsPI,638
27
+ figpack/spike_sorting/views/SpikeAmplitudes.py,sha256=vQYWdJM-3qu568bcfGDC9k9LW_PgvU8j4tN9QYc08Mo,2665
28
+ figpack/spike_sorting/views/SpikeAmplitudesItem.py,sha256=j5Na-diY-vRUAPu0t0VkyFCSKFnQ_f5HT077mB3Cy8c,1134
29
+ figpack/spike_sorting/views/UnitSimilarityScore.py,sha256=cJA9MkETos9qHhV1tqgA7SfNEaPo-duXYCE76hSFGnA,948
30
+ figpack/spike_sorting/views/UnitsTable.py,sha256=M3y1IDJzSnvOaM1-QOyJOVcUcdTkVvxYhEMGd1kmUzs,2969
31
+ figpack/spike_sorting/views/UnitsTableColumn.py,sha256=zBnuoeILTuiVLDvtcOxqa37E5WlbR12rlwNJUeWXxY4,847
32
+ figpack/spike_sorting/views/UnitsTableRow.py,sha256=rEb2hMTA_pl2fTW1nOvnGir0ysfNx4uww3aekZzfWjk,720
33
+ figpack/spike_sorting/views/__init__.py,sha256=iRq7xPmyhnQ3GffnPC0GxKGEWnlqXY_8IOxsMqYZ1IM,967
34
+ figpack/views/Box.py,sha256=TfhPFNtVEq71LCucmWk3XX2WxQLdaeRiWGm5BM0k2l4,2236
35
+ figpack/views/Gallery.py,sha256=sHlZbaqxcktasmNsJnuxe8WmgUQ6iurG50JiChKSMbQ,3314
36
+ figpack/views/GalleryItem.py,sha256=b_upJno5P3ANSulbG-h3t6Xj56tPGJ7iVxqyiZu3zaQ,1244
37
+ figpack/views/Image.py,sha256=hmyAHlRwj0l6fC7aNmHYJFaj-qCqyH67soERm78V5dk,3953
38
+ figpack/views/LayoutItem.py,sha256=wy8DggkIzZpU0F1zFIBceS7HpBb6lu-A3hpYINQzedk,1595
39
+ figpack/views/Markdown.py,sha256=Dl1UX5s0aC-mEx5m6jIJ839YKMNeeVzIDG-EANVrbys,1147
40
+ figpack/views/MatplotlibFigure.py,sha256=YoNtZTItEjatbtNJqATm2H-Oircp5Ca6FZLjHk_B0zg,2778
41
+ figpack/views/MultiChannelTimeseries.py,sha256=sWr2nW1eoYR7V44wF7fac7IoQ6BOnus1nc4STkgIkYw,8501
42
+ figpack/views/PlotlyFigure.py,sha256=E33PEkWSj907Ue73bYfZQlF-JFDdWA8jNrG-buFQLgs,2174
43
+ figpack/views/Splitter.py,sha256=x9jLCTlIvDy5p9ymVd0X48KDccyD6bJANhXyFgKEmtE,2007
44
+ figpack/views/TabLayout.py,sha256=5g3nmL95PfqgI0naqZXHMwLVo2ebDlGX01Hy9044bUw,1898
45
+ figpack/views/TabLayoutItem.py,sha256=xmHA0JsW_6naJze4_mQuP_Fy0Nm17p2N7w_AsmVRp8k,880
46
+ figpack/views/TimeseriesGraph.py,sha256=OAaCjO8fo86u_gO_frNfRGxng3tczxGDGKcJEvZo3rE,7469
47
+ figpack/views/__init__.py,sha256=npSsSmbxN7_tZcjCK76L2l9dRVqubVXIgBnxj1uhjf4,473
48
+ figpack-0.2.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
49
+ figpack-0.2.6.dist-info/METADATA,sha256=VoUFPcVVhIVIxWp7sExL2kXVONvLYmRHMmXNVIRPqCo,3577
50
+ figpack-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
+ figpack-0.2.6.dist-info/entry_points.txt,sha256=l6d3siH2LxXa8qJGbjAqpIZtI5AkMSyDeoRDCzdrUto,45
52
+ figpack-0.2.6.dist-info/top_level.txt,sha256=lMKGaC5xWmAYBx9Ac1iMokm42KFnJFjmkP2ldyvOo-c,8
53
+ figpack-0.2.6.dist-info/RECORD,,