From dc19183848a847cb8692cef6bf45b859f47b303b Mon Sep 17 00:00:00 2001 From: Miles Garnsey Date: Tue, 19 May 2026 19:32:17 +0900 Subject: [PATCH 1/5] refactor: extract evcxr format helpers from display methods Co-Authored-By: Claude Sonnet 4.6 --- plotly/src/plot.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/plotly/src/plot.rs b/plotly/src/plot.rs index ab81e2a8..13942f74 100644 --- a/plotly/src/plot.rs +++ b/plotly/src/plot.rs @@ -403,18 +403,28 @@ impl Plot { tmpl.render().unwrap() } + fn to_evcxr_notebook_format(&self) -> String { + format!( + "EVCXR_BEGIN_CONTENT text/html\n{}\nEVCXR_END_CONTENT", + self.to_jupyter_notebook_html() + ) + } + + fn to_evcxr_lab_format(&self) -> String { + format!( + "EVCXR_BEGIN_CONTENT application/vnd.plotly.v1+json\n{}\nEVCXR_END_CONTENT", + self.to_json() + ) + } + /// Display plot in Jupyter Notebook. pub fn notebook_display(&self) { - let plot_data = self.to_jupyter_notebook_html(); - println!("EVCXR_BEGIN_CONTENT text/html\n{plot_data}\nEVCXR_END_CONTENT"); + println!("{}", self.to_evcxr_notebook_format()); } /// Display plot in Jupyter Lab. pub fn lab_display(&self) { - let plot_data = self.to_json(); - println!( - "EVCXR_BEGIN_CONTENT application/vnd.plotly.v1+json\n{plot_data}\nEVCXR_END_CONTENT" - ); + println!("{}", self.to_evcxr_lab_format()); } /// Displays the plot in Jupyter Lab; if running a Jupyter Notebook then use From ca245ef4160ee5f5f9e32489494f6369c6ca5646 Mon Sep 17 00:00:00 2001 From: Miles Garnsey Date: Tue, 19 May 2026 19:40:39 +0900 Subject: [PATCH 2/5] test: assert evcxr display output format and content Co-Authored-By: Claude Sonnet 4.6 --- plotly/src/plot.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/plotly/src/plot.rs b/plotly/src/plot.rs index 13942f74..89c5e4a9 100644 --- a/plotly/src/plot.rs +++ b/plotly/src/plot.rs @@ -885,6 +885,40 @@ mod tests { plot.lab_display(); } + #[test] + fn lab_display_output() { + let plot = create_test_plot(); + let output = plot.to_evcxr_lab_format(); + + assert!(output.starts_with("EVCXR_BEGIN_CONTENT application/vnd.plotly.v1+json\n")); + assert!(output.ends_with("\nEVCXR_END_CONTENT")); + + let json_str = output + .strip_prefix("EVCXR_BEGIN_CONTENT application/vnd.plotly.v1+json\n") + .unwrap() + .strip_suffix("\nEVCXR_END_CONTENT") + .unwrap(); + let json: serde_json::Value = serde_json::from_str(json_str).unwrap(); + assert!(json.get("data").is_some()); + assert!(json.get("layout").is_some()); + } + + #[test] + fn notebook_display_output() { + let plot = create_test_plot(); + let output = plot.to_evcxr_notebook_format(); + + assert!(output.starts_with("EVCXR_BEGIN_CONTENT text/html\n")); + assert!(output.ends_with("\nEVCXR_END_CONTENT")); + + let html = output + .strip_prefix("EVCXR_BEGIN_CONTENT text/html\n") + .unwrap() + .strip_suffix("\nEVCXR_END_CONTENT") + .unwrap(); + assert!(html.contains("plotly")); + } + #[test] fn plot_serialize_simple() { let plot = create_test_plot(); From 6a22af44c47659078d98f81b71ada00395acd47a Mon Sep 17 00:00:00 2001 From: Miles Garnsey Date: Wed, 20 May 2026 12:46:55 +0900 Subject: [PATCH 3/5] docs: modernise Jupyter setup guide for JupyterLab 4.x Co-Authored-By: Claude Sonnet 4.6 --- docs/book/src/fundamentals/jupyter_support.md | 101 +++++------------- 1 file changed, 29 insertions(+), 72 deletions(-) diff --git a/docs/book/src/fundamentals/jupyter_support.md b/docs/book/src/fundamentals/jupyter_support.md index b329ef30..09727a65 100644 --- a/docs/book/src/fundamentals/jupyter_support.md +++ b/docs/book/src/fundamentals/jupyter_support.md @@ -1,109 +1,66 @@ # Jupyter Support -As of version `0.7.0`, [Plotly.rs](https://github.com/plotly/plotly.rs) has native support for the [EvCxR Jupyter Kernel](https://github.com/google/evcxr/tree/master/evcxr_jupyter). +As of version `0.7.0`, [Plotly.rs](https://github.com/plotly/plotly.rs) has native support for the [EvCxR Jupyter Kernel](https://github.com/evcxr/evcxr/tree/main/evcxr_jupyter). Once you've installed the required packages you'll be able to run all the examples shown here as well as all [the recipes](../recipes.md) in Jupyter Lab! - ## Installation -It is assumed that an installation of the [Anaconda](https://www.anaconda.com/products/individual) Python distribution is already present in the system. If that is not the case you can follow these [instructions](https://www.anaconda.com/products/individual) to get up and running with `Anaconda`. -```shell script -conda install -c plotly plotly=4.9.0 -conda install jupyterlab "ipywidgets=7.5" +Install the plotly package and JupyterLab using pip or conda: + +**pip** +```shell +pip install plotly jupyterlab ``` -optionally (or instead of `jupyterlab`) you can also install Jupyter Notebook: -```shell script -conda install notebook +**conda** +```shell +conda install -c conda-forge plotly jupyterlab ``` -Although there are alternative methods to enable support for the [EvCxR Jupyter Kernel](https://github.com/google/evcxr/tree/master/evcxr_jupyter), we have elected to keep the requirements consistent with what those of other languages, e.g. Julia, Python and R. This way users know what to expect; and also the folks at [Plotly](https://plotly.com/python/getting-started/#jupyter-notebook-support) have done already most of the heavy lifting to create an extension for Jupyter Lab that works very well. +No separate JupyterLab extension install is required — the plotly renderer is bundled +with the plotly package (5.x+) and JupyterLab picks it up automatically. -Run the following to install the Plotly Jupyter Lab extension: -```shell script -jupyter labextension install jupyterlab-plotly@4.9.0 -``` +> **Note:** `anywidget` is required for Python's `FigureWidget` interactive features +> but is **not** needed for the Rust `lab_display()` / `notebook_display()` path. -Once this step is complete to make sure the installation so far was successful, run the following command: -```shell script -jupyter lab -``` +Next, install the EvCxR Jupyter Kernel: -Open a `Python 3` kernel copy/paste the following code in a cell and run it: -```python -import plotly.graph_objects as go -fig = go.Figure(data=go.Bar(x=['a', 'b', 'c'], y=[11, 22, 33])) -fig.show() -``` -You should see the following figure: -
- - -Next you need to install the [EvCxR Jupyter Kernel](https://github.com/google/evcxr/tree/master/evcxr_jupyter). Note that EvCxR requires [CMake](https://cmake.org/download/) as it has to compile ZMQ. If [CMake](https://cmake.org/download/) is already installed on your system and is in your path (to test that simply run ```cmake --version``` if that returns a version you're good to go) then continue to the next steps. - -In a command line execute the following commands: -```shell script +```shell cargo install evcxr_jupyter evcxr_jupyter --install ``` -If you're not familiar with the EvCxR kernel it would be good that you at least glance over the [EvCxR Jupyter Tour](https://github.com/google/evcxr/blob/master/evcxr_jupyter/samples/evcxr_jupyter_tour.ipynb). - ## Usage Launch Jupyter Lab: -```shell script + +```shell jupyter lab ``` -create a new notebook and select the `Rust` kernel. Then create the following three cells and execute them in order: +Create a new notebook and select the `Rust` kernel. Add the plotly dependency and +display a plot: -```shell script -:dep ndarray = "0.15.6" -:dep plotly = { version = ">=0.7.0" } +**Cell 1** ``` - -```rust -extern crate ndarray; -extern crate plotly; -extern crate rand_distr; +:dep plotly = "0.14" ``` +**Cell 2** ```rust -use ndarray::Array; -use plotly::common::Mode; -use plotly::layout::{Layout}; use plotly::{Plot, Scatter}; -use rand_distr::{num_traits::Float, Distribution}; -``` - -Now we're ready to start plotting! -```rust -let x0 = Array::linspace(1.0, 3.0, 200).into_raw_vec(); -let y0 = x0.iter().map(|v| *v * (v.powf(2.)).sin() + 1.).collect(); - -let trace = Scatter::new(x0, y0); +let trace = Scatter::new(vec![1.0, 2.0, 3.0], vec![1.0, 4.0, 9.0]); let mut plot = Plot::new(); plot.add_trace(trace); -let layout = Layout::new().height(525); -plot.set_layout(layout); - plot.lab_display(); -format!("EVCXR_BEGIN_CONTENT application/vnd.plotly.v1+json\n{}\nEVCXR_END_CONTENT", plot.to_json()) ``` -For Jupyter Lab there are two ways to display a plot in the `EvCxR` kernel, either have the plot object be in the last line without a semicolon or directly invoke the `Plot::lab_display` method on it; both have the same result. You can also find an example notebook [here](https://github.com/plotly/plotly.rs/tree/main/examples/jupyter/jupyter_lab.ipynb) that will periodically be updated with examples. -The process for Jupyter Notebook is very much the same with one exception; the `Plot::notebook_display` method must be used to display the plot. You can find an example notebook [here](https://github.com/plotly/plotly.rs/tree/main/examples/jupyter/jupyter_notebook.ipynb) +For Jupyter Lab there are two ways to display a plot in the `EvCxR` kernel: either +have the plot object on the last line without a semicolon, or call `Plot::lab_display` +directly — both produce the same result. + +For Jupyter Notebook, use `Plot::notebook_display` instead. You can find an example +notebook [here](https://github.com/plotly/plotly.rs/tree/main/examples/jupyter/jupyter_notebook.ipynb). From fcd35ede4dd7f343affd2c3075e9b321b37243cb Mon Sep 17 00:00:00 2001 From: Miles Garnsey Date: Fri, 22 May 2026 01:08:47 +0900 Subject: [PATCH 4/5] docs: lead with evcxr_display() as the recommended display method The docs showed lab_display() but users reach for evcxr_display(). Correct the example and remove mention of the lower-level variants. Co-Authored-By: Claude Sonnet 4.6 --- docs/book/src/fundamentals/jupyter_support.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/book/src/fundamentals/jupyter_support.md b/docs/book/src/fundamentals/jupyter_support.md index 09727a65..dc4ccd3c 100644 --- a/docs/book/src/fundamentals/jupyter_support.md +++ b/docs/book/src/fundamentals/jupyter_support.md @@ -22,7 +22,7 @@ No separate JupyterLab extension install is required — the plotly renderer is with the plotly package (5.x+) and JupyterLab picks it up automatically. > **Note:** `anywidget` is required for Python's `FigureWidget` interactive features -> but is **not** needed for the Rust `lab_display()` / `notebook_display()` path. +> but is **not** needed for the Rust `evcxr_display()` path. Next, install the EvCxR Jupyter Kernel: @@ -55,12 +55,11 @@ let trace = Scatter::new(vec![1.0, 2.0, 3.0], vec![1.0, 4.0, 9.0]); let mut plot = Plot::new(); plot.add_trace(trace); -plot.lab_display(); +plot.evcxr_display(); ``` -For Jupyter Lab there are two ways to display a plot in the `EvCxR` kernel: either -have the plot object on the last line without a semicolon, or call `Plot::lab_display` -directly — both produce the same result. +`evcxr_display()` works in both Jupyter Lab and Notebook. Alternatively you can +leave the plot on the last line of a cell without a semicolon for the same effect. -For Jupyter Notebook, use `Plot::notebook_display` instead. You can find an example -notebook [here](https://github.com/plotly/plotly.rs/tree/main/examples/jupyter/jupyter_notebook.ipynb). +You can find a full notebook example +[here](https://github.com/plotly/plotly.rs/tree/main/examples/jupyter/jupyter_notebook.ipynb). From 618c3fe088a234cc49cecc09913b8470f958e796 Mon Sep 17 00:00:00 2001 From: Miles Garnsey Date: Fri, 22 May 2026 01:23:50 +0900 Subject: [PATCH 5/5] docs: note JupyterLab version tested against Co-Authored-By: Claude Sonnet 4.6 --- docs/book/src/fundamentals/jupyter_support.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/book/src/fundamentals/jupyter_support.md b/docs/book/src/fundamentals/jupyter_support.md index dc4ccd3c..52927e54 100644 --- a/docs/book/src/fundamentals/jupyter_support.md +++ b/docs/book/src/fundamentals/jupyter_support.md @@ -4,6 +4,8 @@ As of version `0.7.0`, [Plotly.rs](https://github.com/plotly/plotly.rs) has nati Once you've installed the required packages you'll be able to run all the examples shown here as well as all [the recipes](../recipes.md) in Jupyter Lab! +> Tested against JupyterLab 4.4.7. + ## Installation Install the plotly package and JupyterLab using pip or conda: