- 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_dtype
frompd.StringDType
because 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'])) == False
butpd.api.types.is_string_dtype(pd.Series(['a', 'b'])) == True
. Wat?!
- Feat: add contour line annotations #163
- Refactor: rename the
reset_view
argument ofscatter.data()
tozoom_view
for clarity #162 - Docs: add API docs for
reset_scales
,zoom_view
, andanimate
ofscatter.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_data
as 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_shape
is 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_widget
scatter.widget.lasso_initiator_widget
scatter.widget.selection_widget
scatter.widget.hovering_widget
scatter.widget.color_widgets
scatter.widget.color_by_widget
scatter.widget.color_map_widget
scatter.widget.height_widget
scatter.widget.background_color_widget
scatter.widget.background_image_widget
scatter.widget.lasso_color_widget
scatter.widget.lasso_min_delay_widget
scatter.widget.lasso_min_dist_widget
scatter.widget.color_widget
scatter.widget.color_selected_widget
scatter.widget.color_hover_widget
scatter.widget.opacity_widget
scatter.widget.selection_outline_width_widget
scatter.widget.size_widget
scatter.widget.selection_size_addition_widget
scatter.widget.reticle_widget
scatter.widget.reticle_color_widget
scatter.widget.download_view_widget
scatter.widget.save_view_widget
scatter.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
NaN
s when computing histograms - Fix: Warn when data contains
NaN
s 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
Scatter
instance (#106) - Fix: Broken link to properties in docstrings (#110)
- Fix: don't return color, opacity, or size settings when
labeling
is 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
, andsize
scales as the domains update - Fix: auto-reset
x
andy
scale domains upon updating thex
andy
data - 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
SHIFT
instead of activating the lasso asSHIFT
interferes 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-scatterplot
options viascatter.options()
- Fix distributed build by ensuring that
jscatter/bundle.js
is included in the build - Fix categorical encoding for partial data
Warning: do not use this version! The distributed build is broken. Use
v0.12.6
instead. 🙏
-
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
rows
andcols
ofcompose()
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-scatterplot
tov1.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
this
in 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-scatterplot
tov1.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
labeling
argument 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
v8
and 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
width
andheight
correspond 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()
, renamecolor
todefault
,color_selected
toselected
, andcolor_hover
andhover
- For
scatter.opacity()
, renameopacity
todefault
- For
scatter.size()
, renamesize
todefault
- For
scatter.connection_color()
, renamecolor
todefault
,color_selected
toselected
, andcolor_hover
andhover
- For
scatter.connection_opacity()
, renameopacity
todefault
- For
scatter.connection_size()
, renamesize
todefault
- 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_active
andconnection_color_active
tocolor_selected
andconnection_color_selected
respectively 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_pixels
toview_data
and 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
order
argument 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_light
andglasbey_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