Package: jupyter-scatter
Jupyter ScatterAn interactive scatter plot widget for Jupyter Notebook, Lab, and Google Colabthat can handlemillions of pointsand supportsview linking.Features?🖱️Interactive: Pan, zoom, and select data points interactively with your mouse or through the Python API.🚀Scalable: Plot up to several millions data points smoothly thanks to WebGL rendering.🔗Interlinked: Synchronize the view, hover, and selection across multiple scatter plot instances.✨Effective Defaults: Rely on Jupyter Scatter to choose perceptually effective point colors and opacity by default.📚Friendly API:Enjoy a readable API that integrates deeply with Pandas DataFrames.🛠️Integratable: Use Jupyter Scatter in your own widgets by observing its traitlets.Why?Imagine trying to explore a dataset of millions of data points as a 2D scatter. Besides plotting, the exploration typically involves three things: First, we want to interactively adjust the view (e.g., via panning & zooming) and the visual point encoding (e.g., the point color, opacity, or size). Second, we want to be able to select and highlight data points. And third, we want to compare multiple datasets or views of the same dataset (e.g., via synchronized interactions). The goal of jupyter-scatter is to support all three requirements and scale to millions of points.How?Internally, Jupyter Scatter usesregl-scatterplotfor WebGL rendering,traitletsfor two-way communication between the JS and iPython kernels, andanywidgetfor composing the widget.IndexInstallGet StartedDocsExamplesDevelopmentInstallpipinstalljupyter-scatterIf you are using JupyterLab <=2:jupyterlabextensioninstall@jupyter-widgets/jupyterlab-managerjupyter-scatterFor a minimal working example, take a look attest-environments.Get StartedInfoVisitjupyter-scatter.devfor details on all essential features of Jupyter Scatter and check out ourfull-blown tutorialfrom SciPy '23.Simplest ExampleIn the simplest case, you can pass the x/y coordinates to the plot function as follows:importjscatterimportnumpyasnpx=np.random.rand(500)y=np.random.rand(500)jscatter.plot(x,y)Pandas ExampleSay your data is stored in a Pandas dataframe like the following:importpandasaspd# Just some random float and int valuesdata=np.random.rand(500,4)df=pd.DataFrame(data,columns=['mass','speed','pval','group'])# We'll convert the `group` column to strings to ensure it's recognized as# categorical data. This will come in handy in the advanced example.df['group']=df['group'].map(lambdac:chr(65+round(c)),na_action=None)xyvaluegroup00.130.270.51G10.870.930.80B20.100.250.25F30.030.900.01G40.190.780.65DYou can then visualize this data by referencing column names:jscatter.plot(data=df,x='mass',y='speed')Show the resulting scatter plotAdvanced exampleOften you want to customize the visual encoding, such as the point color, size, and opacity.jscatter.plot(data=df,x='mass',y='speed',size=8,# static encodingcolor_by='group',# data-driven encodingopacity_by='density',# view-driven encoding)In the above example, we chose a static point size of8. In contrast, the point color is data-driven and assigned based on the categoricalgroupvalue. The point opacity is view-driven and defined dynamically by the number of points currently visible in the view.Also notice how jscatter uses an appropriate color map by default based on the data type used for color encoding. In this examples, jscatter uses the color blindness safe color map fromOkabe and Itoas the data type iscategoricaland the number of categories is less than9.Important:in order for jscatter to recognize categorical data, thedtypeof the corresponding column needs to becategory!You can, of course, customize the color map and many other parameters of the visual encoding as shown next.Functional API ExampleTheflat APIcan get overwhelming when you want to customize a lot of properties. Therefore, jscatter provides a functional API that groups properties by type and exposes them via meaningfully-named methods.scatter=jscatter.Scatter(data=df,x='mass',y='speed')scatter.selection(df.query('mass < 0.5').index)scatter.color(by='mass',map='plasma',order='reverse')scatter.opacity(by='density')scatter.size(by='pval',map=[2,4,6,8,10])scatter.height(480)scatter.background('black')scatter.show()When you update properties dynamically, i.e., after having calledscatter.show(), the plot will update automatically. For instance, try callingscatter.xy('speed', 'mass')and you will see how the points are mirrored along the diagonal.Moreover, all arguments are optional. If you specify arguments, the methods will act as setters and change the properties. If you call a method without any arguments it will act as a getter and return the property (or properties). For example,scatter.selection()will return thecurrentlyselected points.Finally, the scatter plot is interactive and supports two-way communication. Hence, if you select some point with the lasso tool and then callscatter.selection()you will get the current selection.Linking Scatter PlotsTo explore multiple scatter plots and have their view, selection, and hover interactions link, usejscatter.link().jscatter.link([jscatter.Scatter(data=embeddings,x='pcaX',y='pcaY',**config),jscatter.Scatter(data=embeddings,x='tsneX',y='tsneY',**config),jscatter.Scatter(data=embeddings,x='umapX',y='umapY',**config),jscatter.Scatter(data=embeddings,x='caeX',y='caeY',**config)],rows=2)https://user-images.githubusercontent.com/932103/162584133-85789d40-04f5-428d-b12c-7718f324fb39.mp4Seenotebooks/linking.ipynbfor more details.Visualize Millions of Data PointsWithjupyter-scatteryou can easily visualize and interactively explore datasets with millions of points.In the following we're visualizing 5 million points generated with theRössler attractor.points=np.asarray(roesslerAttractor(5000000))jscatter.plot(points[:,0],points[:,1],height=640)https://user-images.githubusercontent.com/932103/162586987-0b5313b0-befd-4bd1-8ef5-13332d8b15d1.mp4Seenotebooks/examples.ipynbfor more details.Google ColabWhile jscatter is primarily developed for Jupyter Lab and Notebook, it also runs just fine in Google Colab. Seejupyter-scatter-colab-test.ipynbfor an example.DevelopmentSetting up a development environmentRequirements:Hatch>= 1.7.0Installation:gitclonehttps://github.com/flekschas/jupyter-scatter/jscatter&&cdjscatter
hatchshell
pipinstall-e".[dev]"After Changing Python code:restart the kernel.Alternatively, you can enable auto reloading by enabling theautoreloadextension. To do so, run the following code at the beginning of a notebook:%load_extautoreload%autoreload2After Changing JavaScript code:docd js && npm run build.Alternatively, you can runnpm run watchand rebundle the code on the fly.Setting up a test environmentGo totest-environmentsand follow the instructions.