- Fix: docstrings of
height(),mouse()andto_parquet()did not match the code (#265)
- Fix: add missing
bundle.cssto wheel
- Feat: add
order()for determining the draw order of points (#190 via #237) - Feat: use categorical color encoding in histogram bars (#97)
- Refactor: move toolbar UI from Python ipywidgets to TS React. This enables full Marimo support 🎉
- Chore: add
straightoption to connect() for straight line connections (#130) - Chore: verify Python 3.14 support (label placement not yet available due to
geoindex-rslacking 3.14 wheels) - Fix: Unused categories cause wrong colors/legend (#189 via #233)
- Fix: Wrong coloring when switching color_by between categorical/continuous (#191 via #233)
- Fix: Exception when updating data with changed categories (#197 via #233)
- Fix: geoindex-rs import compatibility (#222)
- Fix: a bug related to installation with default dependencies (#204)
- Fix: make optional package import more robust (#199)
- Feat: add
scatter.label()function for displaying text labels - Feat: add
LabelPlacementclass that allows to statically-resolved label placement and preserve results - Feat: add new color helper methods: brighten, darken, saturate, desaturate
- Feat: add 2D color map support via pycolormap-2d
- Refactor: Make
seaborndependency for contour annotations optional. You can install it viapip install "jupyter-scatter[annotation-extras]"orpip install "jupyter-scatter[all]"
- Feat: automatically assign gray to undefined/NA values for categorical data (#186)
- Fix: properly undefined/NA values in categorical data (#185)
- Fix: tooltip issue with non-existing tooltip (#187)
- Fix: ensure
tooltip_histogram == Falseworks as expected - Fix: ensure a static opacity is not shown in the tooltip
- Feat: add support for brush and rectangle lasso types.
- Feat: expose lasso selection polygon via
scatter.widget.lasso_polygon_selection - Feat: enable merging of lasso selection upon holding down the meta key and deselected points upon holding down the alt key.
- Feat: allow specifying which properties should feature a histogram via
scatter.tooltip(histograms=['color', 'property_a']) - Fix: background histogram render bug
- Fix: ensure NAs are skipped for the histogram
- Fix: ensure that the tooltip is hidden on lasso start
- Fix: ensure that the color, opacity, and size order is reset when one switches from a categorical to a continuous color map. The reset is skipped when
order == 'reverse'.
- Feat: add support for showing a scatter plot in full-screen mode. In full-screen mode you can easily customize and up-scale the resolution for better exporting in PNG.
- Feat: add ability to change the point size zoom scale function via
scatter.size(scale_function='asinh') - Feat: add
scatter.camera(is_fixed=True)to allow fixing the camera (i.e., disable pan/zoom) #176 - Feat: add CLI for quick-starting a demo via
uvx jupyter-scatter demo - Fix: properly alpha blend when saving a view as PNG
- Chore: switch from ESLint+Prettier to Biome #170
- Chore: migrate from hatch to uv #169
- Chore: bump minimum Python version to 3.9
- Fix: revert back to
pd.api.types.is_string_dtypefrompd.StringDTypebecause the two function, albeit looking semantically identical, do not do the same thing. The former detects object and string types while the latter only strictly detects string types. This is confusing aspd.Series(['a', 'b'])is of typeobject. Sopd.StringDtype.is_dtype(pd.Series(['a', 'b'])) == Falsebutpd.api.types.is_string_dtype(pd.Series(['a', 'b'])) == True. Wat?!
- Feat: add contour line annotations #163
- Refactor: rename the
reset_viewargument ofscatter.data()tozoom_viewfor clarity #162 - Docs: add API docs for
reset_scales,zoom_view, andanimateofscatter.data() - Fix: don't use external view domain (only the view) #161
- Fix: re-enable point transition and make it explicit via
scatter.options(transition_points=True, transition_points_duration=3000) - Fix: Correctly render axes grid lines upon resizing
- Fix: Reapply point color map when setting
color_by - Fix: Do not set tooltip titles if the corresponding elements are undefined.
- Feat: add support for line-based annotations via
scatter.annotations() - Feat: the exported and saved images now include a background color instead of a transparent background. You can still still export or save images with a transparent background by holding down the ALT key while clicking on the download or camera button.
- Refactor: When saving the current view as an image via the camera button on the left side bar, the image gets saved in
scatter.widget.view_dataas a 3D Numpy array (shape:[height, width, 4]) instead of a 1D Numpy array. Since the shape is now encoded by the 3D numpy array,scatter.widget.view_shapeis no longer needed and is removed. - Fix: hide button for activating rotate mouse mode as the rotation did not work (which is easily fixable) and should not be available when axes are shown as the axes are not rotateable. However rotating the plot without rotating the axis leads to incorrect tick marks.
- Fix: VSCode integration by updating regl-scatterplot to v1.10.4 (#37)
- Fix: bump regl-scatterplot to v1.10.2 for a hotfix related to rendering more than 1M points
- Fix: regression preventing tooltip from showing up (#141)
- Feat: add
scatter.show_tooltip(point_idx) - Fix: reset scale & norm ranges upon updating the data via
scatter.data() - Fix: ensure
scatter.axes(labels=['x_label', 'y_label'])works properly (#137)
- Fix: preserve filter state upon changing visual encoding (#134)
BREAKING CHANGES:
The following list of helper widgets for configuring the scatter are removed from the scatter.widget as they are unmaintained, undocumented, and incomplete. If you relied on any of those UI widgets, please see jscatter/widget.py v0.15.0 on how they were created.
scatter.widget.mouse_mode_widgetscatter.widget.lasso_initiator_widgetscatter.widget.selection_widgetscatter.widget.hovering_widgetscatter.widget.color_widgetsscatter.widget.color_by_widgetscatter.widget.color_map_widgetscatter.widget.height_widgetscatter.widget.background_color_widgetscatter.widget.background_image_widgetscatter.widget.lasso_color_widgetscatter.widget.lasso_min_delay_widgetscatter.widget.lasso_min_dist_widgetscatter.widget.color_widgetscatter.widget.color_selected_widgetscatter.widget.color_hover_widgetscatter.widget.opacity_widgetscatter.widget.selection_outline_width_widgetscatter.widget.size_widgetscatter.widget.selection_size_addition_widgetscatter.widget.reticle_widgetscatter.widget.reticle_color_widgetscatter.widget.download_view_widgetscatter.widget.save_view_widgetscatter.widget.reset_view_widget
Additionally, the following helper methods are removed as they are unnecessary.
scatter.widget.options()(simply listed out all above removed widgets)scatter.widget.select()(same asscatter.selection = list_of_point_indices)scatter.widget.use_cmap()(same as passing the cmap name toscatter.color(map=cmap_name))
Other Changes:
- Feat: Add basic support for x/y time scale via
Scatter(data=df, x='x', x_scale='time', y='y', y_scale='time') - Docs: Add API documentation for
scatter.widget - Docs: Add description for x/y scales
- Docs: Add description for connected scatterplots
- Fix: Match numerical and string IDs properly in
compose(match_by='XYZ') - Fix: Ensure that the domain and histograms match by avoiding missing categorical indices
- Fix: Ignore
NaNs when computing histograms - Fix: Warn when data contains
NaNs and replace them with zeros - Fix: Show correctly ordered color encoding in legend
- Fix: Ensure the widget's x and y scale domains are updated properly
- Fix: Ensure the widget's color, opacity, and size titles are updated properly
- Fix: Ensure the widget's axes titles are updated properly
- Fix: Include normalization in data dimension name
- Fix: Allow rendering a single axis instead of enforcing either none or both axis
- Fix: Rely on pre-normalized data to get bin ID
- Fix: Connect order
- Fix: X/Y scale domain bug
- Fix: Connected point bugs
- Fix: Remove an unused widget property that causes an issue with newer version of anywidget (#117)
- Feat: Add support for histograms in the tooltip (#96)
- Feat: Add support for non-visualized properties in the tooltip (#96)
- Fix: Allow mixing custom and DataFrame-based data (#89)
- Fix: Improve the tooltip positioning to avoid the tooltip being cut off unnecessarily
- Fix: Properly redraw axes on resize (#108)
- Fix: Incorrect axes scale domain (#107)
- Fix: Use custom regl-scatterplot option on creating a
Scatterinstance (#106) - Fix: Broken link to properties in docstrings (#110)
- Fix: don't return color, opacity, or size settings when
labelingis defined - Fix: prevent x-axis label to be cut off at the bottom
- Fix: axes label color in dark mode
- Fix view synchronization when axes are not shown
- Fix y-padding size determination
- Fix stale channel value getter for the tooltip
- Fix: update
color,opacity, andsizescales as the domains update - Fix: auto-reset
xandyscale domains upon updating thexandydata - Fix: use better number formatter for the legend
- Add the ability to show a tooltip upon hovering over a point via
scatter.tooltip(true)(#86) - Fix axes updating of linked scatter plots when panning and zooming (#87)
- Fix missing x-axes of linked scatter plots (#84)
- Fix a type in the return value of
scatter.xy()
- Fix: Prevent resetting the filter upon color, size, or opacity changes
- Fix: Upon changing the associated data frame via
scatter.data(new_df), reapply color, size, and opacity settings
- Add ability to specify titles when composing multiple scatter plots by passing tuples of
(Scatter, title)tocompose()orlink() - Fix: Add docstrings to
compose()andlink() - Fix: Optimize height of the legend
- Fix: Check if axes are enabled before updating them when the x or y scale changes
- Fix: Merge point selections on
SHIFTinstead of activating the lasso asSHIFTinterferes with Jupyter Lab - Fix: Allow to call
scatter.zoomTo()with the same points multiple times - Fix: Unfilter when calling
scatter.filter(None) - Fix: Properly listen to changes when setting custom
regl-scatterplotoptions viascatter.options()
- Fix distributed build by ensuring that
jscatter/bundle.jsis included in the build - Fix categorical encoding for partial data
Warning: do not use this version! The distributed build is broken. Use
v0.12.6instead. 🙏
-
Ensure that the default point colors respect the background when setting both at the same time during initialization. I.e., in the following scenario, the point color will be set to white by default as the background color was set to black:
jscatter.plot(data=df, background_color='black')
-
Fix an issue when working with views of a pandas DataFrame where not all categorical data is present
-
Loosen strictness of
rowsandcolsofcompose()to allow having empty cells in the grid
-
Respect the dictionary key-value order of categorical encoding maps in the legend. E.g., the following categorical color map legend will read
C, thenB, and finallyA:scatter.legend(True) scatter.color(map=dict(C='red', B='blue', A='pink'))
-
Update third-party JS libraries
- Fix incorrect legend for categorical coloring
- Update
regl-scatterplottov1.6.9
- Fix the ordering of the legend's value labels for continuous encodings such that high to low values are order top to bottom (#70)
-
Add support for referencing points by the Pandas DataFrame's index via
Scatter(data_use_index=True)orscatter.data(use_index=True). This is useful for synchronizing the selection or filtering of two Scatter instances that operate on different data frames with point correspondences. (#62import jscatter import numpy as np import pandas as pd df1 = pd.DataFrame( data=np.random.rand(16, 2), index=[chr(65 + x) for x in range(16)], columns=['x', 'y'] ) df2 = pd.DataFrame( data=np.random.rand(8, 2), index=[chr(76 - x) for x in range(8)], columns=['x', 'y'] ) s1 = jscatter.Scatter(data=df1, data_use_index=True, x='x', y='y', x_scale=[0, 2], y_scale=[0, 1]) s2 = jscatter.Scatter(data=df2, data_use_index=True, x='x', y='y', x_scale=[-1, 1], y_scale=[0, 1]) def on_selection_change(change): s2.selection(s1.selection()) s1.widget.observe(on_selection_change, names='selection') jscatter.compose([s1, s2])
shorter.mp4
-
Avoid unregistering all observers when calling
jscatter.compose()such that external observers remain registered -
Fix undefined
thisin codec preventing thescatter.selection()from working correctly (#66)
- Add
scatter.filter([0, 1, 2])for filtering down points. Filtering down to a specific subset of points is much faster than than updating the underlying data (#61) - Add
scatter.data(df)to allow rendering new data points without having to re-initialize the scatter instance (#61) - Add the ability to automatically zoom to filtered points via
Scatter(zoom_on_filter=True)orscatter.zoom(on_filter=True) - Add lasso on long press and make it the default. The behavior can be changed via
Scatter(lasso_on_long_press=False)orscatter.lasso(on_long_press=False) - Updated
regl-scatterplottov1.6
- Add support for automatic zooming to selected points via
scatter.zoom(on_selection=True) - Fix view synchronization issue
- Add
remove()to the JS widget to ensure that the scatterplot is destroyed in ipywidgetsv8.
- Add support for animated zooming to a set of points via
scatter.zoom(pointIndices)(#49) - Bump regl-scatterplot to
v1.4.1 - Add support for VSCode and Colab (#37)
- Fix serving of numpy data for JS client. Use consistent serialization object between JS and Python.
- Add support for end labeling of continuous data encoding via a new
labelingargument ofcolor(),opacity(),size(),connection_color(),connection_opacity(), andconnection_size(). (#46) - Fix the incorrect size legend when the size map is reversed (#47)
- Adjust widget to be compatible with ipywidgets
v8and jupyterlab-widgetsv3(#39)
- Fix broken build of
v0.7.2 - Fix versions of ipywidgets and jupyterlab_widgets to avoid running into incompatibilities (#40)
Do not use. Build is broken
- Take the x-padding into account when setting a fixed width (#36)
- Make
widthandheightcorrespond to the canvas' (i.e., inner) dimensions such thatScatter(width=500, height=500)will lead to a canvas of size 500x500 px.
- Add support for legends via
scatter.legend(True, position='top-right', size='small')(#30)
- Remove accidentally added
console.log
- Add support for axes labels via
scatter.axes(labels=True)orscatter.axes(labels=['x-axis', 'y-axis'])(#29)
- Fix issues when specifying the color, opacity, or size map via a
dict
- Breaking changes:
- For
scatter.color(), renamecolortodefault,color_selectedtoselected, andcolor_hoverandhover - For
scatter.opacity(), renameopacitytodefault - For
scatter.size(), renamesizetodefault - For
scatter.connection_color(), renamecolortodefault,color_selectedtoselected, andcolor_hoverandhover - For
scatter.connection_opacity(), renameopacitytodefault - For
scatter.connection_size(), renamesizetodefault
- For
- Add
scatter.opacity(unselected=0.5). This property defines the opacity scaling factor of unselected points and must be in[0, 1]. This scaling is only applied if one or more points are selected.
- Fix an issue when dynamically resizing the scatter plot height
- Fix an issue when switching from categorical to continuous color/opacity/size encoding
- Breaking change: Renamed
color_activeandconnection_color_activetocolor_selectedandconnection_color_selectedrespectively for clarity. - Add support for axes via
Scatter(axes=True, axes_grid=True)orscatter.axes(True, grid=True). - Add support for log and power x/y scales via
Scatter(x_scale='log')orscatter.y(scale='pow'). - Add docstrings and type hints
- Unset data-driven color, opacity, and size encoding when only a constant value was passed to an encoder function. E.g., after initializing
scatter = Scatter(..., color_by='property'), callingscatter.color('red')will automatically unsetcolor_by.
- Fix
scatter.pixels()
- Fix more type hints...
- Make type hints backward compatible to Python 3.7
- Breaking change: Change the signature of
compose()to simplify correspondence mapping of data points. - Breaking change: Rename
view_pixelstoview_dataand add faster synchronization from the JS to Python kernel - Add ability to link the view of multiple scatter plots via
compose(sync_view=True) - Add
link()as a shorthand forcompose(sync_view=True, sync_selection=True, sync_hover=True) - Add ability to defined categorical colors using a dictionary. E.g.,
scatter.color(by='coolness', map=dict(cool='blue', hot='orange')) - Fix two issues with the
orderargument in methodscolor(),opacity(),size(),connection_color(),connection_opacity(), andconnection_size()that prevented it's propper use. - Improve the ordering of the default Okabe Ito color map
- Expose default the Okabe Ito (
okabe_ito) and Glasbey (glasbey_lightandglasbey_dark) color maps for convenience - Automatiecally handle string as categorical data
- Fix broken installation of v0.2.1 (#23)
- Simplify installation (#16)
- Complete rewrite of the Python API to match (#3)
- Properly destroy regl-scatterplot on destroy of a widget instance
- Fix bunch of typos related to renaming the pypi and npm package
- First version