<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Jupyter Blog - Martin Renou</title><link href="https://jupyter.org/blog/" rel="alternate"/><link href="https://jupyter.org/blog/feeds/author-martin-renou.atom.xml" rel="self"/><id>https://jupyter.org/blog/</id><updated>2026-08-24T16:09:00+00:00</updated><subtitle>The Project Jupyter blog: news, releases, and community stories, archived from blog.jupyter.org.</subtitle><entry><title>JupyterGIS 0.16: New visualization capabilities, collaborative Story Maps, and more</title><link href="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/" rel="alternate"/><published>2026-08-24T16:09:00+00:00</published><updated>2026-08-24T16:09:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2026-08-24:/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/</id><summary type="html">&lt;p&gt;This release adds support for new geospatial formats, tighter integration with the scientific Python ecosystem, a redesigned Story Map editor, and a more expressive way to style geographic data.&lt;/p&gt;
</summary><content type="html">&lt;blockquote&gt;
&lt;p&gt;Read this article in Notebook.link, as a live story-map! &lt;a href="https://notebook.link/@martinRenou/jupytergis-announcement"&gt;https://notebook.link/@martinRenou/jupytergis-announcement&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://jupyter.org/blog/posts/2026/expanding-geospatial-workflows-in-jupytergis-stac/"&gt;Earlier this year, we introduced STAC browsing and Story Maps in JupyterGIS&lt;/a&gt;, making it easier to discover geospatial datasets and communicate results without leaving Jupyter.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/geojupyter/jupytergis/releases/tag/v0.16.0"&gt;JupyterGIS 0.16&lt;/a&gt; continues in the same direction. This release adds support for new geospatial formats, tighter integration with the scientific Python ecosystem, a redesigned Story Map editor, and a more expressive way to style geographic data.&lt;/p&gt;
&lt;h2 id="story-maps-are-getting-a-new-look"&gt;Story Maps are getting a new look!&lt;/h2&gt;
&lt;p&gt;Story Maps in JupyterGIS let you build a scrollable presentation around your map. A Story Map is made up of a sequence of segments that can combine Markdown content with map views, so you can guide the reader through a geographic story as they scroll.&lt;/p&gt;
&lt;p&gt;Each segment can define its own map state, including the current map location, visible layers, and layer styling. This means that the map can change as the reader moves through the story: layers can appear or disappear, the view can move to a new location, and symbology can change to highlight different aspects of the data.&lt;/p&gt;
&lt;p&gt;Story Maps have received a significant update in this release.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Read this article in Notebook.link, as a live story-map! &lt;a href="https://notebook.link/@martinRenou/jupytergis-announcement"&gt;https://notebook.link/@martinRenou/jupytergis-announcement&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="The Story-map associated to this release annoucement. It contains Text, images, and map views with associated layer states." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/001-1_gyuKfOzFSbmRhH9LVBTJiA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Story-map associated to this release annoucement. It contains Text, images, and map views with associated layer states.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="a-better-story-maps-editing-experience"&gt;A better Story Maps editing experience&lt;/h2&gt;
&lt;p&gt;We’ve also made substantial improvements to the Story Map editing experience.&lt;/p&gt;
&lt;p&gt;The editor has been redesigned around Jupyter’s &lt;strong&gt;real-time collaboration infrastructure, allowing multiple people to edit the same Story Map simultaneously&lt;/strong&gt;. Changes appear immediately for everyone, making it much easier to prepare presentations, reports, or educational material as a team.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Collaboratively edit the Story Map markdown." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/002-1_yLMypnIGkeKXrR1BfXgvHg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Collaboratively edit the Story Map markdown.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The editor now gives you a much better sense of what the final story will look like while you are working on it. Markdown sections can be previewed directly in the editor, and a new Story Map preview makes it possible to see the complete presentation without leaving the editing workflow. This makes it easier to write, arrange, and refine a story while keeping an eye on the final result. We’ve also introduced a new layout that is better suited for long-form content. In addition to guided geographic narratives, Story Maps can now be used to create richer articles combining text, maps, images, and other interactive content.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="New Story Map editor: Set story segment viewport, preview markdown, set layers properties for the story segment." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/003-1_1eO0MShCVn71uIhAkC61ZA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;New Story Map editor: Set story segment viewport, preview markdown, set layers properties for the story segment.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="openeo-layers"&gt;OpenEO layers&lt;/h2&gt;
&lt;p&gt;More and more geospatial workflows rely on remote processing instead of downloading datasets locally. openEO provides a common API to describe these processing pipelines as process graphs that are executed by a backend.&lt;/p&gt;
&lt;p&gt;JupyterGIS can now display &lt;strong&gt;openEO&lt;/strong&gt; process graphs directly as map layers. Instead of exporting intermediate results before visualizing them, you can connect an openEO backend and inspect the output of your processing pipeline directly in the map.&lt;/p&gt;
&lt;p&gt;The visualization is tile-based and lazy: JupyterGIS only requests the data needed for the current map view and zoom level. This makes it possible to explore large remote sensing workflows interactively, without materializing the full result locally.&lt;/p&gt;
&lt;p&gt;JupyterGIS can make use of any openEO server that supports tiling, such as &lt;a href="https://sentinel-hub.github.io/titiler-openeo"&gt;titiler-openeo&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;openeo&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;jupytergis&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GISDocument&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;openeo.processes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;

&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openeo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SERVER_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;authenticate_basic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BASIC_AUTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BASIC_AUTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cube&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;sentinel-2-global-mosaics&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bands&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;B03&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;B08&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;temporal_extent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2022-04-15&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;2022-12-31&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cube&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cube&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reduce_dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;t&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reducer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;first&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cube&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cube&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;10000.0&lt;/span&gt;

&lt;span class="c1"&gt;# NDWI = (GREEN - NIR) / (GREEN + NIR)&lt;/span&gt;
&lt;span class="n"&gt;ndwi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cube&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ndvi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ndwi_vis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ndwi&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;ndwi_png&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndwi_vis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linear_scale_range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;input_min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;input_max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;output_min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;output_max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ndwi_png&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GISDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;40.75&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;longitude&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mf"&gt;73.95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zoom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_openeo_tile_layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="Define a process graph to compute a NDWI, using the Python API of OpenEO and JupyterGIS. It is then lazily evaluated on a per-tile basis while the user pans/zooms on the map." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/004-1_L5MrEnxXuvIkT5rVl0dahw.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Define a process graph to compute a NDWI, using the Python API of OpenEO and JupyterGIS. It is then lazily evaluated on a per-tile basis while the user pans/zooms on the map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to defining openEO process graphs from the scripting Python API, JupyterGIS provides an advanced openEO process graph editor, allowing you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;connect to an openEO tile server&lt;/li&gt;
&lt;li&gt;define the graph graphically, with boxes and arrows&lt;/li&gt;
&lt;li&gt;load data collections and define processes with a drag-and-drop UI&lt;/li&gt;
&lt;li&gt;directly edit the JSON content&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="Editing an openEO process graph from the JupyterGIS front-end" src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/005-1_3AGsNcwe384V1P4-ZkzcYw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Editing an openEO process graph from the JupyterGIS front-end&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another interesting aspect of openEO is that process graphs have a well-defined, declarative JSON representation. Because of this structured format, &lt;strong&gt;they are a natural target for LLM-assisted workflows&lt;/strong&gt;. Users can describe the analysis they want in natural language, have an LLM generate or refine the corresponding process graph (e.g. using jupyterlite-ai), and immediately visualize the result in JupyterGIS. Combined with the lazy, tile-based rendering, this makes it possible to quickly iterate on processing pipelines without waiting for complete datasets to be exported or downloaded.&lt;/p&gt;
&lt;h2 id="lazy-visualization-of-xarray-datasets-with-jupyter-tiler"&gt;Lazy visualization of Xarray datasets with jupyter-tiler&lt;/h2&gt;
&lt;p&gt;JupyterGIS now integrates with the new &lt;a href="https://jupyter-tiler.readthedocs.io"&gt;jupyter-tiler&lt;/a&gt; package, making it straightforward to visualize Xarray datasets from Python.&lt;/p&gt;
&lt;p&gt;Datasets can come from anywhere: they may already exist in your notebook, or they can be loaded on demand from a STAC catalog using stackstac. Once you have an Xarray object, JupyterGIS can display it in the map without requiring an export to another format.&lt;/p&gt;
&lt;p&gt;Rendering happens lazily, generating only the tiles needed for the current view. This makes it possible to explore datasets that are much larger than memory while keeping navigation responsive.&lt;/p&gt;
&lt;p&gt;The result is a smoother workflow from data loading, to analysis, to visualization, all within the same notebook.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_data_array_layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;NDSI Layer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data_array&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ndsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;colormap_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;viridis&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;colormap_range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="Visualizing an Xarray dataset in JupyterGIS." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/006-1_GsxLjpQu33wvCx8KZxBUWA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Visualizing an Xarray dataset in JupyterGIS.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This feature requires the optional dependency jupyter-tiler to be installed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;jupyter-tiler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="a-more-expressive-symbology-model"&gt;A more expressive symbology model&lt;/h2&gt;
&lt;p&gt;Styling geographic data often requires combining multiple visual properties to communicate patterns effectively.&lt;/p&gt;
&lt;p&gt;JupyterGIS 0.16 introduces a &lt;strong&gt;new symbology model inspired by the Grammar of Graphics.&lt;/strong&gt; Instead of relying on a fixed set of styling options, visual properties such as color, size, and opacity can be defined in a more flexible and composable way.&lt;/p&gt;
&lt;p&gt;This makes it easier to build everything from simple thematic maps to more advanced visualizations while keeping styling definitions consistent and reproducible.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A symbology example: apply a Viridis color map to the circle colors, a linear scale to the radius of circles, and a fixed stroke color." src="https://jupyter.org/blog/posts/2026/jupytergis-0-16-new-visualization-capabilities/images/007-1_SU9Ll713eVozkjVQNQNmMA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A symbology example: apply a Viridis color map to the circle colors, a linear scale to the radius of circles, and a fixed stroke color.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="geozarr-and-geopackage-support"&gt;GeoZarr and GeoPackage support&lt;/h2&gt;
&lt;p&gt;This release also expands the range of formats that JupyterGIS can open directly.&lt;/p&gt;
&lt;p&gt;Support for GeoZarr makes it possible to work with cloud-native multidimensional geospatial datasets, while GeoPackage support improves interoperability with existing GIS software and common data exchange workflows.&lt;/p&gt;
&lt;h2 id="new-collaborative-editing-capabilities"&gt;New Collaborative Editing Capabilities&lt;/h2&gt;
&lt;p&gt;JupyterGIS 0.16 also brings collaborative editing to vector layers. When working on a shared JupyterGIS document, multiple users can now edit the same vector data at the same time.&lt;/p&gt;
&lt;p&gt;Features can be created, moved, and edited collaboratively, with changes synchronized in real time between users. This makes it possible to work together on tasks such as digitizing features, annotating a map, or refining a dataset without having to exchange files or manually merge changes.&lt;/p&gt;
&lt;p&gt;Combined with the collaborative Story Map editor, this makes collaboration a more integral part of JupyterGIS: users can work together on the data itself, and then use the same shared document to explore and communicate their results.&lt;/p&gt;
&lt;h2 id="a-new-r-api"&gt;A new R API&lt;/h2&gt;
&lt;p&gt;JupyterGIS 0.16 also introduces an R client, bringing JupyterGIS to R users through the new &lt;a href="https://github.com/geojupyter/r-jupytergis"&gt;&lt;code&gt;r-jupytergis&lt;/code&gt;&lt;/a&gt; package. The R client provides bindings for interacting with JupyterGIS widgets from an R notebook, using the same JavaScript front-end as the Python client.&lt;/p&gt;
&lt;p&gt;The main interface is the &lt;code&gt;GISDocument&lt;/code&gt; widget, which can be used to create and manipulate JupyterGIS documents directly from R. This makes it possible to build geospatial workflows in R while using the same interactive map interface available to Python users.&lt;/p&gt;
&lt;p&gt;The R client also uses the same underlying collaborative infrastructure as the Python client, including the Yrs CRDT library. This means that R users can participate in the same collaborative JupyterGIS workflows rather than working in a separate environment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GISDocument&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;france_hiking.jGIS&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="nf"&gt;add_raster_layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://mt1.google.com/vt/lyrs=y&amp;amp;x={x}&amp;amp;y={y}&amp;amp;z={z}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Google Satellite&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;attribution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Google&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;opacity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.6&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="bug-fixes-and-performance-improvements"&gt;Bug fixes and performance improvements&lt;/h2&gt;
&lt;p&gt;As usual, this release also includes many smaller improvements throughout the project.&lt;/p&gt;
&lt;p&gt;We’ve fixed a number of bugs, improved performance in several parts of the application, and continued polishing both the user interface and the Python API.&lt;/p&gt;
&lt;p&gt;JupyterGIS continues to evolve as a collaborative GIS environment that fits naturally within the Jupyter ecosystem. Whether your workflow starts from a notebook, a STAC catalog, an openEO backend, or a local dataset, the goal remains the same: make it easier to move between analysis, visualization, and communication without switching tools.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;This work on JupyterGIS by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; was funded by &lt;a href="https://www.esa.int/"&gt;the European Space Agency (ESA)&lt;/a&gt; for the Story-maps development, the R API, openEO layers support and the collaborative labelling. Additionally, QuantStack was funded by &lt;a href="https://cnes.fr/"&gt;the French National Centre for Space Studies (CNES)&lt;/a&gt; for the lazy visualization of xarray datasets.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="contributors-to-this-release"&gt;Contributors to this release&lt;/h2&gt;
&lt;p&gt;By order of &lt;a href="https://github-activity.readthedocs.io/en/latest/use/#how-does-this-tool-define-contributions-in-the-reports"&gt;number of contributions&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/arjxn-py"&gt;&lt;strong&gt;Arjun Verma&lt;/strong&gt;&lt;/a&gt; is a Developer at QuantStack. He worked on the server-side geoprocessing infrastructure and on the openEO editor in the JupyterGIS front-end.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/martinRenou"&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt;&lt;/a&gt; is a Technical Director at QuantStack and a maintainer of JupyterGIS. For this release, Martin coordinated and guided much of the development, and worked on the integration of openEO layers.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/gjmooney"&gt;&lt;strong&gt;Gregory Mooney&lt;/strong&gt;&lt;/a&gt; is a Developer at QuantStack and a long-time contributor to JupyterGIS. He led much of the work on the new Story Map editor and its collaborative editing capabilities.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/MMesch"&gt;&lt;strong&gt;Matthias Meschede&lt;/strong&gt;&lt;/a&gt; is Chief Operating Officer at QuantStack. He introduced the new Grammar of Graphics-inspired symbology model, bringing a more expressive and composable approach to styling geographic data.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mfisher87"&gt;&lt;strong&gt;Matt Fisher&lt;/strong&gt;&lt;/a&gt; is the Community Manager of &lt;a href="https://github.com/geojupyter"&gt;GeoJupyter&lt;/a&gt;. He contributed to many of the discussions around the release and helped shape several of the design decisions across the project.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nakul-py"&gt;&lt;strong&gt;Nakul Verma&lt;/strong&gt;&lt;/a&gt; is an open-source contributor to JupyterGIS. He contributed numerous bug fixes and improvements throughout the release, and introduced support for Vega expressions in the new symbology system.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/AntoinePrv"&gt;&lt;strong&gt;Antoine Prouvost&lt;/strong&gt;&lt;/a&gt; is a Developer at QuantStack. He led the initial work on the R API for JupyterGIS, building its first skeleton and establishing the foundations for the &lt;code&gt;r-jupytergis&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/SandrineP"&gt;&lt;strong&gt;Sandrine Pataut&lt;/strong&gt;&lt;/a&gt; is a Developer at QuantStack. She worked on bringing many of JupyterGIS’s features to the R API, helping make the new client more complete and useful for R users.&lt;/p&gt;
&lt;p&gt;We are grateful to everyone who contributed code, reviews, ideas, discussions, and feedback to this release. JupyterGIS continues to benefit from an increasingly diverse community of contributors, and we look forward to seeing what comes next!&lt;/p&gt;
</content><category term="geoscience"/><category term="JupyterGIS"/><category term="science"/></entry><entry><title>Collaborative editing for GIS workflows with Jupyter and QGIS</title><link href="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/" rel="alternate"/><published>2025-02-26T18:50:00+00:00</published><updated>2025-07-16T19:41:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2025-02-26:/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/</id><summary type="html">&lt;p&gt;The QGIS open-source project is a cornerstone in the geosciences ecosystem, providing robust tools for spatial data analysis and visualisation.&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/001-1__WoRjRDGSKbaUY6b4TsndA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The QGIS open-source project is a cornerstone in the geosciences ecosystem, providing robust tools for spatial data analysis and visualisation. While QGIS excels in empowering researchers and engineers, the evolving landscape of geospatial research demands enhanced collaboration and accessibility, prompting a shift towards web-based technologies.&lt;/p&gt;
&lt;h2 id="collaboration-in-jupyter"&gt;Collaboration in Jupyter&lt;/h2&gt;
&lt;p&gt;Collaboration has long been a key requirement for data science and scientific computing workflows, but Jupyter Notebooks historically lacked built-in real-time collaboration features.&lt;/p&gt;
&lt;p&gt;To bridge this gap, the &lt;a href="https://github.com/jupyterlab/jupyter-collaboration"&gt;&lt;strong&gt;jupyter-collaboration&lt;/strong&gt;&lt;/a&gt; project has focused on integrating multi-user editing capabilities directly into JupyterLab and Jupyter Notebook. This effort builds on foundational work in conflict-free replicated data types (CRDTs), leveraging technologies like &lt;a href="https://github.com/yjs/yjs"&gt;&lt;strong&gt;Yjs&lt;/strong&gt;&lt;/a&gt;, and required integration into the Notebook document model and WebSocket-based architecture.&lt;/p&gt;
&lt;figure&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/0e8IQ76sulI" title="Notebook code suggestions in collaboration mode" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
&lt;p&gt;Making Notebook code suggestions in collaboration mode with &lt;a href="https://github.com/jupyterlab-contrib/jupyter-suggestions"&gt;https://github.com/jupyterlab-contrib/jupyter-suggestions&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This approach did not only enable collaborative editing of notebooks, but also opened the door for collaboration on other editing UIs. This was done e.g. in &lt;a href="https://github.com/jupytercad/JupyterCAD"&gt;&lt;strong&gt;JupyterCAD&lt;/strong&gt;&lt;/a&gt;, a 3D parametric modeler that allows multiple users to collaboratively design and manipulate CAD models within JupyterLab.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Read more about JupyterCAD here &lt;a href="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/"&gt;Announcing JupyterCAD 3.0&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/Zu0AT6IRA98" title="JupyterCAD suggestions" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
&lt;p&gt;Collaboration in JupyterCAD&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="introducing-jupytergis"&gt;Introducing JupyterGIS&lt;/h2&gt;
&lt;p&gt;Today, we are excited to announce &lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS&lt;/a&gt;, a web-based, collaborative, and extensible interface for GIS, leveraging the JupyterLab application framework and integrating seamlessly with the Jupyter notebook interface.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS&lt;/a&gt; provides the following key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a JupyterLab extension for collaborative editing of geospatial data files: with COG, Shapefile, GeoJSON data source support,&lt;/li&gt;
&lt;li&gt;support for &lt;strong&gt;importing, exporting and collaborating with QGIS files,&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;advanced analysis and editing features with an &lt;strong&gt;identify tool&lt;/strong&gt; and a &lt;strong&gt;symbology panel&lt;/strong&gt; approaching what QGIS provides,&lt;/li&gt;
&lt;li&gt;easily &lt;strong&gt;share and deploy GIS projects&lt;/strong&gt; using JupyterLite.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: JupyterGIS is not an official Jupyter subproject.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="gis-features"&gt;GIS features&lt;/h2&gt;
&lt;h3 id="raster-and-vector-layers"&gt;Raster and vector layers&lt;/h3&gt;
&lt;p&gt;JupyterGIS allows you to create multiple types of raster and vector layers, including local or remote GeoTIFFs, GeoJSON, shapefiles, and tile services.&lt;/p&gt;
&lt;p&gt;You can select from a set of pre-defined tile services in our gallery, or you can provide your own source.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/4_voiMm2zPk" title="JupyterGIS: raster and vector layers" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3 id="identify-tool-and-filtering"&gt;Identify tool and filtering&lt;/h3&gt;
&lt;p&gt;Akin to QGIS, we provide an identify tool and filtering capabilities, helping you to inspect your datasource.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/Cs500f7eQMA" title="JupyterGIS: identify tool and filtering" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3 id="symbology"&gt;Symbology&lt;/h3&gt;
&lt;p&gt;The symbology of a layer refers to its visual representation on the map, helping you to analyze your data comfortably. JupyterGIS provides a similar feature for its raster and vector layers.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/nyFPZCShyxs" title="JupyterGIS: symbology" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3 id="spatio-temporal-data"&gt;Spatio-temporal data&lt;/h3&gt;
&lt;p&gt;You can easily animate and analyze your spatio-temporal data.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/y6OSPdlW_kU" title="JupyterGIS: spatio-temporal data" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3 id="python-api"&gt;Python API&lt;/h3&gt;
&lt;p&gt;Even though you can do most operations from the UI, JupyterGIS also provides a Python API enabling scripting capabilities, which can be used to process data and operate on JupyterGIS documents programmatically from a Jupyter notebook.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/gUn1JHg1y4Y" title="JupyterGIS: Python API" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h2 id="collaborative-features"&gt;Collaborative features&lt;/h2&gt;
&lt;p&gt;Building upon our previous work to enable collaborative editing in JupyterCAD, we developed a shared document model to support multi-user workflows in JupyterGIS.&lt;/p&gt;
&lt;p&gt;Everything is shared between collaborators, from layers data to symbology and filtering rules.&lt;/p&gt;
&lt;p&gt;We also provide some collaboration features like the ability to see other collaborators’ cursors, follow collaborators’ viewports, add geolocated Google Docs-like comment conversations, and see what layer features collaborators are identifying.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/FzHYYCvWyu0" title="JupyterGIS: collaborative features" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;h2 id="try-it"&gt;Try it!&lt;/h2&gt;
&lt;p&gt;You can directly try &lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS&lt;/a&gt; in your browser, without installing anything, thanks to &lt;a href="https://github.com/jupyterlite/jupyterlite"&gt;JupyterLite&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jupytergis.readthedocs.io/en/latest/lite/lab/index.html?path=france_hiking.jGIS/"&gt;https://jupytergis.readthedocs.io/en/latest/lite/lab/index.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="documentation"&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Check out the Python API reference and tutorials on how to get started in our documentation:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jupytergis.readthedocs.io/"&gt;https://jupytergis.readthedocs.io&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="whats-next"&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;We are excited to welcome new contributors and see the &lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS&lt;/a&gt; community grow. Here are some exciting developments on our radar for the future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for more data source types.&lt;/li&gt;
&lt;li&gt;Processing tools,&lt;/li&gt;
&lt;li&gt;Support for suggestions by collaborators, similar to the inline suggestions feature of JupyterCAD,&lt;/li&gt;
&lt;li&gt;An improved and more featureful Python API,&lt;/li&gt;
&lt;li&gt;A better coverage of QGIS features.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-can-you-support-our-work"&gt;How can you support our work?&lt;/h2&gt;
&lt;p&gt;Your support is important, if you would like to help us build more exciting tools around JupyterGIS, do not hesitate to contact us &lt;a href="https://jupyter.zulipchat.com/#narrow/channel/471314-geojupyter"&gt;on the public geojupyter Zulip channel!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Additionally, you can join us for the bi-weekly GeoJupyter hackathon on Wednesday &lt;a href="https://geojupyter.org/calendar.html"&gt;https://geojupyter.org/calendar.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This work on JupyterGIS by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; and &lt;a href="https://www.simula.no/"&gt;Simula Research Lab&lt;/a&gt; (Simula) &lt;a href="https://jupyter.org/blog/posts/2024/jupytergis/"&gt;was funded by the European Space Agency (ESA) for our proposal “&lt;em&gt;Real-time collaboration and collaborative editing for GIS workflows with Jupyter and QGIS&lt;/em&gt;”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are also grateful to &lt;a href="https://dse.berkeley.edu"&gt;The Eric and Wendy Schmidt Center for Data Science &amp;amp; Environment (DSE) at UC Berkeley&lt;/a&gt; for funding the work of Matt Fisher on the project.&lt;/p&gt;
&lt;p&gt;Finally, this wouldn’t have been possible without the foundational work on &lt;a href="https://github.com/jupytercad/JupyterCAD"&gt;JupyterCAD&lt;/a&gt; initiated by &lt;a href="https://github.com/trungleduc"&gt;Duc Trung Le&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-jupytergis-contributors"&gt;About the JupyterGIS contributors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/002-1_FvjrRTQuLq-RcpISEHyB8w.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/meriem-ben-ismail-163042230/"&gt;Meriem Ben Ismail&lt;/a&gt; is a Scientific Software Developer at &lt;a href="https://quantstack.net"&gt;QuantStack&lt;/a&gt;. She just completed her Software Engineering degree at &lt;a href="https://insat.rnu.tn"&gt;INSAT&lt;/a&gt; (National Institute of Applied Sciences and Technology in Tunisia) and her six-month internship as an open-source scientific software engineer at &lt;a href="https://quantstack.net"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/003-1_XiLiEd21JkqLBa_SjgN4gg.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/nicolas-brichet-a26369150/"&gt;Nicolas Brichet&lt;/a&gt; is a Scientific Software Developer at QuantStack. He holds a master’s degree in robotics from the University of Montpellier. Prior to joining Quantstack, Nicolas worked for almost fourteen years in French research institutes (INRAE and CNRS), as software developer for scientific research. He also worked on different parts of the data lifecycle, such as data acquisition, analysis, and storage.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/004-1_wLk7y0bKAluKt1Du2r2MfA.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/david-brochart-4208721/"&gt;David Brochart&lt;/a&gt; is a Technical Director at QuantStack. David used to work in the semiconductor industry as a digital circuit designer, mostly using FPGAs. He studied telecommunications at the French “Telecom Bretagne” engineering school, with major in digital circuit design. David also worked as a researcher in hydrology at Irstea, a French scientific research institute, where he heavily used the Python scientific stack.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/005-1_zPpzRreH5i7dnvg6L9DK_A.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/mfisher87"&gt;Matt Fisher&lt;/a&gt; is a Research Software Engineer and Community Manager at &lt;a href="https://dse.berkeley.edu"&gt;Schmidt Center for Data Science &amp;amp; Environment&lt;/a&gt;. Matt is passionate about open science, community-owned software, teaching and learning, accessibility, and inclusion. It is his treasured privilege to support researchers and educators in their missions by working on projects like &lt;a href="https://qgreenland.org"&gt;QGreenland&lt;/a&gt; and &lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS!&lt;/a&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/006-1_J4D8_KdSR60tPA_TVAhURA.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/annefouilloux/"&gt;Anne Fouilloux&lt;/a&gt;, a Senior Research Engineer, specializes in Open Science, FAIR data, and Big Data analytics. With a PhD in Atmospheric Physics, she has contributed to Pangeo and EOSC (European Open Science Cloud), focusing on data management, Earth system modeling, and scalable computing. A strong advocate for Open Science, she advances data accessibility and interoperability to drive scientific innovation.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/007-1_z2By7q9wyJvunxZNezKHxg.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/gjmooney/"&gt;Greg Mooney&lt;/a&gt; is a Scientific Computing Developer at &lt;a href="https://quantstack.net"&gt;QuantStack&lt;/a&gt;. He received a Bachelors degree in Software Engineering from &lt;a href="https://www.asu.edu/"&gt;Arizona State University (ASU)&lt;/a&gt;. Before joining QuantStack, he worked as an Aegis Computer Network Technician, working on the network infrastructure connecting various sensor systems onboard naval vessels.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/008-1_rliFUY5GuF6sqKnjho66EQ.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Technical Director at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; and a maintainer of &lt;a href="https://jupyter.org/"&gt;Project Jupyter&lt;/a&gt;. Among other projects Martin is a core team member of the ipywidgets project and maintains many Jupyter widget packages such as &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt;, &lt;a href="https://github.com/bloomberg/ipydatagrid"&gt;ipydatagrid&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt;, &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt;, and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt;. He is a co-creator of the &lt;a href="https://github.com/voila-dashboards/voila/"&gt;Voilà&lt;/a&gt; dashboarding system, and the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; kernel.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/real-time-collaboration-and-collaborative-editing-for/images/009-1_0_qw_xXLELz_8gHUB-3JZw.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/arjxn-py"&gt;Arjun Verma&lt;/a&gt; is a Scientific Software Development Intern at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;. He is also a final year undergraduate student at Cluster Innovation Centre, University of Delhi. He loves 3D &amp;amp; GIS and also contributes to &lt;a href="https://github.com/jupytercad/JupyterCAD"&gt;JupyterCAD&lt;/a&gt; and is one of the maintainers of &lt;a href="https://pybamm.org/"&gt;PyBaMM&lt;/a&gt; where he has also been &lt;a href="https://summerofcode.withgoogle.com/"&gt;GSoC&lt;/a&gt; contributor and mentor.&lt;/p&gt;
</content><category term="geoscience"/><category term="science"/></entry><entry><title>Announcing JupyterCAD 3.0</title><link href="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/" rel="alternate"/><published>2025-02-17T09:38:00+00:00</published><updated>2025-02-17T09:38:00+00:00</updated><author><name>Arjun Verma</name></author><id>tag:jupyter.org,2025-02-17:/blog/posts/2025/announcing-jupytercad-3-0/</id><summary type="html">&lt;p&gt;The latest iteration of the web-based collaborative CAD editor&lt;/p&gt;
</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/001-1_m9xr-RYt-bA0tfE6YwjNMQ.webp" alt="Screenshot of JupyterCAD, showing a model of gear, with an anotation editor opened." loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are thrilled to introduce JupyterCAD 3.0, the newest version of the collaborative CAD modeler designed for JupyterLab.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/jupytercad/jupytercad"&gt;JupyterCAD&lt;/a&gt; is an unofficial JupyterLab extension for 3D geometry modeling with collaborative editing support. It is designed to allow multiple people to work on the same file at the same time, and to facilitate discussion and collaboration around the 3D shapes being created.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;JupyterCAD 3.0 represents a significant leap forward in usability and user experience compared to the previous release.&lt;/p&gt;
&lt;h2 id="whats-new-in-jupytercad-30"&gt;What’s new in JupyterCAD 3.0?&lt;/h2&gt;
&lt;h3 id="color-customization"&gt;Color customization&lt;/h3&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/kTePlIUbgik" title="JupyterCAD color customization" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;JupyterCAD 3.0 allows you to customize object colors directly within the application, while we were limited to gray models in earlier versions. Adjust colors easily to suit your design needs or preferences.&lt;/p&gt;
&lt;h3 id="embedded-python-console"&gt;Embedded Python console&lt;/h3&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/eyZmY9jt6GY" title="JupyterCAD embedded console" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;The new embedded Python console offers advanced users direct access to JupyterCAD’s Python API, enabling on-the-fly scripting and automation for power users.&lt;/p&gt;
&lt;h3 id="ux-improvements"&gt;UX improvements&lt;/h3&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/j5ypepW8QxU" title="JupyterCAD Axes Helper" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;The new &lt;strong&gt;AxesHelper&lt;/strong&gt; provides a clear visual reference for coordinate axes, making it easier to navigate and align models in 3D space.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/lxYKdLS62Zw" title="JupyterCAD copy-paste functionality" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;We have also added &lt;strong&gt;copy-paste functionality&lt;/strong&gt; using &lt;strong&gt;Ctrl+C&lt;/strong&gt; and &lt;strong&gt;Ctrl+V&lt;/strong&gt; shortcuts, making it faster and easier to duplicate objects within your models.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/Dx13O7adpj8" title="JupyterCAD 3.0 improved toolbar" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;An &lt;strong&gt;improved toolbar&lt;/strong&gt; now includes options to &lt;strong&gt;toggle wireframe&lt;/strong&gt;, &lt;strong&gt;toggle transform controls&lt;/strong&gt;, &lt;strong&gt;toggle clip plane&lt;/strong&gt; and a &lt;strong&gt;toggleable console&lt;/strong&gt;, giving users quick access to essential tools.&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/790f6Wc4_Wk" title="JupyterCAD smooth camera tracking" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;JupyterCAD 3.0 also introduces &lt;strong&gt;smooth camera tracking&lt;/strong&gt;, where selecting an object from the object tree triggers a smooth transition of the camera to focus on the selected object, enhancing navigation and model exploration.&lt;/p&gt;
&lt;h3 id="mouse-based-3d-controls"&gt;Mouse-based 3D controls&lt;/h3&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/xMCvxiIglZk" title="JupyterCAD Mouse-based 3D transform controls" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Move or rotate your 3D models effortlessly with &lt;strong&gt;mouse-based controls&lt;/strong&gt; that bring fluidity and precision to model editing and interaction.&lt;/p&gt;
&lt;h3 id="suggestions-support"&gt;Suggestions support&lt;/h3&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/Zu0AT6IRA98" title="JupyterCAD suggestions" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;With JupyterCAD 3.0, collaboration becomes even more seamless with suggestions. Collaborators can propose changes to a model, which can be reviewed and applied collaboratively, fostering a dynamic and efficient workflow.&lt;/p&gt;
&lt;h2 id="try-it"&gt;Try it!&lt;/h2&gt;
&lt;figure&gt;
&lt;img alt="Screenshot of the JupyterCAD GitHub repository." src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/002-1_DmBkGvfYG37OR0UueGpdag.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Screenshot of &lt;a href="https://github.com/jupytercad/JupyterCAD"&gt;JupyterCAD GitHub repository&lt;/a&gt;, with a link to try JupyterCAD (circled in red) with JupyterLite. This is simply deployed as a static website on “GitHub Pages”.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Explore JupyterCAD 3.0 in action with our &lt;strong&gt;JupyterLite deployment&lt;/strong&gt; — no installation required. Visit us at &lt;a href="https://jupytercad.github.io/JupyterCAD"&gt;jupytercad.github.io/JupyterCAD&lt;/a&gt; and start modeling directly in your browser.&lt;/p&gt;
&lt;h2 id="installing-jupytercad"&gt;Installing JupyterCAD&lt;/h2&gt;
&lt;p&gt;You can easily install JupyterCAD with pip or mamba:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;jupytercad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;mamba&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;conda&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forge&lt;/span&gt; &lt;span class="n"&gt;jupytercad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Additionally, you can install FreeCAD along with the JupyterCAD-FreeCAD plugin to enable support for FCstd files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;mamba&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;conda&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forge&lt;/span&gt; &lt;span class="n"&gt;freecad&lt;/span&gt; &lt;span class="n"&gt;jupytercad&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;freecad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="whats-next"&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;JupyterCAD is evolving rapidly, with some exciting updates just around the corner and others in active development:&lt;/p&gt;
&lt;h3 id="upcoming-features"&gt;Upcoming Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Enhanced User Experience&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Smoother exploded view&lt;/li&gt;
&lt;li&gt;Support for renaming objects directly from object tree&lt;/li&gt;
&lt;li&gt;Incremental rotation controls for precise adjustments&lt;/li&gt;
&lt;li&gt;Enhanced 3D view settings for better customization.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nested &amp;amp; Refined Side Panel&lt;/strong&gt;: Navigate and organize objects more easily with a refined and nested side panel experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support for more File Formats&lt;/strong&gt;: Broaden compatibility with support for more file formats.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="features-in-development"&gt;Features in Development&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;New CAD Operations&lt;/strong&gt;: New tools for operations like &lt;strong&gt;linear&lt;/strong&gt; and &lt;strong&gt;radial patterns&lt;/strong&gt; to expand modeling capabilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support for measuring distances&lt;/strong&gt;: Tools to measure distances and dimensions directly in the viewport.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Improved 2D Sketcher&lt;/strong&gt;: Enhanced features to make 2D sketching more intuitive and robust.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The development of the JupyterCAD open-source project by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; was funded by a grant from &lt;a href="https://ecologie.gouv.fr/direction-generale-laviation-civile-dgac"&gt;DGAC&lt;/a&gt; in the framework of the French “Plan de Relance” (refinanced by &lt;a href="https://next-generation-eu.europa.eu/index_en"&gt;Next generation EU&lt;/a&gt;) as part of a collaboration between &lt;a href="https://www.safran-group.com/companies/safran-aircraft-engines"&gt;Safran Aircraft Engines&lt;/a&gt;, &lt;a href="https://www.inria.fr/en"&gt;INRIA&lt;/a&gt;, and &lt;a href="https://www.akkodis.com/"&gt;Akkodis&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We also extend our gratitude to the &lt;a href="https://github.com/jupytercad/JupyterCAD/graphs/contributors"&gt;external contributors&lt;/a&gt; whose efforts and feedback have been instrumental in shaping this release. Your support and collaboration drive the ongoing success of JupyterCAD.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/003-1_4LK5G7er7fRNtT4gbUoWWw.webp" alt="Logo of Safran Aircraft Engines" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;This work was built upon the strong foundation laid by open-source software projects such as &lt;a href="https://threejs.org/"&gt;&lt;strong&gt;Three.js&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://dev.opencascade.org/"&gt;&lt;strong&gt;OpenCascade&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://ocjs.org/"&gt;&lt;strong&gt;OpenCascade.js&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://www.freecad.org/"&gt;&lt;strong&gt;FreeCAD&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://github.com/jupyterlab/jupyterlab"&gt;&lt;strong&gt;JupyterLab&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://github.com/jupyterlite/jupyterlite"&gt;&lt;strong&gt;JupyterLite&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p&gt;JupyterCAD is an open-source project resulting from &lt;a href="https://github.com/jupytercad/JupyterCAD/graphs/contributors"&gt;contributors&lt;/a&gt;’ collective efforts. Below, we highlight the primary contributors for this release:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/004-0_lIAP4xLgMI8KptQn.jpg" alt="Portrait of Trung Le" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/trungleduc"&gt;Le Duc Trung&lt;/a&gt; is a Scientific Software Developer at QuantStack. He works on several projects within the Jupyter ecosystem, from the main projects like &lt;a href="https://github.com/jupyterlab/jupyterlab"&gt;JupyterLab&lt;/a&gt;, &lt;a href="https://github.com/voila-dashboards/voila/"&gt;Voilà&lt;/a&gt;, and &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt; to various JupyterLab extensions and widgets.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/005-0_RPV4uLZ7SYZ0_KwH.jpg" alt="Portrait of Martin Renou" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Technical Director at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; and a maintainer of &lt;a href="https://jupyter.org/"&gt;Project Jupyter&lt;/a&gt;. Among other projects Martin is a core team member of the ipywidgets project and maintains many Jupyter widget packages such as &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt;, &lt;a href="https://github.com/bloomberg/ipydatagrid"&gt;ipydatagrid&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt;, &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt;, and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt;. He is a co-creator of the &lt;a href="https://github.com/voila-dashboards/voila/"&gt;Voilà&lt;/a&gt; dashboarding system, and the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; kernel.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2025/announcing-jupytercad-3-0/images/006-1_ne6lm0Wifp81ZLEIB6fxiQ.webp" alt="Portrait of Arjun Verma" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/arjxn-py"&gt;Arjun Verma&lt;/a&gt; is a Scientific Software Development Intern at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;. He is also a final year undergraduate student at Cluster Innovation Centre, University of Delhi. He loves 3D &amp;amp; GIS and also contributes to &lt;a href="https://github.com/geojupyter/jupytergis"&gt;JupyterGIS&lt;/a&gt; and is one of the maintainers of &lt;a href="https://pybamm.org/"&gt;PyBaMM&lt;/a&gt; where he has also been &lt;a href="https://summerofcode.withgoogle.com/"&gt;GSoC&lt;/a&gt; contributor and mentor.&lt;/p&gt;
</content><category term="collaboration"/><category term="JupyterCAD"/></entry><entry><title>And Voici!</title><link href="https://jupyter.org/blog/posts/2023/and-voici/" rel="alternate"/><published>2023-12-06T15:21:00+00:00</published><updated>2023-12-06T15:21:00+00:00</updated><author><name>Duc Trung Le</name></author><id>tag:jupyter.org,2023-12-06:/blog/posts/2023/and-voici/</id><summary type="html">&lt;p&gt;Scaling Jupyter dashboards up to the millions.&lt;/p&gt;
</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/and-voici/images/001-1_Tjh9IaZrdJhTQzxyIOgI8Q.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Voici (meaning “here is” in French) is a novel project reshaping Jupyter-based interactive dashboards by combining &lt;a href="https://jupyter.org/blog/posts/2019/and-voila/"&gt;Voilà&lt;/a&gt; and &lt;a href="https://jupyter.org/blog/posts/2021/jupyterlite-jupyter-webassembly-python/"&gt;JupyterLite&lt;/a&gt; features. It facilitates the creation of dynamic, in-browser environments for data visualization and exploration.&lt;/p&gt;
&lt;p&gt;Built upon the foundations of Voilà, Voici inherits the ability to convert any Jupyter notebook into a standalone user-friendly dashboard. While the simplicity and extensibility of Voilà are kept intact, &lt;strong&gt;Voici adopts the in-browser execution model of JupyterLite, replacing the client-server approach&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Dashboards generated by Voici are simply a collection of static files. Deploying and scaling such dashboards is straightforward since there is no need to allocate computational resources in the backend.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Voici dashboards are extraordinarily scalable compared to their “Voilà” counterparts, since they don’t require a container per user session.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Voilà and Voici, as their name suggests, share a lot of commonalities like the CLI, the configuration options, and the templating system. The difference in their execution model results in a distinction: Voilà can hide the source code from the browser, displaying only the rendered dashboard, whereas Voici exposes the entire notebook content to the front end.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="From a notebook to a Voici dashboard" src="https://jupyter.org/blog/posts/2023/and-voici/images/002-0_pW-uDn20xeFuu6ce.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;From a notebook to a Voici dashboard&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="installation-and-first-time-use"&gt;Installation and first-time use&lt;/h2&gt;
&lt;p&gt;You can install Voici using pip:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;voici
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or using conda/mamba:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;voici&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Upon installation, the Voici command-line utility becomes available and &lt;strong&gt;can be used as a drop-in replacement for the &lt;em&gt;voila&lt;/em&gt; command&lt;/strong&gt;. For example, you can generate static dashboards from a notebook or a directory of notebooks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build a single dashboard&lt;/span&gt;
voici&lt;span class="w"&gt; &lt;/span&gt;my-notebook.ipynb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build a directory of notebooks&lt;/span&gt;
voici&lt;span class="w"&gt; &lt;/span&gt;notebooks/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Build a dashboard with a dark theme and voila-gridstack template&lt;/span&gt;
voici&lt;span class="w"&gt; &lt;/span&gt;my-notebook.ipynb&lt;span class="w"&gt; &lt;/span&gt;--template&lt;span class="w"&gt; &lt;/span&gt;gridstack&lt;span class="w"&gt; &lt;/span&gt;--theme&lt;span class="w"&gt; &lt;/span&gt;dark
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once the dashboards are built in the &lt;em&gt;_output&lt;/em&gt; directory, you can simply serve the static web page with your favorite web server. For example, using CPython’s simple HTTP server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;http.server&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;_output
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="A Voici dashboard using the dark theme" src="https://jupyter.org/blog/posts/2023/and-voici/images/003-0_26EQ9I6L6MnwIaND.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;a href="https://trungleduc.github.io/voici-stock-dashboard/voici/render/dashboard.html"&gt;A Voici dashboard&lt;/a&gt; using the dark theme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For the configurations of the themes, templates, or the tree page, you can refer to the &lt;a href="https://voila.readthedocs.io/en/stable/customize.html"&gt;Voilà documentation&lt;/a&gt; for available options. The Voici-specific configurations can be found in the &lt;a href="https://voici.readthedocs.io"&gt;Voici documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="deploy-voici-dashboard"&gt;Deploy Voici dashboard&lt;/h2&gt;
&lt;p&gt;Besides the static site hosting services, it is also possible to deploy Voici dashboards to GitHub Pages directly from your repository or to embed them into Sphinx documentation.&lt;/p&gt;
&lt;h3 id="publishing-voici-dashboards-on-github-pages"&gt;Publishing Voici dashboards on GitHub Pages&lt;/h3&gt;
&lt;p&gt;Creating your deployment on GitHub Pages is straightforward with the help of a &lt;a href="https://github.com/voila-dashboards/voici-demo"&gt;template repository&lt;/a&gt; available on GitHub. You can follow the instructions from the following video:&lt;/p&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/ejtACmuecQg" title="Voici Dashboard Deployed on Github Pages" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;The dashboard will be built by the CI action and published on the corresponding GitHub page of your repository.&lt;/p&gt;
&lt;h3 id="embedding-voici-dashboards-in-sphinx-documentation"&gt;Embedding Voici dashboards in Sphinx documentation&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;jupyterlite-sphinx&lt;/em&gt; is a Python package that allows embedding Jupyterlite in Sphinx documentation using simple directives. It is used in the documentation of major projects like &lt;em&gt;scikit-image&lt;/em&gt; or &lt;em&gt;ipywidgets&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In addition to JupyterLite applications, this package also supports embedding Voici dashboards with the &lt;a href="https://jupyterlite-sphinx.readthedocs.io/en/latest/directives/voici.html"&gt;voici directive&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;voici&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; my_notebook.ipynb
  &lt;span class="nc"&gt;:height:&lt;/span&gt; 600px
  &lt;span class="nc"&gt;:prompt:&lt;/span&gt; Try Voici!
  &lt;span class="nc"&gt;:prompt_color:&lt;/span&gt; #dc3545
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this directive, the Voici dashboard will be generated automatically with the Sphinx documentation, and the dashboard will be loaded as per user request.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A Voici dashboard embedded in Sphinx documentation" src="https://jupyter.org/blog/posts/2023/and-voici/images/004-0_uwgSS42KAo1EkCvF.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A Voici dashboard embedded in Sphinx documentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="voici-gallery"&gt;Voici gallery&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://voila-dashboards.github.io/voici-gallery/"&gt;Voici gallery&lt;/a&gt; is a collection of dashboards built with Voici, it aims to provide a source of inspiration for crafting complex dashboards entirely based on the Jupyter ecosystem.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Voici Gallery home page" src="https://jupyter.org/blog/posts/2023/and-voici/images/005-0_K5TYc8RPlRPBKcdU.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Voici Gallery home page&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you’ve created an interesting dashboard and would like to share it with a wider audience, don’t hesitate to submit a pull request &lt;a href="https://github.com/voila-dashboards/voici-gallery"&gt;here&lt;/a&gt; to have it included in the list of examples!&lt;/p&gt;
&lt;h2 id="future-development"&gt;Future development&lt;/h2&gt;
&lt;p&gt;Voici is rapidly evolving, with many improvements already in the works such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better integration with JupyterLab and JupyterLite to preview and generate Voici dashboards from their user interface.&lt;/li&gt;
&lt;li&gt;Provide more user-friendly tools to easily deploy Voici dashboards to other platforms like GitLab and HuggingFace,…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;User feedback from the community also plays a big role in the project roadmap. Explore Voici and share your thoughts with us using the &lt;a href="https://github.com/voila-dashboards/voici/issues"&gt;project’s GitHub issues&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/and-voici/images/006-0_FA4jYIdu6lJ4-U4p.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Technical Director at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; and a maintainer of &lt;a href="https://jupyter.org/"&gt;&lt;strong&gt;Project Jupyter&lt;/strong&gt;&lt;/a&gt;. Among other projects Martin is a core team member of the ipywidgets project and maintains many Jupyter widget packages such as &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt;, &lt;a href="https://github.com/bloomberg/ipydatagrid"&gt;ipydatagrid&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt;, &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt;, and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt;. He is a co-creator of the &lt;a href="https://github.com/voila-dashboards/voila/"&gt;Voilà&lt;/a&gt; dashboarding system, and the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; kernel.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/and-voici/images/007-0_TOhdhVrxFO17XsXl.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/trungleduc"&gt;Le Duc Trung&lt;/a&gt; is a Scientific Software Developer at QuantStack. He works on several projects within the Jupyter ecosystem, from the main projects like JupyterLab, Voilà, and ipywidgets to various JupyterLab extensions and widgets.&lt;/p&gt;
</content><category term="dashboards"/></entry><entry><title>Collaborative CAD in JupyterLab</title><link href="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/" rel="alternate"/><published>2023-06-02T15:15:00+00:00</published><updated>2023-06-16T14:55:00+00:00</updated><author><name>Duc Trung Le</name></author><id>tag:jupyter.org,2023-06-02:/blog/posts/2023/collaborative-cad-in-jupyterlab/</id><summary type="html">&lt;p&gt;We are thrilled to introduce JupyterCAD, a tool that integrates Computer-Aided Design (CAD) capabilities into JupyterLab.&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/001-1_9r3Xz-v5wyuz8aAKY2WV-A.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;We are thrilled to introduce &lt;a href="https://jupytercad.readthedocs.io/"&gt;JupyterCAD&lt;/a&gt;, a tool that integrates &lt;strong&gt;Computer-Aided Design&lt;/strong&gt; (CAD) capabilities into JupyterLab. With its &lt;strong&gt;JupyterLab extension&lt;/strong&gt;, dedicated &lt;strong&gt;JupyterCAD application&lt;/strong&gt;, and &lt;strong&gt;Python API for CAD operations&lt;/strong&gt;, JupyterCAD allows users to effortlessly create, edit and share 3D designs without leaving the Jupyter ecosystem.&lt;/p&gt;
&lt;p&gt;This blog post provides an overview of JupyterCAD’s features and highlights its &lt;strong&gt;collaborative editing capabilities&lt;/strong&gt; which enable teamwork in the realm of CAD.&lt;/p&gt;
&lt;p&gt;Everything that is shown below can be tested by installing JupyterCAD from PyPI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# From PyPI&lt;/span&gt;
pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;jupytercad
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;h2 id="one-extension-three-interfaces"&gt;One extension, three interfaces&lt;/h2&gt;
&lt;p&gt;Built using the latest JupyterLab 4 release, JupyterCAD combines CAD functionalities with the &lt;a href="https://jupyter.org/blog/posts/2022/accelerating-jupyterlab/"&gt;enhanced performance&lt;/a&gt; and &lt;a href="https://jupyter.org/blog/posts/2023/improving-the-accessibility-of-jupyter/"&gt;accessibility improvements&lt;/a&gt; introduced in JupyterLab 4. The flexibility of JupyterLab allows us to create the extension once but deploy it in multiple ways to target three groups of audiences: users who prefer working in the JupyterLab environment, users who favor dedicated applications, and those advanced users who do everything programmatically.&lt;/p&gt;
&lt;h3 id="jupyterlab-extension"&gt;JupyterLab Extension&lt;/h3&gt;
&lt;p&gt;Experience CAD features directly within JupyterLab with the JupyterCAD extension. Open and edit &lt;a href="https://www.freecad.org/"&gt;FreeCAD&lt;/a&gt; files, perform CAD operations, including creating 3D primitives, applying boolean operators, and exploding the view. JupyterCAD’s extension integrates seamlessly into JupyterLab, providing an intuitive environment for CAD enthusiasts and data scientists alike.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The integrated interface of JupyterCAD inside JupyterLab" src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/002-1_gnukYLJE43zcmuaEAwCuOA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterCAD extension inside JupyterLab&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="jupytercad-application"&gt;JupyterCAD Application&lt;/h3&gt;
&lt;p&gt;For a streamlined CAD experience, JupyterCAD offers a dedicated application that eliminates distractions and emphasizes CAD features.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="An interface of the standalone JupyterCAD application" src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/003-1_AcyuVpviiNtSal9Wi4CDYQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The standalone JupyterCAD Application.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Starting the dedicated JupyterCAD application is as simple as starting JupyterLab or Jupyter Notebook:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jupyter&lt;span class="w"&gt; &lt;/span&gt;cad
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This dedicated application has been built in a similar way to the coming &lt;a href="https://jupyter.org/enhancement-proposals/79-notebook-v7/notebook-v7.html"&gt;Jupyter Notebook 7&lt;/a&gt;. It’s a JupyterLab “remix” built from the ground up using JupyterLab core components and custom extensions. Much like JupyterLab, it offers theming and localization support, and more planned features on the horizon.&lt;/p&gt;
&lt;h3 id="python-api-for-cad-operations"&gt;Python API for CAD Operations&lt;/h3&gt;
&lt;p&gt;Advanced users can unlock the full potential of CAD operations with JupyterCAD’s Python API. JupyterCAD allows users to programmatically visualize, create, and manipulate the shapes from a Jupyter Notebook. For example, one can open a FreeCAD file and start modifying it from the notebook with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;jupytercad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CadDocument&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CadDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;example.FCStd&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Create a cone, a sphere then cut the cone with the sphere.&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_cone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_sphere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="An animation of using JupyterCAD python API in notebook" src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/004-1_I_XVE0J8vjYne5wnsZ9WuA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Adding object to FreeCAD file from Jupyter Notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;JupyterCAD API also integrates nicely with the &lt;a href="https://github.com/tpaviot/pythonocc-core"&gt;OpenCascade Python API&lt;/a&gt;, providing expanded capabilities for working with shapes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;jupytercad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CadDocument&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;# Create a prism shape with OpenCascade&lt;/span&gt;
&lt;span class="n"&gt;prism&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BRepPrimAPI_MakePrism&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CadDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_occ_shape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prism&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="Visualize OpenCascade shape object with JupyterCAD." src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/005-1_4qvN9PdUYf5-jq5rjYUAEQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Visualize OpenCascade shape object with JupyterCAD.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="unlocking-teamwork-with-real-time-collaboration"&gt;Unlocking teamwork with real-time collaboration&lt;/h2&gt;
&lt;h3 id="collaborative-editing"&gt;Collaborative Editing&lt;/h3&gt;
&lt;p&gt;One of the standout features of JupyterCAD is its shared editing functionality, which seamlessly &lt;strong&gt;connects users across different interfaces within the JupyterCAD ecosystem&lt;/strong&gt;. Whether collaborators are using the dedicated JupyterCAD application, the JupyterLab extension, or working with the Python API in a Notebook, any changes made to a shared document are instantly reflected for all users.&lt;/p&gt;
&lt;p&gt;Real-time collaboration allows individuals working in the Python API to make modifications to the CAD document, while simultaneously providing a synchronized view for collaborators using the JupyterLab extension or the JupyterCAD application. This ensures that all participants have access to the most up-to-date version of the design, fostering efficient communication and &lt;strong&gt;eliminating the need for manual synchronization or file exchange&lt;/strong&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Real-time collaborative editing in JupyterCAD" src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/006-1_4lDSgoYLrUqX7SQul_yXxw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Real-time collaborative editing in JupyterCAD.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="follow-mode"&gt;Follow Mode&lt;/h3&gt;
&lt;p&gt;With JupyterCAD’s follow-mode feature, collaboration becomes even more fluid. You can follow another user’s camera movements and view adjustments in real-time. This mode allows you to gain insights into the design process, and enhance communication among team members.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Follow Mode in action." src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/007-1_DgAD-S5mvLOEK6RtDM8GZA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Follow Mode in action.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="annotations-system"&gt;Annotations System&lt;/h3&gt;
&lt;p&gt;The annotations system in JupyterCAD adds an interactive layer to 3D designs. Now you can add annotations to specific shapes within a CAD file, give context, provide feedback, or write instructions.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Adding annotation at precise positions" src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/008-1_QD98Lrlr7_CJfgVbxHhf6w.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Adding annotation at precise positions&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;hr&gt;
&lt;h2 id="what-goes-on-under-the-hood"&gt;What goes on under the hood?&lt;/h2&gt;
&lt;p&gt;All the above features are made possible thanks to two major open-source components: &lt;a href="https://ocjs.org/"&gt;&lt;strong&gt;OpenCascade.js&lt;/strong&gt;&lt;/a&gt;, the WebAssembly build of OpenCascade, and &lt;a href="https://github.com/jupyterlab/jupyter_collaboration"&gt;&lt;strong&gt;jupyter_collaboration&lt;/strong&gt;&lt;/a&gt;, the real-time collaboration framework of JupyterLab.&lt;/p&gt;
&lt;h3 id="in-browser-geometric-modeling-kernel"&gt;In-browser geometric modeling kernel&lt;/h3&gt;
&lt;p&gt;To execute all geometric operations, JupyterCAD uses a custom build of &lt;strong&gt;OpenCascade.js,&lt;/strong&gt; which is a port of the OpenCascade library to JavaScript and WebAssembly via Emscripten. Running on a separate thread, the CAD Kernel of JupyterCAD allows users to perform complex operations at near-native speed. It also helps to lower the load of the server while serving JupyterCAD to many users.&lt;/p&gt;
&lt;h3 id="jupyterlab-real-time-collaboration-framework"&gt;JupyterLab Real-Time Collaboration framework&lt;/h3&gt;
&lt;p&gt;In JupyterLab 4, Real-Time Collaboration (RTC) is not only about editing notebooks but it has become a framework for building collaborative applications. Using the components of &lt;strong&gt;jupyter_collaboration&lt;/strong&gt; helps us accelerate the development of the RTC features in JupyterCAD. Collaborative Editing is built upon a shared data model where &lt;strong&gt;jupyter_collaboration&lt;/strong&gt; handles all the transportation and conflict resolution, while Follow Mode makes use of Awareness, a lightweight notification system provided by the library.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="future-work"&gt;Future work&lt;/h2&gt;
&lt;p&gt;The current state of JupyterCAD illustrates the capabilities of JupyterLab as a foundation to build complex applications, not just for scientific computing but also for more general technical computing applications.&lt;/p&gt;
&lt;p&gt;We will continue to improve JupyterCAD on two axes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enhancing the 3D viewer with features to help users interact with the objects&lt;/li&gt;
&lt;li&gt;Enriching the Python API to improve interoperability with other CAD libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We plan on upstreaming some of the features of JupyterCAD, like the annotations system and the Follow Mode, to jupyter_collaboration to enable it in other file contexts in JupyterLab (Notebooks, text files, etc).&lt;/p&gt;
&lt;p&gt;User feedback from the community also plays a big role in the project roadmap. Try JupyterCAD and share your feedback with us using the project’s &lt;a href="https://github.com/QuantStack/jupytercad/issues"&gt;GitHub issues&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/009-0_3Y8y-PCaP2B9a6de.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/trungleduc"&gt;Le Duc Trung&lt;/a&gt; is a Scientific Software Developer at QuantStack. He works on several projects within the Jupyter ecosystem, from the main projects like JupyterLab, Voilà, and ipywidgets to various JupyterLab extensions and widgets.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2023/collaborative-cad-in-jupyterlab/images/010-0_A1jOuQ60SPZ_NTVv.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Technical Director at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; and a maintainer of &lt;a href="https://jupyter.org/"&gt;&lt;strong&gt;Project Jupyter&lt;/strong&gt;&lt;/a&gt;. Among other projects Martin is a core team member of the ipywidgets project and maintains many Jupyter widget packages such as &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt;, &lt;a href="https://github.com/bloomberg/ipydatagrid"&gt;ipydatagrid&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt;, &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt;, and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt;. He is a co-creator of the &lt;a href="https://github.com/voila-dashboards/voila/"&gt;Voilà&lt;/a&gt; dashboarding system, and the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; kernel.&lt;/p&gt;
</content><category term="collaboration"/><category term="JupyterCAD"/><category term="JupyterLab"/></entry><entry><title>Mamba meets JupyterLite</title><link href="https://jupyter.org/blog/posts/2022/mamba-meets-jupyterlite/" rel="alternate"/><published>2022-07-14T11:19:00+00:00</published><updated>2022-07-15T10:26:00+00:00</updated><author><name>Thorsten Beier</name></author><id>tag:jupyter.org,2022-07-14:/blog/posts/2022/mamba-meets-jupyterlite/</id><summary type="html">&lt;p&gt;Introducing a mamba-based distribution for WebAssembly, and deploying scalable computing environments with JupyterLite.&lt;/p&gt;
</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/mamba-meets-jupyterlite/images/001-1_dbJO26hiSR8EFygX1rnqrA.webp" alt="JupyterLite logo" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;JupyterLite is a Jupyter distribution that runs entirely in the web browser without any server components. To achieve this, all language kernels must also run in the browser.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A screenshot of JupyterLite running in the Browser. One can see as Matplotlib figure and some Pandas DataFrame code. Furthermore a p5.js kernel instance is visible." src="https://jupyter.org/blog/posts/2022/mamba-meets-jupyterlite/images/002-0_MoW-XpW5yQgCxinq.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;JupyterLite running in the browser as a static website&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A significant benefit of this approach is the &lt;strong&gt;ease of deployment&lt;/strong&gt;. With JupyterLite, the only requirement to provide a live computing environment is a collection of static assets. It makes it possible to embed a console or a notebook interface on any static page or blog without having to deal with a server architecture deployment. The &lt;strong&gt;scalability&lt;/strong&gt; of this approach allowed several major projects of our ecosystem (&lt;a href="https://numpy.org"&gt;NumPy&lt;/a&gt;, &lt;a href="https://www.sympy.org/en/shell.html"&gt;SymPy&lt;/a&gt;, &lt;a href="https://pandas.pydata.org/getting_started.html"&gt;Pandas&lt;/a&gt;, &lt;a href="https://www.pymc.io/welcome.html"&gt;PyMC&lt;/a&gt;, and many more) to embed interactive examples on their websites, which are visited by millions of users monthly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;JupyterLite is the easiest and most scalable way to embed an interactive console or notebook on a web page without any server component.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The most prominent JupyterLite kernel is the &lt;em&gt;Pyolite&lt;/em&gt; Python kernel, which is based on the &lt;a href="https://pyodide.org/en/stable/"&gt;Pyodide&lt;/a&gt; distribution for WebAssembly. Beyond the CPython interpreter, Pyodide includes many popular scientific computing packages such as NumPy, Pandas, and Matplotlib. Pyodide also provides a foreign function interface (FFI) that allows calling Python from JavaScript and vice versa.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLite inline console embedded on the SymPy project website" src="https://jupyter.org/blog/posts/2022/mamba-meets-jupyterlite/images/003-1_rKzDNlHO6LnhH1ZDyb996g.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLite inline console embedded on the &lt;a href="https://www.sympy.org/en/shell.html"&gt;SymPy project website&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="pyodide-and-beyond"&gt;Pyodide — and beyond&lt;/h2&gt;
&lt;p&gt;While Pyodide provides many scientific computing packages, its monolithic distribution model does not allow to specify package versions, although versions of pure python packages installed on top can be set. Our goal is to enable the &lt;strong&gt;composability of computing environments&lt;/strong&gt; allowed by package managers and to adopt the conda-forge model for large-scale software distribution crowdsourcing.&lt;/p&gt;
&lt;p&gt;Being able to pin down package versions in an environment is a strong requirement for software &lt;strong&gt;reproducibility.&lt;/strong&gt; In fact, a locked WebAssembly environment could be seen as a reproducibility &lt;strong&gt;time capsule&lt;/strong&gt;. As WebAssembly is a recognized web standard, it ought to be runnable for much longer than native binary packages: these are bound to a combination of architecture and platform and will eventually require an emulator.&lt;/p&gt;
&lt;p&gt;This is why we developed a mamba-based distribution of WebAssembly packages built with Emscripten.&lt;/p&gt;
&lt;h2 id="emscripten-forge"&gt;Emscripten-forge&lt;/h2&gt;
&lt;p&gt;The choice of the Mamba/Conda package manager was natural. Its main strength is the conda-forge community-maintained distribution, which has become the &lt;em&gt;de facto&lt;/em&gt; standard source of packages for scientific computing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Beyond its solid technological foundations and the multi-platform nature of the conda-forge distribution, its main strength is its social model. It allowed for a crowdsourcing approach of the packaging problem, with a balance of separation of concerns between maintainer teams and across-the-board automation, plus an amazing maintainers community.&lt;/p&gt;
&lt;p&gt;We plan on contributing this work to the conda-forge project, so that all recipes live in the same space.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Mamba/Conda package manager has support for many platforms and architectures such as Linux, OS X (for both x86 and arm64), and Windows. However, the &lt;strong&gt;WebAssembly&lt;/strong&gt; family of platforms is not supported yet.&lt;/p&gt;
&lt;h3 id="adding-support-for-webassembly-to-mamba-conda"&gt;Adding support for WebAssembly to mamba &amp;amp; conda&lt;/h3&gt;
&lt;p&gt;To create conda packages for the WebAssembly platform, we relied on the &lt;a href="https://emscripten.org/"&gt;Emscripten toolchain&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We defined a new target platform for conda-build and boa, namely &lt;code&gt;wasm32-unknown-emscripten&lt;/code&gt; for which we use the &lt;code&gt;emscripten-32&lt;/code&gt; shorthand name. We then associated the &lt;a href="https://emscripten.org/"&gt;Emscripten&lt;/a&gt; compiler, &lt;a href="https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes/emscripten_emscripten-32"&gt;wrapped in a conda package&lt;/a&gt; as the C/C++ compiler for this new target.&lt;br&gt;
This already allowed us to build many packages, including simple libraries like &lt;code&gt;bzip2&lt;/code&gt; and &lt;code&gt;zlib&lt;/code&gt;, but also more complex packages like &lt;code&gt;Python&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For Python extension modules we used &lt;a href="https://github.com/benfogle/crossenv"&gt;&lt;code&gt;crossenv&lt;/code&gt;&lt;/a&gt; which can create virtual environments for cross-compiling, and &lt;a href="https://github.com/conda-forge/cross-python-feedstock"&gt;&lt;code&gt;cross-python&lt;/code&gt;&lt;/a&gt; which integrates &lt;a href="https://github.com/benfogle/crossenv"&gt;&lt;code&gt;crossenv&lt;/code&gt;&lt;/a&gt; into conda. All the code and recipes for cross-compilation are hosted on the &lt;a href="https://github.com/emscripten-forge/recipes"&gt;emscripten-forge GitHub repository&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We then used &lt;a href="https://github.com/emscripten-forge/recipes/blob/main/.github/workflows/build_recipes.yaml"&gt;GitHub actions&lt;/a&gt; to build packages with Emscripten and upload them to a package server.&lt;/li&gt;
&lt;li&gt;Packages are hosted on a deployment of the &lt;a href="https://github.com/mamba-org/quetz"&gt;Quetz&lt;/a&gt; open-source server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this, you can easily create an environment for the &lt;code&gt;emscripten-32&lt;/code&gt; target:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;micromamba create -n my-env --platform=emscripten-32 \
    -c https://repo.mamba.pm/emscripten-forge \
    -c https://repo.mamba.pm/conda-forge \
    python ipython numpy jedi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that we not only added emscripten-forge as a channel, but also &lt;a href="https://repo.mamba.pm/conda-forge"&gt;conda-forge&lt;/a&gt;. This means all noarch packages can be used.&lt;/p&gt;
&lt;h3 id="adding-new-packages-to-the-emscripten-forge-channel"&gt;Adding new packages to the emscripten-forge channel&lt;/h3&gt;
&lt;p&gt;Adding new packages is a simple procedure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fork the repository &lt;a href="https://github.com/emscripten-forge/recipes"&gt;https://github.com/emscripten-forge/recipes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;create a folder for your package in &lt;a href="https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten"&gt;&lt;strong&gt;recipes/recipes_emscripten/&amp;lt;my_package&amp;gt;&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;add a &lt;a href="https://github.com/emscripten-forge/recipes/blob/main/recipes/recipes_emscripten/widgetsnbextension/recipe.yaml"&gt;&lt;code&gt;recipe.yaml&lt;/code&gt;&lt;/a&gt; for your package in &lt;code&gt;recipes/recipes_emscripten/&amp;lt;your_package&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;create a pull request containing the recipe. Once the pull request is merged, the package is automatically uploaded to the &lt;code&gt;emscripten-forge&lt;/code&gt; channel.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="integration-with-jupyterlite"&gt;Integration with JupyterLite&lt;/h2&gt;
&lt;p&gt;Even though this is a general-purpose conda-based distribution for Emscripten packages, we had one particular application in mind for this first iteration: &lt;strong&gt;JupyterLite&lt;/strong&gt;. The existing Pyolite kernel is too tightly coupled with the Pyodide distribution, so we decided to go with &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;&lt;strong&gt;xeus-python&lt;/strong&gt;&lt;/a&gt; instead.&lt;/p&gt;
&lt;p&gt;The main reason for picking &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt; (over ipykernel) is that with xeus-based kernels, it is possible to override the communication layer of the kernel (switching e.g. from ZMQ to HTTP/2). In the case of JupyterLite, the implementation simply relies on direct JavaScript function calls.&lt;/p&gt;
&lt;p&gt;You can check out our &lt;a href="https://jupyter.org/blog/posts/2021/xeus-lite/"&gt;earlier blog post&lt;/a&gt; for more details on the JupyterLite xeus-based kernels.&lt;/p&gt;
&lt;h3 id="providing-a-complete-python-development-experience"&gt;Providing a complete Python development experience&lt;/h3&gt;
&lt;p&gt;Some remaining intrinsic limitations to the WebAssembly platform need to be worked around to provide a complete experience to end-users. For example, sockets cannot be created in WebAssembly, preventing the use of the default asyncio event loop implementation. Luckily, the Pyodide authors developed a custom asyncio event-loop called &lt;a href="https://pyodide.org/en/latest/usage/api/python-api/webloop.html"&gt;WebLoop&lt;/a&gt;: it wraps the browser event loop using the Python — JavaScript foreign function interface (FFI) provided with &lt;a href="https://pyodide.org/en/stable/usage/type-conversions.html"&gt;Pyodide&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id="pyjs"&gt;Pyjs&lt;/h4&gt;
&lt;p&gt;Since it is non-trivial to extract Pyodide’s FFI and use it for other projects, we created a modern Python - JavaScript FFI from scratch. This was done with the following tricks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pybind/pybind11"&gt;Pybind11&lt;/a&gt; is used to call Python from C++ and vice versa,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html"&gt;Embind&lt;/a&gt; is used to call JavaScript from C++ and vice versa.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When we use &lt;a href="https://github.com/pybind/pybind11"&gt;Pybind11&lt;/a&gt; and &lt;a href="https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html"&gt;Embind&lt;/a&gt; together we can call Python from JavaScript and vice versa, with C++ as a man in the middle. This not only allows us to write a simple FFI from scratch with relatively little code but also avoids calling any low-level CPython APIs and enables using high-level constructs — like &lt;a href="https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html#calling-python-functions"&gt;&lt;code&gt;pybind11::object&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://emscripten.org/docs/api_reference/val.h.html"&gt;&lt;code&gt;emscripten::val&lt;/code&gt;&lt;/a&gt;— instead.&lt;br&gt;
The code is available in the &lt;a href="https://github.com/emscripten-forge/pyjs"&gt;pyjs&lt;/a&gt; repository. The API is very similar to Pyodide’s so that it can be used as a drop-in replacement in code, like Pyodide’s &lt;a href="https://pyodide.org/en/latest/usage/api/python-api/webloop.html"&gt;WebLoop&lt;/a&gt; implementation.&lt;/p&gt;
&lt;h4 id="deployment"&gt;Deployment&lt;/h4&gt;
&lt;p&gt;The &lt;a href="https://github.com/jupyterlite/xeus-python-kernel"&gt;xeus-python-kernel&lt;/a&gt; allows conda packages to be pre-installed in the Python runtime. This can be done by passing the &lt;code&gt;XeusPythonEnv.packages&lt;/code&gt; CLI option to &lt;code&gt;jupyter lite build&lt;/code&gt;. The following command will install &lt;code&gt;NumPy&lt;/code&gt;, &lt;code&gt;Matplotlib&lt;/code&gt;, and &lt;code&gt;ipyleaflet&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;jupyter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lite&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;XeusPythonEnv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;\
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;\
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;matplotlib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;\
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;ipyleaflet&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="xeus-python kernel with the ipyleaflet widget visible." src="https://jupyter.org/blog/posts/2022/mamba-meets-jupyterlite/images/004-1_JCiZIwwkFen5kwEA2rK4SA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Running the xeus-python kernel with the ipyleaflet widget in JupyterLite&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More details can be found in the &lt;a href="https://github.com/jupyterlite/xeus-python-kernel"&gt;xeus-python-kernel GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="what-about-the-future"&gt;What about the future?&lt;/h2&gt;
&lt;p&gt;This combination of JupyterLite and Mamba has the potential to open Jupyter to millions of additional users.&lt;br&gt;
Given its scalability, ease of deployment, reproducibility, and accessibility, JupyterLite will be everywhere: countries, organizations, and schools that don’t have access to sovereign cloud infrastructure will be able to deploy Jupyter-based education platforms on servers that they truly own, without endangering the data of their students or becoming too reliant on resources that they do not control.&lt;/p&gt;
&lt;p&gt;In the short term, we are working on the following “next steps”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mambalite:&lt;/strong&gt; To support the installation of packages at runtime. Similar to Pyodide’s pip-lite, it will allow downloading packages at runtime.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fortran:&lt;/strong&gt; Compiling Fortran code with Emscripten is currently not supported, but it is necessary for key packages like SciPy. Pyodide relies on f2c, a Fortran-to-C converter, in conjunction with a set of patches to compile Fortran code with Emscripten. We are working on a more direct approach: compiling SciPy natively with &lt;a href="https://lfortran.org/"&gt;LFortran&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Binderlite:&lt;/strong&gt; Binder converts a repository of notebooks into an executable JupyterLab environment, making code immediately reproducible by anyone, anywhere. Emscripten-forge is the missing piece to build BinderLite, a version of Binder relying on JupyterLite instances instead of vanilla JupyterLab instances.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust/PyO3 support:&lt;/strong&gt; We are working on integrating the &lt;a href="https://blog.pyodide.org/posts/rust-pyo3-support-in-pyodide/"&gt;work of the Pyodide team&lt;/a&gt; on Rust/PyO3 support in emscripten-forge. This will be important to build Rust extension modules like &lt;code&gt;cryptography&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="credits"&gt;Credits&lt;/h2&gt;
&lt;p&gt;This was built upon the work of a much bigger crowd!&lt;/p&gt;
&lt;h3 id="the-pyodide-team"&gt;The Pyodide team&lt;/h3&gt;
&lt;p&gt;The Pyodide project was started at the Mozilla foundation by &lt;a href="https://twitter.com/MDroettboom"&gt;Michael Droettboom&lt;/a&gt; and is now maintained by &lt;a href="https://github.com/hoodmane"&gt;Hood Chatham&lt;/a&gt;, &lt;a href="https://twitter.com/RomanYurchak"&gt;Roman Yurchak&lt;/a&gt;, and &lt;a href="https://github.com/ryanking13"&gt;Gyeongjae Choi&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The foundational work of the Pyodide project pioneered the use of Python in the browser and made all of the rest possible, from JupyterLite to this work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="the-emscripten-team"&gt;The Emscripten team&lt;/h3&gt;
&lt;p&gt;Both Pyodide and emscripten-forge are built upon the Emscripten toolchain, which provides the foundational components to be able to meaningfully run WebAssembly programs in the browser.&lt;/p&gt;
&lt;h3 id="the-jupyterlite-team"&gt;The JupyterLite team&lt;/h3&gt;
&lt;p&gt;The JupyterLite project was started by &lt;a href="https://twitter.com/jtpio"&gt;Jeremy Tuloup&lt;/a&gt;, with significant contributions from &lt;a href="https://github.com/bollwyvl"&gt;Nick Bollweg&lt;/a&gt; and &lt;a href="https://twitter.com/martinrenou"&gt;Martin Renou&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="the-mamba-org-team"&gt;The Mamba Org team&lt;/h3&gt;
&lt;p&gt;The mamba ecosystem has been instrumental in making these developments possible. We use the Quetz open-source server for hosting the packages and the Boa tool to build them. In the mamba development team, we should highlight the work of &lt;a href="https://twitter.com/wuoulf"&gt;Wolf Vollprecht&lt;/a&gt;, &lt;a href="https://twitter.com/johanmabille"&gt;Johan Mabille&lt;/a&gt;, &lt;a href="https://twitter.com/MJKlaim"&gt;Joel Lamotte&lt;/a&gt;, and &lt;a href="https://twitter.com/atrawog"&gt;Andreas Trawöger&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="the-xeus-team"&gt;The Xeus team&lt;/h3&gt;
&lt;p&gt;The xeus project was started by &lt;a href="https://twitter.com/johanmabille"&gt;Johan Mabille&lt;/a&gt; and &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;. It is at the foundation of the JupyterLite integration and helped to get all the pieces together (Xeus, Mamba, Jupyter). We should especially credit the work of &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; and &lt;a href="https://twitter.com/thorstenbeier"&gt;Thorsten Beier&lt;/a&gt; on this integration with JupyterLite.&lt;/p&gt;
&lt;h2 id="acknowledgment"&gt;Acknowledgment&lt;/h2&gt;
&lt;p&gt;The work of Thorsten Beier, Johan Mabille, Martin Renou, Sylvain Corlay, Wolf Vollprecht, Joel Lamotte, and Andreas Trawoger at &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; was funded by &lt;a href="https://twitter.com/TechAtBloomberg?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;h3 id="thorsten-beier"&gt;Thorsten Beier&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/thorstenbeier"&gt;Thorsten Beier&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he graduated in computer science at the University of Heidelberg and worked at the &lt;a href="https://www.embl.org/"&gt;EMBL&lt;/a&gt;. As an open-source developer, Thorsten worked on a variety of projects, from &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;xeus&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; in C++ to &lt;a href="https://github.com/inferno-pytorch/inferno"&gt;inferno&lt;/a&gt;, &lt;a href="https://kipoi.org/"&gt;kipoi&lt;/a&gt;, &lt;a href="https://www.ilastik.org/"&gt;ilastik&lt;/a&gt;, and &lt;a href="https://github.com/uhlmanngroup/napari-splineit"&gt;napari-splineit&lt;/a&gt; in Python.&lt;/p&gt;
&lt;h3 id="martin-renou"&gt;Martin Renou&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he studied at the French Aerospace Engineering School &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt;. He also worked at Logilab in Paris and Enthought in Cambridge. As an open-source developer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, Martin worked on a variety of projects, from &lt;a href="https://github.com/QuantStack/xsimd"&gt;xsimd&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt;, and &lt;a href="https://github.com/QuantStack/xframe"&gt;xframe&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; in Python and JavaScript.&lt;/p&gt;
</content><category term="JupyterLite"/><category term="WebAssembly"/></entry><entry><title>Inspector JupyterLab</title><link href="https://jupyter.org/blog/posts/2022/inspector-jupyterlab/" rel="alternate"/><published>2022-04-11T11:50:00+00:00</published><updated>2022-04-21T09:37:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2022-04-11:/blog/posts/2022/inspector-jupyterlab/</id><summary type="html">&lt;p&gt;JupyterLab provides multiple ways to improve your coding workflow: code highlighting, code completion, theming, debugger with rich variable rendering and more.&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/inspector-jupyterlab/images/001-1_pRzjLlwQIIMhJmx2G_3-Mw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;JupyterLab provides multiple ways to improve your coding workflow: code highlighting, code completion, theming, debugger with rich variable rendering and more.&lt;/p&gt;
&lt;h2 id="the-jupyterlab-inspector"&gt;The JupyterLab inspector&lt;/h2&gt;
&lt;p&gt;The JupyterLab inspector is one of the ways to enhance your coding experience, it is a UI panel that provides &lt;strong&gt;contextual help&lt;/strong&gt; while you are typing:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/inspector-jupyterlab/images/002-1_zSExeL4Doygxl-o3lnStuQ.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;You can open the inspector using the &lt;strong&gt;Ctrl + I&lt;/strong&gt; shortcut (or &lt;strong&gt;⌘ + I&lt;/strong&gt; on Mac).&lt;/p&gt;
&lt;p&gt;With the Python kernel (ipykernel or xeus-python), this contextual help normally contains a text representation generated using the &lt;code&gt;inspect&lt;/code&gt; Python module and the docstrings associated to an object. But there is a way to make it much nicer!&lt;/p&gt;
&lt;h2 id="go-go-gadget-docrepr"&gt;Go-Go-Gadget Docrepr&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/spyder-ide/docrepr"&gt;Docrepr&lt;/a&gt; is a Python package which &lt;strong&gt;renders docstrings into HTML&lt;/strong&gt; using &lt;a href="https://www.sphinx-doc.org/"&gt;Sphinx&lt;/a&gt;, maintained by the Spyder team. IPython allows to use docrepr for code inspection, making it the perfect combination for a nice rendering of the contextual help in the inspector!&lt;/p&gt;
&lt;p&gt;Thanks to the recent work on the &lt;a href="https://github.com/jupyterlab/jupyterlab_pygments"&gt;jupyterlab-pygments&lt;/a&gt; extension, the docrepr output even &lt;strong&gt;respect the current JupyterLab theme&lt;/strong&gt; for syntax highlighting!&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/inspector-jupyterlab/images/003-1_OtluradnAZEDP_Cpe7x-hQ.mp4" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;
&lt;p&gt;First you will need to install the package (either with pip or mamba)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install docrepr jupyterlab_pygments
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install -c conda-forge docrepr jupyterlab_pygments
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order for IPython to use docrepr, you will need to execute the following in your Notebook (&lt;em&gt;e.g.&lt;/em&gt; in the first cell):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ip = get_ipython()
ip.sphinxify_docstring = True
ip.enable_html_pager = True
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This also can be set in your IPython configuration file located in &lt;code&gt;~/.ipython/profile_default/ipython_config.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;c = get_config()

c.InteractiveShell.sphinxify_docstring = True
c.InteractiveShell.enable_html_pager = True
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You are all set! The JupyterLab inspector will now render HTML representations of the contextual help.&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;Docrepr has a long history, it originates from the Sphinxify tool of the Sage project that was created back in 2009 by &lt;a href="https://twitter.com/timdumol"&gt;Tim Dumol&lt;/a&gt;. In 2010 &lt;a href="https://twitter.com/ccordoba12?lang=en"&gt;Carlos Córdoba&lt;/a&gt; used it to power Spyder’s help pane and in 2015 he extracted that code and created the docrepr Python package, so that other projects could benefit from it. It was later integrated in IPython by &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;. In 2021 &lt;a href="https://github.com/CAM-Gerlach"&gt;C.A.M. Gerlach&lt;/a&gt;, &lt;a href="https://github.com/fasiha"&gt;Ahmed Fasih&lt;/a&gt; and myself updated the package to support the latest Sphinx version.&lt;/p&gt;
&lt;p&gt;My work on this project at &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; was funded by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/inspector-jupyterlab/images/004-0_Rb8PCWI-Ozz0Fhxy.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt;, I am a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt;. Before joining QuantStack, I studied at the aerospace engineering school &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt; in Toulouse, France. I also worked at Logilab in Paris, France and Enthought in Cambridge, UK. As an open-source developer at QuantStack, I work on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; in Python and JavaScript/TypeScript, I am also the author of several JupyterLab extensions.&lt;/p&gt;
</content><category term="documentation"/><category term="JupyterLab"/></entry><entry><title>Jupyter Everywhere</title><link href="https://jupyter.org/blog/posts/2022/jupyter-everywhere/" rel="alternate"/><published>2022-03-15T15:22:00+00:00</published><updated>2022-03-15T15:38:00+00:00</updated><author><name>Jeremy Tuloup</name></author><id>tag:jupyter.org,2022-03-15:/blog/posts/2022/jupyter-everywhere/</id><summary type="html">&lt;p&gt;Easily embed a console, a notebook, or a fully-fledged IDE on any web page.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Easily embed a console, a notebook, or a fully-fledged IDE on any web page.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In a &lt;a href="https://jupyter.org/blog/posts/2021/jupyterlite-jupyter-webassembly-python/"&gt;previous blog post&lt;/a&gt;, we announced JupyterLite, a JupyterLab distribution that runs entirely in the web browser, backed by in-browser language kernels.&lt;/p&gt;
&lt;p&gt;By default, JupyterLite ships with a Python kernel powered by &lt;a href="https://pyodide.org"&gt;Pyodide&lt;/a&gt; and &lt;a href="https://ipython.readthedocs.io/en/stable"&gt;IPython&lt;/a&gt;, bringing a wide variety of features from &lt;strong&gt;code completion&lt;/strong&gt; to &lt;strong&gt;interactive visualizations&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The latest releases of JupyterLite now ship with a REPL application by default, that you can embed in any website.&lt;/p&gt;
&lt;h2 id="embed-a-live-python-console-on-your-website"&gt;Embed a live Python console on your website 🚀&lt;/h2&gt;
&lt;p&gt;Do you want to add an interactive code console to your website, so your visitors can run Python code directly in their browser without installing anything?&lt;/p&gt;
&lt;p&gt;Let’s say you already have a static website up and running. This could for example be a Jekyll blog. With the JupyterLite REPL, you can embed the interactive console in your website with something as simple as the following code snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://jupyterlite.github.io/demo/repl/index.html?kernel=python&amp;amp;toolbar=1&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;500px&amp;quot;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And there you have it, a live Python REPL embedded in your blog! 🎉&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="An example of embedding a live Python console in a Jekyll blog." src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/001-1_6o4AQYSXu5D0FUEDuKN12g.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;An example of embedding a live Python console in a Jekyll blog.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This example relies on the publicly available &lt;a href="https://github.com/jupyterlite/demo"&gt;demo website&lt;/a&gt; deployed to GitHub Pages. However we recommend setting up your own JupyterLite deployment, so you can have full control and use custom configuration and extensions (see the &lt;em&gt;Deploying your JupyterLite website&lt;/em&gt; section below).&lt;/p&gt;
&lt;h2 id="powering-the-numpy-documentation"&gt;Powering the NumPy documentation 🐍&lt;/h2&gt;
&lt;p&gt;The NumPy project had already been using an interactive console on the &lt;a href="https://numpy.org"&gt;numpy.org&lt;/a&gt; documentation website. The previous console was powered by &lt;a href="https://github.com/executablebooks/thebe"&gt;Thebe&lt;/a&gt; and &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt;. While this gave great flexibility and a way for users to try NumPy without installing anything on their machine, it required starting a new Jupyter Server on Binder for each user, and then waiting for a kernel to start before being able to type some code.&lt;/p&gt;
&lt;p&gt;This setup worked for a while but started to become more difficult to maintain and operate.&lt;/p&gt;
&lt;p&gt;With the JupyterLite-powered Python REPL, &lt;a href="https://numpy.org"&gt;numpy.org&lt;/a&gt; is now able to provide an interactive code console and let anyone try NumPy in their browsers. This considerably reduces the number of resources needed and allows for a smoother and snappier user experience.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLite REPL on numpy.org" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/002-1_aBGC8_llGDnbWifezqJBHQ.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLite REPL on numpy.org&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The REPL is currently based on the JupyterLab Code Console, which gives a familiar “look and feel” to Jupyter users. Other user interfaces such as a &lt;a href="https://github.com/jupyterlite/jupyterlite/issues/148"&gt;Single Executable Cell&lt;/a&gt; are also being considered for the next version of the REPL.&lt;/p&gt;
&lt;h2 id="try-jupyter"&gt;Try Jupyter 🟠&lt;/h2&gt;
&lt;p&gt;Another recent adopter of the JupyterLite stack is the official Jupyter website.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://try.jupyter.org"&gt;try.jupyter.org&lt;/a&gt; has been using the public-facing &lt;a href="https://mybinder.org"&gt;mybinder.org&lt;/a&gt; deployment to let users try the different Jupyter subprojects, such as &lt;a href="https://jupyter.org/blog/posts/2019/and-voila/"&gt;Voilà&lt;/a&gt; and the &lt;a href="https://jupyter.org/blog/posts/2020/xeus-is-now-a-jupyter-subproject/"&gt;Xeus-based&lt;/a&gt; kernels.&lt;/p&gt;
&lt;p&gt;This setup has been working nicely for many years. However, the Binder project recently faced &lt;a href="https://github.com/jupyterhub/mybinder.org-deploy/issues/2138"&gt;funding issues&lt;/a&gt;, which drastically reduced the overall capacity of the Binder federation. This means fewer resources are available to users for their projects, and this also impacted the Try Jupyter website.&lt;/p&gt;
&lt;p&gt;To mitigate this, we decided to create a custom JupyterLite website and use it for some of the demos on Try Jupyter. Users can then continue to try some of the Jupyter interfaces in their browsers without installing anything on their machines. As a result, the JupyterLab and Jupyter Notebook demos now point to the new JupyterLite deployment.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Launching JupyterLite from try.jupyter.org" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/003-1_UZ42uWfkmSasuyGWFRI2ZQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Launching JupyterLite from try.jupyter.org&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The “Try Jupyter with JupyterLite” deployment also includes the &lt;a href="https://github.com/jupyterlab-contrib/jupyterlab-tour"&gt;jupyterlab-tour&lt;/a&gt; extension, offering a user-friendly tour of the Jupyter interface to newcomers.&lt;/p&gt;
&lt;h2 id="deploying-your-jupyterlite-website"&gt;Deploying your JupyterLite website 💡&lt;/h2&gt;
&lt;p&gt;Contrary to a regular Jupyter deployment, JupyterLite can be served as a simple static website without running a Python server. This makes it &lt;strong&gt;simpler to deploy, and cheaper to operate&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Below are some examples for deploying your own JupyterLite and Python REPL.&lt;/p&gt;
&lt;h3 id="deploy-to-github-pages"&gt;Deploy to GitHub Pages&lt;/h3&gt;
&lt;p&gt;GitHub Pages is one of the simplest ways to host a JupyterLite website.&lt;/p&gt;
&lt;p&gt;This is what the demo repository available at &lt;a href="https://github.com/jupyterlite/demo"&gt;https://github.com/jupyterlite/demo&lt;/a&gt; does by default. It lets you bootstrap your JupyterLite website with a few clicks, and deploy it to GitHub Pages within a couple of minutes.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Creating a JupyterLite website with just a couple of clicks" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/004-1_fK9jSMoHgqBpnKN5aLXlIg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Creating a JupyterLite website with just a couple of clicks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;After a few minutes, your website will be ready and you can then embed your live Python console with the following snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://yourhandle.github.io/my-custom-deployment/repl/index.html?kernel=python&amp;amp;toolbar=1&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;500px&amp;quot;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="The JupyterLite REPL running on GitHub Pages" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/005-1_KkyYclq5t2YyyuUhFQfbEw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLite REPL running on GitHub Pages&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="deploy-to-vercel-or-netlify"&gt;Deploy to Vercel or Netlify&lt;/h3&gt;
&lt;p&gt;Hosted platforms like Vercel and Netlify are good options to deploy a static JupyterLite website.&lt;/p&gt;
&lt;p&gt;The REPLite project is an example deployed to Vercel, based on the following repository with some custom configuration: &lt;a href="https://github.com/jtpio/replite"&gt;https://github.com/jtpio/replite&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Python REPL can be embedded with an IFrame:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://replite.vercel.app/repl?kernel=python&amp;amp;toolbar=1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we use the &lt;code&gt;?kernel=python&lt;/code&gt; URL parameter to automatically choose the Python kernel on startup.&lt;/p&gt;
&lt;h3 id="deploying-to-readthedocs-using-the-sphinx-extension"&gt;Deploying to ReadTheDocs using the Sphinx extension&lt;/h3&gt;
&lt;p&gt;Going the extra mile, &lt;a href="https://github.com/jupyterlite/jupyterlite-sphinx"&gt;jupyterlite-sphinx&lt;/a&gt; brings the power of JupyterLite to your Sphinx documentation. It automatically creates a JupyterLite deployment in your documentation website and provides some utilities for using that deployment easily.&lt;/p&gt;
&lt;p&gt;If you are developing software, it’s a very convenient tool to let your users test your library directly on the documentation page!&lt;/p&gt;
&lt;p&gt;This is also really useful for Jupyter users who want to easily share their work on &lt;a href="http://readthedocs.org"&gt;readthedocs.org&lt;/a&gt;, GitHub Pages, or any other host that supports Sphinx documentation.&lt;/p&gt;
&lt;h4 id="installation"&gt;Installation&lt;/h4&gt;
&lt;p&gt;You can install &lt;code&gt;jupyterlite-sphinx&lt;/code&gt; with pip:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install jupyterlite-sphinx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then add the extension to your &lt;code&gt;conf.py&lt;/code&gt; file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;extensions = [
    &amp;#39;jupyterlite_sphinx&amp;#39;,
    # And other sphinx extensions
    # ...
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that’s it! &lt;code&gt;jupyterlite-sphinx&lt;/code&gt; will automatically deploy a JupyterLite website when building your docs with Sphinx.&lt;/p&gt;
&lt;h4 id="usage"&gt;Usage&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;jupyterlite-sphinx&lt;/code&gt; provides multiple Sphinx directives for embedding Python consoles and custom Notebooks in your documentation:&lt;/p&gt;
&lt;p&gt;To embed a Python REPL similar to the &lt;a href="http://NumPy.org"&gt;NumPy.org&lt;/a&gt; one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;replite&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;
   &lt;span class="nc"&gt;:kernel:&lt;/span&gt; python
   &lt;span class="nc"&gt;:theme:&lt;/span&gt; JupyterLab Light
   &lt;span class="nc"&gt;:width:&lt;/span&gt; 100%
   &lt;span class="nc"&gt;:height:&lt;/span&gt; 600px

    print(&amp;#39;Hello from a JupyterLite console!&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;img alt="Embedding the JupyterLite REPL" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/006-0_DMYBurEcdHmylCDu.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Embedding the JupyterLite REPL&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;To embed a full Notebook:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;retrolite&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; my_notebook.ipynb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;figure&gt;
&lt;a href="https://ipycanvas.readthedocs.io/en/master"&gt;&lt;img alt="An interactive Jupyter Notebook on the ipycanvas documentation" src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/007-1_CCLLn1s1p9GEFwHB6WAH-w.jpg" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;An interactive Jupyter Notebook on the &lt;a href="https://ipycanvas.readthedocs.io/en/master"&gt;ipycanvas documentation&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Finally, you might also want to embed the full JupyterLite UI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;jupyterlite&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that the notebooks are saved in the browser local storage, so any work done on those Notebooks can be retrieved later when coming back to the web page with the same browser.&lt;/p&gt;
&lt;h4 id="documentation"&gt;Documentation&lt;/h4&gt;
&lt;p&gt;You can find the &lt;code&gt;jupyterlite-sphinx&lt;/code&gt; documentation with live examples following this link:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jupyterlite-sphinx.readthedocs.io"&gt;jupyterlite-sphinx — JupyterLite sphinx extension documentation&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="example"&gt;Example&lt;/h4&gt;
&lt;p&gt;You can find an example of &lt;code&gt;jupyterlite-sphinx&lt;/code&gt; being used on &lt;a href="https://readthedocs.org/"&gt;ReadTheDocs&lt;/a&gt; here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ipycanvas.readthedocs.io/en/master"&gt;ipycanvas: Interactive Canvas in Jupyter — ipycanvas documentation&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="more-examples"&gt;More examples&lt;/h3&gt;
&lt;p&gt;JupyterLite can be deployed on more platforms than just the ones mentioned above. Pretty much anything that can serve static files should work!&lt;/p&gt;
&lt;p&gt;Feel free to check out the documentation to learn more about deploying your JupyterLite website on other platforms: &lt;a href="https://jupyterlite.readthedocs.io/en/latest/deploying.html#hosted"&gt;https://jupyterlite.readthedocs.io/en/latest/deploying.html#hosted&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="jupyter-everywhere"&gt;Jupyter Everywhere 🌐&lt;/h2&gt;
&lt;p&gt;With JupyterLite gaining rapid adoption on widely visited websites such as &lt;a href="https://numpy.org"&gt;numpy.org&lt;/a&gt; and &lt;a href="https://try.jupyter.org"&gt;try.jupyter.org&lt;/a&gt;, we envision Jupyter being adopted on more websites and documentation over the next months.&lt;/p&gt;
&lt;p&gt;We hope to bring interactive computing with Jupyter to even more people than before and make it more accessible by lowering the barrier of entry.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/008-0_TK59W6sOJHNg-Sgi.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Because JupyterLite can easily be extended with JupyterLab extensions, we also expect more Jupyter-based deployments and applications to flourish, making good reuse of the existing components that constitute the vibrant Jupyter ecosystem 🌸&lt;/p&gt;
&lt;p&gt;Jupyter is language agnostic and more kernels are now available in JupyterLite, for example for Lua and SQLite based on the &lt;a href="https://jupyter.org/blog/posts/2021/xeus-lite/"&gt;Xeus framework&lt;/a&gt;. Soon Jupyter will also power the documentation and websites of other languages, not just Python.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/009-0_bIbm1NNbif5Dn1H8.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt; and a Jupyter Distinguished Contributor. Martin works on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt;, &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; in Python and TypeScript.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/010-1_rBRr_6uBceP-shArkLcXhQ.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/jtpio"&gt;Jeremy Tuloup&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; and a Jupyter Distinguished Contributor. Maintainer and contributor of JupyterLab, Jupyter Notebook, JupyterLite, Voilà, and projects within the Jupyter ecosystem.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2022/jupyter-everywhere/images/011-1_Ab9PIO4Zs-6MOYhzF4GXPA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
</content><category term="JupyterLite"/></entry><entry><title>Abracadabra! Bringing the magics to xeus-python</title><link href="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/" rel="alternate"/><published>2021-02-18T13:30:00+00:00</published><updated>2021-02-18T14:06:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2021-02-18:/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/</id><summary type="html">&lt;p&gt;Last year, we set ourselves to implement a visual debugger for JupyterLab. This endeavor required major developments in the JupyterLab front-end, in core-Jupyter protocols, and on the kernel side (the part of the Jupyter infrastructure responsible for executing the code).&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last year, we set ourselves to implement a &lt;strong&gt;visual debugger for JupyterLab&lt;/strong&gt;. This endeavor required major developments in the JupyterLab front-end, in core-Jupyter protocols, and on the kernel side (the part of the Jupyter infrastructure responsible for executing the code).&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/001-0_B0kK-zNJr0Suisyv.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For kernel-side development, we decided to start with the &lt;a href="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/"&gt;&lt;strong&gt;xeus-python&lt;/strong&gt; kernel&lt;/a&gt;, a lightweight implementation of a Jupyter kernel for the Python programming language. Based on &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;&lt;strong&gt;xeus&lt;/strong&gt;&lt;/a&gt;, xeus-python has a flexible concurrency model that was required to &lt;em&gt;e.g.&lt;/em&gt; add breakpoints while executing code.&lt;/p&gt;
&lt;p&gt;Unfortunately, xeus-python did not provide all ipykernel features (magics, Matplotlib support, &lt;em&gt;etc.&lt;/em&gt;). Furthermore, many notebooks depend on IPython, as they import it explicitely or make use of the IPython configuration system.&lt;/p&gt;
&lt;p&gt;Today, we are proud to announce that xeus-python supports 100% of the IPython magics! This was achieved by leveraging the core IPython package. This is getting us closer to feature parity with ipykernel.&lt;/p&gt;
&lt;h2 id="magics"&gt;Magics&lt;/h2&gt;
&lt;p&gt;xeus-python now supports all magics that IPython provides and even user-defined magics!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Support for builtin IPython magics and user-defined magics" src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/002-1_PTiGVyDsazc_ziz6Bk4EnA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Support for builtin IPython magics and user-defined magics&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="matplotlib"&gt;Matplotlib&lt;/h2&gt;
&lt;p&gt;Most Matplotlib back-ends are now supported by xeus-python, allowing you to show static plots with the inline back-end or interactive plots with &lt;a href="https://github.com/matplotlib/ipympl"&gt;ipympl&lt;/a&gt; in your Notebook:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Matplotlib inline back-end and ipympl interactive back-end" src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/003-1_cmnPUKlhHHwUf8PZhNQx2g.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Matplotlib inline back-end and ipympl interactive back-end&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="extending"&gt;Extending&lt;/h2&gt;
&lt;p&gt;IPython has a rich configuration system that you can tweak in order to get an enhanced Notebook experience. Xeus-python now supports any configuration you setup for IPython:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Automatically import NumPy in the IPython settings" src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/004-1_bB5hiXIbVAlV3kX9KJfLfg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Automatically import NumPy in the IPython settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="visual-debugging"&gt;Visual Debugging&lt;/h2&gt;
&lt;p&gt;The latest JupyterLab version introduced a visual debugger in its interface. xeus-python was the first Jupyter kernel to add support for it!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Stepping into Python code in JupyterLab with the visual debugger" src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/005-1_efZAtaJQqeirAZoEqbxvdw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Stepping into Python code in JupyterLab with the visual debugger&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;xeus-python is not the only Jupyter kernel that supports debugging anymore: &lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; is a xeus-based Jupyter kernel for the &lt;a href="https://robotframework.org/"&gt;RobotFramework&lt;/a&gt; language that supports the JupyterLab visual debugger.&lt;/p&gt;
&lt;h2 id="try-it-online"&gt;Try it online&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can try it out without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xeus-python/stable?urlpath=/lab/tree/notebooks/xeus-python.ipynb"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/006-0_2sBOFFsk_322apCe.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;You can install the latest xeus-python version using mamba or conda:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install xeus-python -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install xeus-python -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also compile it yourself, instructions can be found in the repository:&lt;br&gt;
&lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;https://github.com/jupyter-xeus/xeus-python&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;My work on &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; at &lt;a href="https://twitter.com/QuantStack"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt; was funded by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/abracadabra-bringing-the-magics-to-xeus-python/images/007-0_5XdymjYwzZe-hvy8.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt;, I am a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt;. Before joining QuantStack, I studied at the aerospace engineering school &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt; in Toulouse, France. I also worked at Logilab in Paris, France and Enthought in Cambridge, UK. As an open-source developer at QuantStack, I work on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; in Python and JavaScript/TypeScript.&lt;/p&gt;
</content><category term="IPython"/><category term="kernels"/><category term="xeus"/></entry><entry><title>Robotic Process Automation with JupyterLab</title><link href="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/" rel="alternate"/><published>2021-01-18T10:36:00+00:00</published><updated>2021-01-18T10:36:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2021-01-18:/blog/posts/2021/robotic-process-automation-with-jupyterlab/</id><summary type="html">&lt;p&gt;Introducing a new Jupyter kernel for Robot Framework&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Robotic Process Automation (RPA) differs from classical automation tools in that the actions to automate can be developed by observing a user perform a task in a graphical user interface, across multiple applications.&lt;/p&gt;
&lt;p&gt;It is a means to lower the entry barrier of process automation and enable the use of tools that don’t provide a programmatic interface.&lt;/p&gt;
&lt;p&gt;Most typically, RPA developers will use a mixed approach between textual programming and performing actions manually. The resulting programs are typically called software &lt;em&gt;robots&lt;/em&gt;. Therefore, interactive computing tools like Jupyter are a natural environment for RPA, as the interactive nature of Jupyter allows for quick iterations and trial-and-errors when developing such robots.&lt;/p&gt;
&lt;p&gt;While many RPA tools are commercial software, &lt;a href="https://robotframework.org/"&gt;Robot Framework&lt;/a&gt; and the tooling developed by &lt;a href="https://robocorp.com/"&gt;Robocorp&lt;/a&gt; provide an open-source RPA programming language, with a high-level syntax, extensible with Python plugins. It has a rich ecosystem of libraries and tools that are developed as separate projects.&lt;/p&gt;
&lt;h2 id="robot-framework-and-project-jupyter"&gt;Robot Framework and Project Jupyter&lt;/h2&gt;
&lt;p&gt;Today, we are happy to announce the first release of &lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;&lt;strong&gt;xeus-robot&lt;/strong&gt;&lt;/a&gt;, a Jupyter kernel for &lt;a href="https://robotframework.org/"&gt;Robot Framework&lt;/a&gt; based on &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;xeus&lt;/a&gt;, supporting the new JupyterLab 3.0 visual debugger, auto-completion, and much more!&lt;/p&gt;
&lt;p&gt;But before we dive into xeus-robot, we should recognize the earlier work by &lt;a href="https://github.com/bollwyvl"&gt;Nick Bollweg&lt;/a&gt; and &lt;a href="https://github.com/datakurre"&gt;Asko Soukka&lt;/a&gt;, who developed two Jupyter kernels for Robot Framework, &lt;a href="https://github.com/gtri/irobotframework"&gt;irobotframework&lt;/a&gt;, and &lt;a href="https://github.com/robots-from-jupyter/robotkernel"&gt;robotkernel&lt;/a&gt;, and gave an &lt;a href="https://www.youtube.com/watch?v=rbYF_RmiAR8"&gt;amazing talk&lt;/a&gt; together at &lt;a href="https://robocon.io/"&gt;RoboCon&lt;/a&gt; in 2019!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The motivation for us to reboot this effort with a kernel based on xeus was to enable the &lt;strong&gt;JupyterLab Visual Debugger&lt;/strong&gt; for this kernel. This requires a different concurrency model than that of ipykernel, which underlies both irobotframework and robotkernel. In the end, we were able to provide the same features and more, including e.g. code completion in Python cells, debugging etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="diving-into-xeus-robot"&gt;Diving into Xeus-robot&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/001-1_3HNfLnwDpXNZ6n6HPD2lXQ.webp" alt="Xeus robot logo" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; is a reboot of the already existing robotkernel, based on xeus.&lt;/p&gt;
&lt;p&gt;Like most language kernels, &lt;a href="https://github.com/jupyter-xeus/xeus-robot"&gt;xeus-robot&lt;/a&gt; supports code completion, inspection, error handling, etc. It also allows using Python cells to define custom robot keywords in Python, those Python cells support code completion as well.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Code completion in Robot framework" src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/002-1_OPqkYEI78eT1dj5P6WEeXg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Code Completion in Robot Framework&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;By using the libraries robotframework-seleniumlibrary and robotframework-seleniumscreenshots, you can even complete the selection of elements on the page you are currently testing!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="RPA code completion" src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/003-1_Z-aWN6goZH_1YcabAYj2fQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Code completion with an action of the user in the UI.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;code&gt;%%python&lt;/code&gt; cell magic makes it possible to extend Robotframework with Python modules in the notebook.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Robot Framework extenions in Python" src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/004-1_TSiSmKHJOGE0PQ_c7alv1w.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Extending RobotFramework with Python, and code completion in Python cells&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Widget-based UIs are provided to test Robotframework “keywords”.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Robot Framework and Jupyter widgets" src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/005-1_nyXQAQivNvV23xvS_1KCYQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Testing Robot Framework “keywords” with Jupyter widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Last but not least, xeus-robot comes with full support for the JupyterLab Visual Debugger! After the xeus-python kernel, it is the second Jupyter kernel to support the Jupyter Debugger Protocol! We hope that many more will come.&lt;/p&gt;
&lt;p&gt;You can set breakpoints, step in defined keywords (the equivalent of functions), inspect variables, and see the callstack, as shown below.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="JupyterLab Visual Debugger" src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/006-1_EFxI8mzCwYwnK9DB_xGxTQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The JupyterLab Visual Debugger in action with Robot Framework&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="installing-xeus-robot"&gt;Installing xeus-robot&lt;/h2&gt;
&lt;p&gt;Xeus-robot is available for all platforms on conda-forge, and can be installed with conda or mamba.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install xeus-robot -c conda-forge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;jupyterlab-robotmode&lt;/code&gt; package, which provides JupyterLab syntax highlighting for Robot Framework will also be installed as a dependency.&lt;/p&gt;
&lt;p&gt;For your conda installation, we recommend starting from &lt;strong&gt;mambaforge&lt;/strong&gt; or &lt;strong&gt;miniforge&lt;/strong&gt; which are available for download &lt;a href="https://github.com/conda-forge/miniforge"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;, and default to the conda-forge channel (making the &lt;code&gt;-c conda-forge&lt;/code&gt; argument unnecessary).&lt;/p&gt;
&lt;h2 id="try-it-online"&gt;Try it online&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can try it out without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-xeus/xeus-robot/stable?urlpath=/lab/tree/notebooks/xrobot.ipynb"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/007-0_TQpdhVZSAnE-XOrm.jpg" alt="&amp;quot;Launch binder&amp;quot; badge" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://robocorp.com/"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/008-1_E9XGge6uWrbmvndUoZ1Qug.webp" alt="Robocorp logo" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The work on xeus-robot by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; was funded by &lt;a href="https://robocorp.com/"&gt;Robocorp&lt;/a&gt;, and is part of their initiative to create an open-source RPA ecosystem. Beyond the xeus-robot kernel, Robocorp also funds the integration of Robot Framework with &lt;a href="https://marketplace.visualstudio.com/items?itemName=robocorp.robocorp-code"&gt;Visual Studio Code&lt;/a&gt;, &lt;a href="https://rpaframework.org/"&gt;RPA Framework&lt;/a&gt;, and other development to push the Robot Framework project forward.&lt;/p&gt;
&lt;p&gt;The implementation of the debugger in xeus-robot relies on &lt;a href="https://github.com/robocorp/robotframework-lsp"&gt;robotframework-lsp&lt;/a&gt; by &lt;a href="https://twitter.com/fabiofz"&gt;Fabio Zadrozny&lt;/a&gt; and we want to thank him for his help in integrating it in xeus-robot.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/009-1_zwPmx9pH4pkXOxowHQOsuQ.jpeg" alt="Martin Renou" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; is a scientific software developer at QuantStack. He is the creator of the xeus-python and xeus-robot kernels.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2021/robotic-process-automation-with-jupyterlab/images/010-1_YQZupQRMB6JJfhM_byi2KA.jpeg" alt="Johan Mabille" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Johan Mabille&lt;/strong&gt; is a scientific software developer at QuantStack. He is a co-author of the xeus project, and developed the debugger extensions to xeus-python and xeus-robot. He also co-authored the front-end for the JupyterLab visual debugger.&lt;/p&gt;
</content><category term="JupyterLab"/></entry><entry><title>ipygany: Jupyter into the third dimension</title><link href="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/" rel="alternate"/><published>2020-10-14T09:51:00+00:00</published><updated>2020-11-01T12:42:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2020-10-14:/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/</id><summary type="html">&lt;p&gt;Scientific visualization in the Jupyter notebook&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Scientific visualization in the Jupyter notebook&lt;/em&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/001-1_IB4Bf4aEC5RXJJ1gY1zGFw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;From Paraview to Mayavi, there are multiple solutions for data analysis on 3D meshes on the desktop. Most of these tools provide high-level APIs that can be driven with a scripting language like Python. For example, one could control Paraview from a Jupyter Notebook. But this is not ideal as it relies on a desktop application for the rendering, which prevents using tools like &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Nowadays, most scientists run their computation on the cloud, and they need tools for interacting and analyzing with their data.&lt;/p&gt;
&lt;p&gt;There are already some solutions that are more integrated into Jupyter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt; is a WebGL-based 3D plotting library for Jupyter. It has many features including multi-volume rendering.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/K3D-tools/K3D-jupyter"&gt;K3D-jupyter&lt;/a&gt; helps you create 3D plots backed by WebGL with high-level API (surfaces, isosurfaces, voxels, mesh, cloud points, vtk objects, volume renderer, colormaps, etc).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets"&gt;itkwidgets&lt;/a&gt; is a tool for visualizing images, point sets, and meshes in 2D and 3D in Jupyter. It works by doing the rendering on the back-end and by streaming the frames to the front-end.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Kitware/ipyvtk-simple"&gt;ipyvtk-simple&lt;/a&gt; is a Jupyter library for interfacing with any Python vtkRenderWindow. It relies on &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt; for streaming the frames to the front-end.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We needed a Paraview-like experience for Jupyter. We could provide this experience by relying on the vtk library in Python, but this means that every time you want to apply a new filter like warp-by-scalar, the Python back-end needs to send the filtered mesh to the front-end for display. This is far from ideal, as it might be hundreds of megabytes to download for every roundtrip to the back-end.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;itkwidgets&lt;/code&gt; and &lt;code&gt;ipyvtk-simple&lt;/code&gt; fix this issue by not sending the mesh to the page, instead, the rendering is done on the back-end and streamed to the user. This solution is, in a way, similar to using Paraview using a vnc solution. It works fine as long as you have a fast and low latency connection to the Jupyter server, and this solution scales properly with the mesh size, as the amount of data sent to the user is the same whether you analyze a fine or a coarse mesh.&lt;/p&gt;
&lt;p&gt;Solutions like ipyvolume and K3D-jupyter can be backed by the Python vtk library (or by &lt;a href="https://github.com/pyvista/pyvista"&gt;PyVista&lt;/a&gt;), but again, this means doing the mesh filtering in Python and sending the filtered meshes to the page for every change.&lt;/p&gt;
&lt;p&gt;Today we are proud to announce &lt;a href="https://github.com/QuantStack/ipygany"&gt;&lt;strong&gt;ipygany&lt;/strong&gt;&lt;/a&gt;! ipygany is a &lt;strong&gt;Jupyter widget&lt;/strong&gt; that aims at bringing a &lt;strong&gt;Paraview-like experience to the webpage&lt;/strong&gt;. With ipygany, you only send your mesh data to the front-end once, and effects such as mesh warping, contour computation, threshold filtering are directly done in the front-end and most-typically with the GPU.&lt;/p&gt;
&lt;h2 id="introducing-ipygany"&gt;Introducing ipygany&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/ipygany"&gt;ipygany&lt;/a&gt; is a new interactive widgets library that allows you to visualize and analyze volumetric data in the Jupyter Notebook.&lt;/p&gt;
&lt;p&gt;Whether your data comes from a VTK file or NumPy arrays, ipygany allows you to dynamically load your data, display them in the Notebook, and apply different kinds of visual effects on it.&lt;/p&gt;
&lt;p&gt;ipygany provides a set of effects inspired by Paraview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IsoColor&lt;/strong&gt;: apply color-mapping to your mesh.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Warp&lt;/strong&gt;: deform your mesh given a 3-D input data (e.g. displacement data on a beam)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WarpByScalar&lt;/strong&gt;: deform your mesh given a 1-D input data (e.g. terrain elevation)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Threshold&lt;/strong&gt;: only visualize mesh parts inside a range of data (e.g. &lt;em&gt;222 K≤ temperature ≤ 240 K&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IsoSurface:&lt;/strong&gt; only visualize the surface where the mesh respects a data value (e.g. &lt;em&gt;pressure == 3 bar&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Glyph effects like &lt;strong&gt;PointCloud&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Water&lt;/strong&gt; visualization&lt;/li&gt;
&lt;li&gt;And there’s more to come!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Most of those effects are computed on the &lt;strong&gt;GPU&lt;/strong&gt; &lt;strong&gt;only&lt;/strong&gt;! Which makes them &lt;strong&gt;really fast&lt;/strong&gt;. For example, changing the deformation factor of the Warp effect only sends one floating-point number to the GPU, and the GPU will know how to re-render the mesh (using shaders) according to the new factor value, this update is virtually &lt;strong&gt;instantaneous&lt;/strong&gt;. Changing the warp factor value is technically as fast as moving the camera position, it only requires rendering a new frame.&lt;/p&gt;
&lt;p&gt;We strive to use efficient algorithms for better performances, especially for computation that cannot be done with the GPU.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="WarpByScalar: completely computed on the GPU" src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/002-1_44MjnyyY7En1fSyg3ZjUbg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;WarpByScalar: completely computed on the GPU&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Effects can be easily combined for highlighting important parts in your mesh. For example, you can easily cut your mesh using the Threshold effect then apply a Warp effect for visualizing a deformation on the result.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Combining a Threshold with a Warp" src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/003-1_Y0vnsdwZ80L651FIcu9SUA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Combining a Threshold with a Warp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;All those effects are interactive widgets, they are stateful objects that you can dynamically update from Python or using widgets like sliders, text inputs, etc.&lt;/p&gt;
&lt;p&gt;Your mesh is also an interactive widget: &lt;strong&gt;you can dynamically update your data&lt;/strong&gt;, which is very useful when your data changes through time.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Visualizing an animation from two viewpoints" src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/004-1_hAGP5bJQ-2xN7w0dLprXig.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Visualizing an animation from two viewpoints&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you work with fluid dynamics, we even provide refractive/reflective effects and water caustics computation for nice looking visualization:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="If you do Water simulation, ipygany also allows you to render you water with reflective/refractive effects and it even computes light caustics!" src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/005-1_au2ruI66bs1gx3AY3qtvlQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;If you do Water simulation, ipygany also allows you to render you water with reflective/refractive effects and it even computes light caustics!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="installation"&gt;Installation&lt;/h2&gt;
&lt;p&gt;You can install ipygany with conda or &lt;a href="https://github.com/mamba-org/mamba"&gt;mamba&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mamba install -c conda-forge ipygany
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install -c conda-forge ipygany
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or you can install it with pip:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install ipygany
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you use JupyterLab you’ll need to install the labextension (not needed with the coming JupyterLab v3):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;jupyter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;labextension&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;@jupyter&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;widgets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jupyterlab&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ipygany&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="documentation"&gt;Documentation&lt;/h2&gt;
&lt;p&gt;You can find the documentation following this link:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://ipygany.readthedocs.io/"&gt;https://ipygany.readthedocs.io&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="try-it-online"&gt;Try it online&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;a href="https://mybinder.org/"&gt;MyBinder&lt;/a&gt;, you can try it out without the need of installing anything on your computer. Just follow this link:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/QuantStack/ipygany/stable?filepath=examples"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/006-1_T9WU53MjGAIX6i9XYsnL1w.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="acknowledgement"&gt;Acknowledgement&lt;/h2&gt;
&lt;p&gt;This work is led at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; and founded by &lt;a href="https://www.erdc.usace.army.mil/About/"&gt;ERDC&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2020/ipygany-jupyter-into-the-third-dimension/images/007-0_kREnDs33Zid5X4QE.jpg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt;, I am a Scientific Software Engineer at &lt;a href="https://quantstack.net/"&gt;&lt;strong&gt;QuantStack&lt;/strong&gt;&lt;/a&gt;. Before joining QuantStack, I studied at the aerospace engineering school &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt; in Toulouse, France. I also worked at Logilab in Paris, France and Enthought in Cambridge, UK. As an open-source developer at QuantStack, I work on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/bqplot/bqplot"&gt;bqplot&lt;/a&gt; in Python and Javascript/TypeScript.&lt;/p&gt;
</content><category term="visualization"/></entry><entry><title>SlicerJupyter: a 3D Slicer kernel for interactive publications</title><link href="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/" rel="alternate"/><published>2020-07-08T16:29:00+00:00</published><updated>2020-07-08T16:58:00+00:00</updated><author><name>Jean-Christophe Fillion-Robin</name></author><id>tag:jupyter.org,2020-07-08:/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/</id><summary type="html">&lt;p&gt;Use Jupyter and 3D Slicer kernel to implement biomedical data processing workflows in a notebook.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Use Jupyter and 3D Slicer kernel to implement biomedical data processing workflows in a notebook.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The Jupyter ecosystem is a powerful platform for exploratory computational science, and now it can connect with some of the deep and rich domain-specific desktop applications that have decades of feature development already invested in them. With the integration of &lt;a href="https://www.slicer.org/"&gt;3D Slicer&lt;/a&gt; with Jupyter through the &lt;a href="https://github.com/jupyter-xeus/xeus-python"&gt;xeus-python&lt;/a&gt;’s interpreter, we demonstrate how a &lt;a href="https://www.qt.io/"&gt;Qt-based&lt;/a&gt; graphical desktop application with 3D visualization provided by &lt;a href="https://vtk.org/"&gt;Visualization Toolkit (VTK)&lt;/a&gt;, image processing provided by the &lt;a href="https://itk.org/"&gt;Insight Toolkit (ITK)&lt;/a&gt;, can be used through a Jupyter notebook. This approach is available on the &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; GitHub repository and could be extended to other applications that embed Python, such as Blender, FreeCAD, or ParaView.&lt;/p&gt;
&lt;p&gt;This xeus-python integration is beneficial both for the Jupyter ecosystem and desktop applications. Features that have been developed for decades for desktop applications become readily available for Jupyter users without learning a new working environment or redeveloping features. For a desktop application, the Jupyter notebook can serve as a way to create reproducible data processing workflows, scientific publications, and maintainable tutorials without requiring local software installation. From Jupyter, you can now quickly create simple medical imaging applications with extremely rich interactivity from 3D Slicer. Read below for a discussion of the features available and the history of the project.&lt;/p&gt;
&lt;h2 id="powerful-medical-imaging-capabilities-available-through-jupyter"&gt;Powerful Medical Imaging Capabilities Available Through Jupyter&lt;/h2&gt;
&lt;p&gt;3D Slicer (or Slicer for short) is a C++ desktop application that uses Qt, ITK, and VTK libraries for visualization and medical image analysis. Slicer’s embedded Python interpreter makes all its features accessible with the Python programming language. Slicer has a simple built-in console to run Python commands interactively and can run Python scripts from files, but these are not as convenient as cell-base interactive notebooks, which have become popular among data scientists and researchers in recent years.&lt;/p&gt;
&lt;p&gt;By integrating the xeus-python kernel, we can use a Slicer process as a Jupyter kernel. xeus-python leverages the &lt;a href="https://github.com/jupyter-xeus/xeus"&gt;xeus&lt;/a&gt; C++ implementation of the Jupyter kernel protocol. xeus-python is &lt;a href="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/"&gt;an alternative to ipykernel&lt;/a&gt;, which can be used with a vanilla CPython interpreter, interfacing to standard CPython Jupyter widgets like &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets"&gt;itkwidgets&lt;/a&gt;, but it can also be coupled with custom interpreters and GUI event loops, like the Slicer interpreter and its Qt event loop. This allows you to represent a complete scene in Medical Reality Markup Language, MRML, Slicer’s internal data structure. The kernel exposes the full medical imaging API and representation of your data in a meaningful way for Python developers, allowing access through standard Python ecosystem formats such as pandas dataframes and NumPy arrays in the Notebook.&lt;/p&gt;
&lt;h3 id="interactivity-levels"&gt;Interactivity Levels&lt;/h3&gt;
&lt;p&gt;You can also use Jupyter interactive widgets (sliders, buttons, etc.) to control Slicer, modify data, or adjust processing and visualization parameters. Interactivity can be implemented at different levels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Level 1&lt;/strong&gt;: Standard Jupyter widgets display application specific objects by automatic conversion of application-specific data objects to standard Python objects. For example, Slicer markup fiducial lists are displayed as a nicely formatted table and model nodes are rendered as 3D objects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 2&lt;/strong&gt;: Static image widgets display content that the desktop application renders. These widgets can be made interactive by modifying data and rendering parameters using additional standard widgets. This makes rich visualization capabilities — sophisticated rendering various data types, rendering of very large data sets, etc. directly available in Jupyter.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 3&lt;/strong&gt;: Dynamic viewer widgets display 2D and 3D views rendered by the desktop application. Mouse and keyboard events are forwarded to the desktop application that allows zooming/rotating views, and to utilize all 3D interactions implemented in the desktop such as placing annotations, making measurements, or segmenting images the same way as if it was done on the desktop appication’s screen. This is implemented in the Slicer Jupyter kernel using &lt;a href="https://ipycanvas.readthedocs.io/en/latest/"&gt;ipycanvas&lt;/a&gt; and &lt;a href="https://github.com/mwcraig/ipyevents"&gt;ipyevents&lt;/a&gt; packages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Level 4&lt;/strong&gt;: Full desktop graphical user interface integration. Users can see parts of the application window rendered in notebook cells, including standard desktop widgets (sliders, menus, etc.). It is implemented using noVNC and TigerVNC in Slicer Jupyter. This is particularly useful when the application runs on a remote server.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;iframe src="https://www.youtube-nocookie.com/embed/oZ3_cRXX2QM" title="Medical image processing in your web browser using Jupyter notebooks and 3D Slicer" width="560" height="315" style="aspect-ratio: 560 / 315" loading="lazy" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;
&lt;figcaption&gt;
&lt;p&gt;Video demonstrating how to run 3D Slicer using Binder&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These interactive tools allow developers to implement complete data processing workflows in a notebook, even if certain steps require manual user inputs such as segmenting 3D regions or setting seed points.&lt;/p&gt;
&lt;h3 id="try-it-online"&gt;Try it online!&lt;/h3&gt;
&lt;p&gt;Since Jupyter notebooks can be used from any web browser, it can essentially turn any desktop application to a web application. By setting up a remote Jupyter server, users do not have to install anything on their computers. We have set up a demonstration of this using Binder (&lt;a href="http://www.mybinder.org"&gt;www.mybinder.org&lt;/a&gt;) that anybody can try at &lt;a href="https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master"&gt;https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/Slicer/SlicerNotebooks/master"&gt;&lt;img alt="Click on the binder image to launch the demo" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/001-0_powLrWNrbtb0dRWs.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the binder image to launch the demo&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The docker image that installs and configures Slicer and all dependencies (ipycanvas, ipyevents, VNC, etc.) is available at &lt;a href="https://github.com/Slicer/SlicerDocker/tree/master/slicer-notebook"&gt;https://github.com/Slicer/SlicerDocker/tree/master/slicer-notebook&lt;/a&gt;. For deployment to non-technical users, applications can be deployed using Voilà (&lt;a href="https://voila.readthedocs.io/"&gt;https://voila.readthedocs.io/&lt;/a&gt;), which only shows relevant content and interactive widgets, so the notebook looks like a simple dynamic web page.&lt;/p&gt;
&lt;p&gt;The current implementation is already stable and offers a wide range of features, but there is still room for design and performance improvements. For example, we could not implement fully automatic conversion of application-specific data objects to displayable Python objects (due to complex implementation of display hooks); xeus-python debugger’s threading model needs to be improved to allow using it without locking the application’s main thread; and dynamic viewer widget’s performance (level 3 interaction) could be optimized to achieve higher refresh rates.&lt;/p&gt;
&lt;h2 id="history-of-slicer-and-this-integration"&gt;History of Slicer and this integration&lt;/h2&gt;
&lt;p&gt;Built over two decades with support from the NIH and a worldwide open source developer community, 3D Slicer is a unique, multi-platform desktop application for analysis, integration, and visualization of medical images that is heavily used by researchers globally for basic and applied research in a wide range of topics. The 3D Slicer Community includes physician-scientists with disease-specific knowledge of clinical challenges, computer scientists and physicists who develop novel algorithms, imaging informatics researchers, software engineers with the ability to understand clinical problems and create reliable tools, and application engineers with the multidisciplinary skills to deploy these tools in a range of cancer research settings. Slicer is maintained by Kitware, Inc., and the NAMIC consortium, and has an active open source software community. Slicer is used in hospitals and by researchers, with more than 10k academic citations and more than 150k downloads in the last year alone.&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://download.slicer.org"&gt;&lt;img alt="Click on the image to download 3D Slicer" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/002-1_ePhHKkjqV-AW0mvDkaeurw.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the image to download 3D Slicer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It can be used for image processing workflows on 2D, 3D, and 4D images. What makes Slicer so useful is its huge set of community contributed modules that extend its functionality, as well as its ability to read DICOM and a wide array of exotic file formats.&lt;/p&gt;
&lt;p&gt;Slicer has been scriptable in Python for well over a decade, but a robust &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; extension is born from significant development effort by the community. The idea for this integration dates back to SciPy in 2014, when Jean-Christophe Fillion-Robin of Kitware organized a sprint intended to integrate Slicer and an IPython notebook, motivated by the dream of creating interactive and fun tutorials for Slicer. Mike Sarahan and Jean-Christophe created this proof of concept &lt;a href="https://github.com/commontk/QEmbedIPython#qt-embed-ipython"&gt;https://github.com/commontk/QEmbedIPython#qt-embed-ipython&lt;/a&gt;, but it was far from usable. In 2015 Matt McCormick of Kitware, created the &lt;a href="https://github.com/Slicer/SlicerDocker"&gt;SlicerDocker&lt;/a&gt; repository to support headless builds and rendering in a Docker image. Then in June 2018, while attending the Slicer Project Week, Andras Lasso (Queen’s University) and Jean-Christophe learned about Xeus, a C++ implementation of the Jupyter kernel protocol developed by QuantStack that would help streamline the integration of Slicer with Jupyter. To support this effort, Andras and Jean-Christophe created the &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;Slicer/SlicerJupyter&lt;/a&gt; GitHub repository. They also contributed changes to Xeus to support this new integration paradigm where the event loop of the kernel is driven by a Qt-based Desktop application (see &lt;a href="https://github.com/jupyter-xeus/xeus/pull/63"&gt;here&lt;/a&gt;). Building on this foundation, Isaiah Norton, then working at Brigham and Women’s Hospital, contributed additional improvements like a better auto-completion using jedi (see &lt;a href="https://github.com/Slicer/SlicerJupyter/pull/12"&gt;https://github.com/Slicer/SlicerJupyter/pull/12&lt;/a&gt;) as well as integration with Binder. More recently, Jean-Christophe and Sylvain Corlay (QuantStack) met after the Slicer project week while attending SciPy in Austin. Following the creation of a new project called xeus-python (started by Martin Renou at QuantStack), we took the integration of Jupyter and Slicer to the next level by adding support for improved interactive use and MRML data node visualization directly in the notebook.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the authors&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Alphabetically ordered&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt; is the founder and CEO of QuantStack, and a core Jupyter developer. He co-authored xeus and xeus-python.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Sylvain Corlay" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/003-1_DKAhOe_Y4JdGYkgi9jHBSQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Sylvain Corlay&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Jean-Christophe Fillion-Robin&lt;/strong&gt; is an open-source enthusiast, original author of the SlicerJupyter extension and a principal engineer at Kitware Inc where he leads the development of “3D Slicer” based commercial applications. J-Christophe also maintains &lt;a href="https://scikit-build.org"&gt;scikit-build&lt;/a&gt;, an improved build system generator for CPython C/C++/Fortran/Cython extensions.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Jean-Christophe Fillion-Robin" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/004-1_slg9clPxU3DhL4W2pE2kCA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Jean-Christophe Fillion-Robin&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Mike Grauer&lt;/strong&gt; is a Technical Leader on the data and analytics team at Kitware. He is specialized in building scalable server-side processing frameworks that enable scientific workflows over web platforms.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Mike Grauer" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/005-1_SuBw-BD8efPla8tfd98RUg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Mike Grauer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Andras Lasso&lt;/strong&gt; is an original author of the SlicerJupyter extension, Senior Research Engineer and Associate Director of the Laboratory for Percutaneous Surgery at Queen’s University.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Andras Lasso" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/006-1_kINpFRIt94iHaxTA90zncQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Andras Lasso&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Matt McCormick&lt;/strong&gt; is an open source, medical imaging researcher working at Kitware Inc. Matt is an active, contributing member of scientific open source software efforts such as the Insight Toolkit (ITK) and scientific Python (SciPy) communities, and maintains the Jupyter 3D widget, &lt;a href="https://github.com/InsightSoftwareConsortium/itkwidgets"&gt;itkwidgets&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Matt McCormick" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/007-1_Pm17Os2v8Kf_GiZQw1G_ZQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Matt McCormick&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Isaiah Norton&lt;/strong&gt; is a Senior Software Developer at TileDB, Inc. with experience in digital pathology and image-guided surgical navigation.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Isaiah Norton" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/008-1_eR4Y9MX-2lcRsXEKodCJrQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Isaiah Norton&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Steve Pieper&lt;/strong&gt; is a Chief Architect and active developer of the 3D Slicer application for well over a decade. He is CEO of Isomics, Inc, where he uses a range of software technologies to perform medical imaging research with leading universities and companies.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Steve Pieper" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/009-1_aNwZz5TLENXuS2WQRb_N9w.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Steve Pieper&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; is a scientific software developer at QuantStack. He is the original author of xeus-python, the xeus-based Python kernel, and contributed to the new concurrency model used for the debugger.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Martin Renou" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/010-1_Cy9QfZytimqXQut2-bdcIA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Martin Renou&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;Mike Sarahan&lt;/strong&gt; is a software engineer at RStudio, PBC working on bringing language ecosystems together. He is passionate about making software work for data scientists in ways that are easy to maintain and improve.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Mike Sarahan" src="https://jupyter.org/blog/posts/2020/slicerjupyter-a-3d-slicer-kernel-for-interactive/images/011-1_YKNdPIBH39iFBIL9nD_kfg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Mike Sarahan&lt;/figcaption&gt;
&lt;/figure&gt;
</content><category term="kernels"/><category term="science"/><category term="visualization"/></entry><entry><title>ipycanvas: A Python Canvas for Jupyter</title><link href="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/" rel="alternate"/><published>2019-10-25T12:48:00+00:00</published><updated>2022-04-08T08:29:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2019-10-25:/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/</id><summary type="html">&lt;p&gt;As you may already know, the Jupyter Notebook and JupyterLab are Browser-based applications. Browsers are incredibly powerful, they allow you to swap rich and interactive graphical interfaces containing buttons, sliders, maps, 2D and 3D plots and even video games in your webpages!&lt;/p&gt;</summary><content type="html">&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/001-1_LHrtcPJMCWVMgsvNR6tR6w.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;As you may already know, the Jupyter Notebook and JupyterLab are Browser-based applications. &lt;strong&gt;Browsers are incredibly powerful&lt;/strong&gt;, they allow you to swap rich and interactive graphical interfaces containing buttons, sliders, maps, 2D and 3D plots and even video games in your webpages!&lt;/p&gt;
&lt;p&gt;All this power is readily made available to the Python ecosystem by &lt;strong&gt;Jupyter interactive widgets&lt;/strong&gt; libraries. Whether you want to create simple controls using &lt;a href="https://github.com/jupyter-widgets/ipywidgets/"&gt;ipywidgets&lt;/a&gt;, display interactive data on a 2D map with &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt;, plot 2D data using &lt;a href="https://github.com/bloomberg/bqplot/"&gt;bqplot&lt;/a&gt; or plot volumic data with &lt;a href="https://github.com/maartenbreddels/ipyvolume"&gt;ipyvolume&lt;/a&gt;, all of this is made possible thanks to the &lt;strong&gt;open-source&lt;/strong&gt; community.&lt;/p&gt;
&lt;p&gt;One powerful tool in the Browser is the &lt;strong&gt;HTML5 Canvas&lt;/strong&gt; element, it allows you to draw 2D or 3D graphics on the webpage. There are two available APIs for the Canvas, the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"&gt;Canvas API&lt;/a&gt; which focuses on 2D graphics, and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API"&gt;WebGL API&lt;/a&gt; which uses hardware acceleration for 3D graphics.&lt;/p&gt;
&lt;p&gt;After some discussions with my work colleague &lt;a href="https://twitter.com/wuoulf"&gt;Wolf Vollprecht&lt;/a&gt;, we came to the conclusion that it would be a great idea to directly expose the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"&gt;Canvas API&lt;/a&gt; to IPython, without making any modification to it. And that’s how we came up with &lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="ipycanvas-exposing-the-canvas-api-to-ipython"&gt;ipycanvas: Exposing the Canvas API to IPython&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/002-1_-Q6-aW2mJjMfsxmieaGomw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/martinRenou/ipycanvas"&gt;ipycanvas&lt;/a&gt; exposes the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"&gt;Canvas API&lt;/a&gt; to IPython, making it possible to &lt;strong&gt;draw anything you want on a Jupyter Notebook&lt;/strong&gt; directly in Python! Anything is possible, you can draw custom heatmaps from NumPy arrays, you can implement your own 2D video-game, or you can create yet another IPython plotting library!&lt;/p&gt;
&lt;p&gt;ipycanvas provides a low-level API that allows you to draw simple primitives like lines, polygons, arcs, text, images… Once you’re familiar with the API, you’re only limited by your own imagination!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Draw image from NumPy array" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/003-1_80VJXjNns82TZUcLURNplg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Draw image from NumPy array&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Implementation of the Game Of Life" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/004-1_jjBIO9JslYo7LfIyTpfjxQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Implementation of the Game Of Life&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Draw millions of particles" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/005-1_QeQxhuDRL1AwXokdsQ2fhQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Draw millions of particles&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Draw custom sprites" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/006-1_6SqrCHH4YsJUY4nrDTU7fw.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Draw custom sprites&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="A line plot drawn with ipycanvas, with a slider that changes it" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/007-1_PtctDM0B6OT604tRFV2WtA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A line plot drawn with ipycanvas, with a slider that changes it&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Make your own plotting library for Jupyter fully in Python!" src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/008-1_rCvw3tMgRVixKn_wUAHEAQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Make your own plotting library for Jupyter fully in Python!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Using &lt;a href="https://twitter.com/astronomatty"&gt;Matt Craig&lt;/a&gt;’s &lt;a href="https://github.com/mwcraig/ipyevents"&gt;ipyevents&lt;/a&gt; library, you can add mouse and key events to the Canvas and react to user interactions.&lt;/p&gt;
&lt;p&gt;If you have a GamePad around, you can also use the built-in &lt;a href="https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20List.html#Controller"&gt;Controller&lt;/a&gt; widget and make your own video-game in a Jupyter Notebook!&lt;/p&gt;
&lt;h3 id="documentation"&gt;Documentation&lt;/h3&gt;
&lt;p&gt;Check-out the ipycanvas documentation for more information: &lt;a href="https://ipycanvas.readthedocs.io/en/latest/?badge=latest"&gt;ipycanvas.readthedocs.io&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="github-repository"&gt;Github repository&lt;/h3&gt;
&lt;p&gt;Give it a star on Github if you like it! &lt;a href="https://github.com/martinRenou/ipycanvas/"&gt;github.com/martinRenou/ipycanvas&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="try-it-online"&gt;Try it online!&lt;/h3&gt;
&lt;p&gt;You can try it without the need of installing anything on your computer just by clicking on the image below:&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/martinRenou/ipycanvas/stable?filepath=examples"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/009-0_gt0KurDRJ50ZIIvf.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;
&lt;p&gt;Note that you first need to have Jupyter installed on your computer. You can install ipycanvas using pip:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;ipycanvas
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or using conda:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;conda-forge&lt;span class="w"&gt; &lt;/span&gt;ipycanvas
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="about-the-author"&gt;About the author&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://twitter.com/martinRenou"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/ipycanvas-a-python-canvas-for-jupyter/images/010-1_GH0Cfo-a2zZuJFrJyKrebA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My name is &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt;, I am a Scientific Software Engineer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, I studied at the aerospace engineering school &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt; in Toulouse, France. I also worked at Logilab in Paris and Enthought in Cambridge, UK. As an open-source developer at QuantStack, I worked on a variety of projects, from &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt; and &lt;a href="https://github.com/QuantStack/xeus-python/"&gt;xeus-python&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; in Python and Javascript.&lt;/p&gt;
</content><category term="visualization"/><category term="widgets"/></entry><entry><title>Interactive GIS in Jupyter with ipyleaflet</title><link href="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/" rel="alternate"/><published>2019-09-24T22:54:00+00:00</published><updated>2019-09-25T15:19:00+00:00</updated><author><name>Sylvain Corlay</name></author><id>tag:jupyter.org,2019-09-24:/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/</id><summary type="html">&lt;p&gt;As Jupyter grew in popularity, a broad ecosystem of visualization packages based on Jupyter widgets has been developed, bringing even more interactivity to the Jupyter world.&lt;/p&gt;</summary><content type="html">&lt;p&gt;As Jupyter grew in popularity, a broad ecosystem of visualization packages based on Jupyter widgets has been developed, bringing even more interactivity to the Jupyter world.&lt;/p&gt;
&lt;p&gt;In this article, we dive into Jupyter Interactive Widgets and the &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; package, an interactive maps visualization system for Jupyter.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A non-interactive map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/001-1_YA26aVkLDM1KXjNtGu5-Hw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A non-interactive map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="jupyter-widgets"&gt;Jupyter Widgets&lt;/h2&gt;
&lt;p&gt;Jupyter Interactive Widgets are “special objects” that can be instantiated by the user in their code and result in a counterpart component being created in the front-end.&lt;/p&gt;
&lt;p&gt;The core &lt;code&gt;ipywidgets&lt;/code&gt; package provides a collection of controls that Jupyter users can use to build simple UIs as part of their notebooks (sliders, buttons, dropdowns, layout components).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Basic ipywidgets controls." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/002-1_a8s90I7Kj3DyBjmh_LjAaw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Basic ipywidgets &lt;strong&gt;controls&lt;/strong&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More than a collection of controls, it provides a framework upon which a large ecosystem of components has been built, allowing notebook authors to capture user inputs in very diverse ways.&lt;/p&gt;
&lt;p&gt;Popular libraries built upon interactive widgets include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/bloomberg/bqplot"&gt;&lt;strong&gt;bqplot&lt;/strong&gt;&lt;/a&gt;, a 2-D plotting system for Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipyvolume/"&gt;&lt;strong&gt;ipyvolume&lt;/strong&gt;&lt;/a&gt;, a 3-D plotting package based on WebGL and ThreeJS,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jupyter-widgets/pythreejs"&gt;&lt;strong&gt;PythreeJS&lt;/strong&gt;&lt;/a&gt;, a 3-D scene description package exposing a large part of the ThreeJS API to Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mariobuikhuizen/ipyvuetify"&gt;&lt;strong&gt;ipyvuetify&lt;/strong&gt;&lt;/a&gt;, a large collection of VuetifyJS components exposed to Jupyter,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;&lt;strong&gt;ipywebrtc&lt;/strong&gt;&lt;/a&gt;, a library exposing the features of the WebRTC protocol to Jupyter kernels,&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/twosigma/beakerx"&gt;&lt;strong&gt;beakerx&lt;/strong&gt;&lt;/a&gt;, a collection of widgets, extensions, and kernels for Jupyter,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and many more… This list is not comprehensive and dozens of other widget packages have been developed.&lt;/p&gt;
&lt;p&gt;Key aspects of Jupyter widgets include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bidirectionality&lt;/strong&gt;: Widgets are not just meant for display but can also be used to capture user inputs, which can then trigger new computation. Notebook authors can compose sophisticated applications including a variety of components from different packages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Language Agnosticism&lt;/strong&gt;: Built upon the Jupyter ecosystem, the interactive widget protocol used for the synchronization between the kernel and the front-end is well-specified and can be implemented for any kernel.&lt;br&gt;
Back-ends for other languages than Python already exist, such as for C++ (with the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; Jupyter kernel), and languages of the JVM such as Clojure or Groovy (with the &lt;a href="http://beakerx.com/"&gt;beakerx&lt;/a&gt; kernels).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;: Jupyter widgets are not meant as a monolithic system with one and only one way to achieve a specific task. We strive to provide a foundational layer allowing third-party widget authors to be as inventive as possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;A common pattern for Jupyter widget packages has been to bring the capabilities of popular JavaScript visualization frameworks to Jupyter with a bridge based on ipywidgets. This is the case for the ipyleaflet package, as well as pythreejs and ipyvuetify.&lt;/p&gt;
&lt;p&gt;Another use case is the development of &lt;em&gt;ad hoc&lt;/em&gt; controls that are not necessarily relevant for a mainstream visualization package, but may be specific to a scientific field. An example is the &lt;a href="https://github.com/erdc/ipymesh"&gt;ipymesh&lt;/a&gt; project by Chris Kees which can be used to draw PSLG (planar straight-line graphs) in the Jupyter notebook.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ipyleaflet"&gt;ipyleaflet&lt;/h2&gt;
&lt;p&gt;ipyleaflet is a Jupyter - LeafletJS bridge, bringing mapping capabilities to the notebook and JupyterLab.&lt;/p&gt;
&lt;p&gt;Built as a bridge between the LeafletJS package and Jupyter, the ipyleaflet API maps to that of LeafletJS, bringing most of the core features of the package to Jupyter, and enabling a few popular LeafletJS extensions. A small difference is that following the Python coding style, ipyleaflet makes use of &lt;em&gt;snake_case&lt;/em&gt; instead of &lt;em&gt;CamelCase&lt;/em&gt; for attribute names.&lt;/p&gt;
&lt;h3 id="ipyleaflet-features"&gt;ipyleaflet features&lt;/h3&gt;
&lt;p&gt;The main components to the library are layers and controls, respectively items to be displayed on the map, and interactive widgets overlayed on the map area for greater interactivity.&lt;/p&gt;
&lt;p&gt;The first thing for which you may want to change the default value are the zoom level, the position, or the base layer for the map.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Changing the basemap layer in an ipyleaflet map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/003-1_02DmPnByfXtPkeYnytNvfA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Changing the basemap layer in an ipyleaflet map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Maps can be interactively edited in the Jupyter notebook, by dynamically changing or adding layers. In this screenshot, we add a custom layer including a GeoJSON dataset.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: An alternative layer to GeoJSON is GeoData, which lets the user load the data in the form of a GeoPandas dataframe instead of raw GeoJSON.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="Adding a GeoJSON dataset to an interactive map." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/004-1_3t7T3EGIeA10R0XrrM9ZVw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Adding a GeoJSON dataset to an interactive map.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A number of simple primitives are available such as markers and heatmaps. In the following screencast, we show how primitive properties can be linked with other widgets, and used as means to take user input on a map:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Linking properties of ipyleaflet primitives to other Jupyter widgets." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/005-1_31XAuFgaeln-mrjxxRzdxA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Linking properties of ipyleaflet primitives to other Jupyter widgets.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;em&gt;splitmap&lt;/em&gt; control can be used to compare to different set of ipyleaflet layers at the same location.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The splitmap control." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/006-1_lZT_nX-jH3jcMLFdhTUxXw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;splitmap&lt;/strong&gt; control.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another interesting layer is the &lt;em&gt;velocity&lt;/em&gt; layer which can be used to display wind velocity data. This control can take data in the form of an &lt;a href="https://github.com/pydata/xarray"&gt;xarray&lt;/a&gt; dataset.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The velocity layer." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/007-1_u2J2aJy6FfBaFytG0ppruw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;velocity&lt;/strong&gt; layer.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;More classical visualization tools are also available, such as &lt;em&gt;choropleths&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="A choropleth layer." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/008-1_MbLnLa_LsugvYdBNjGhhQQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A &lt;strong&gt;choropleth&lt;/strong&gt; layer.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="jupyterlab-integration-with-the-sidecar-and-theming-support"&gt;JupyterLab Integration with the Sidecar and Theming Support&lt;/h3&gt;
&lt;p&gt;ipyleaflet is well integrated with JupyterLab&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ipyleaflet controls make use of the &lt;strong&gt;JupyterLab themes&lt;/strong&gt; for coloring so that they don’t stand out when using e.g. a dark theme.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The support for JupyterLab themes in ipyleaflet." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/009-1_6tCnE8oedSXuEtiGKA1fAA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The support for JupyterLab &lt;strong&gt;themes&lt;/strong&gt; in ipyleaflet.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ipyleaflet can be used in combination with the &lt;a href="https://github.com/jupyter-widgets/jupyterlab-sidecar/"&gt;&lt;strong&gt;JupyterLab sidecar&lt;/strong&gt;&lt;/a&gt; widget.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the sidecar widget in JupyterLab to display a map aside of the notebook." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/010-1_eUr0hcPcBInlp125yA7sHg.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the &lt;strong&gt;sidecar&lt;/strong&gt; widget in JupyterLab to display a map aside of the notebook.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Together with the sidecar, a map can be programmatically added to the right-side toolbar of the JupyterLab application, and interactively edited in the notebook. This prevents the back-and-forth scrolling often required to see how changes are reflected visually.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The workflow enabled by ipyleaflet in combination with the sidecar is similar to that of the &lt;a href="https://github.com/OpenGeoscience/geonotebook"&gt;geonotebook&lt;/a&gt; project by Christopher Kotfila, Jonathan Beezley, and Dan LaManna from &lt;a href="https://www.kitware.com/"&gt;Kitware&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;
&lt;img alt="The geonotebook (which was based on the classic notebook) provided a similar workflow to the lab sidecar." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/011-1_u2dMqR9n5Vwl1ELtpTbVCg.jpg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The &lt;strong&gt;geonotebook&lt;/strong&gt; (which was based on the classic notebook) provided a similar workflow to the lab sidecar.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="a-more-advanced-example"&gt;A more advanced example&lt;/h3&gt;
&lt;p&gt;Combined with other widget libraries such as bqplot or the core ipywidget package, ipyleaflet users can easily compose more complex applications and dashboards. In the following screencast, we explore the wealth-of-nations dataset with a leafletmap, a bqplot line chart and a dropdown widget:&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Exploring the wealth-of-nations dataset with ipyleaflet, bqplot and core ipywidgets." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/012-1_0SvmdK7ykkDXZ4oU-x6QzA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Exploring the wealth-of-nations dataset with ipyleaflet, bqplot and core ipywidgets.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="trying-ipyleaflet-online-with-mybinder"&gt;Trying ipyleaflet online with mybinder&lt;/h3&gt;
&lt;p&gt;If you would like to try out ipyleaflet &lt;em&gt;now&lt;/em&gt;, it is possible thanks to the binder project. Just click on the image below!&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="https://mybinder.org/v2/gh/jupyter-widgets/ipyleaflet/stable?filepath=examples"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/013-1_AsxYLD3dKd9Vej3SII_eLg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="interactive-gis-in-c-xleaflet"&gt;Interactive GIS in C++: xleaflet&lt;/h3&gt;
&lt;p&gt;As mentioned earlier, interactive widgets back-ends for other programming languages have be implemented. There is a C++ back-end for ipywidgets: &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; which is the building block for creating other C++ widgets back-ends.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/014-0_aPvM-7TR9IbP_NXO.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xleaflet"&gt;xleaflet&lt;/a&gt; is the C++ - LeafletJS bridge that exposes almost the same API as ipyleaflet, only that you use it from a C++ interpreter! It is based upon xwidgets which brings the bidirectional communication with the front-end.&lt;/p&gt;
&lt;p&gt;You can learn more about the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; Jupyter kernel, xwidgets and xleaflet by reading the following &lt;a href="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/"&gt;blogpost&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="xleaflet is the C++ backend to the jupyter-leaflet integration." src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/015-1_m2ElLEj6r-6uDqXmA0tqRw.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;&lt;strong&gt;xleaflet&lt;/strong&gt; is the C++ backend to the jupyter-leaflet integration.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="deploying-ipyleaflet-based-dashboards-with-voila"&gt;Deploying ipyleaflet-based dashboards with Voilà&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/016-1_36JTV2RMHwg0DEW6V00d2A.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/voila"&gt;Voilà&lt;/a&gt; is a tool that turns Jupyter notebooks into standalone dashboards. Built upon the Jupyter stack, it inherits the language agnosticism of the ecosystem, and can be used to produce standalone applications based on ipyleaflet.&lt;/p&gt;
&lt;p&gt;A companion project to Voilà is the Voilà gallery project, a public facing set up of JupyterHub serving Voilà dashboard. It is kindly hosted by &lt;a href="https://www.ovh.com/fr/"&gt;OVH&lt;/a&gt;. You can check out the Voilà gallery at URL &lt;a href="https://voila-gallery.org/services/gallery/"&gt;https://voila-gallery.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For more resources about &lt;em&gt;voilà&lt;/em&gt;, check out&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the original announcement of the project: &lt;a href="https://blog.jupyter.org/and-voil%C3%A0-f6a2c08a4a93"&gt;&lt;em&gt;And Voilà!&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and for the gallery: &lt;a href="https://jupyter.org/blog/posts/2019/a-gallery-of-voila-examples/"&gt;&lt;em&gt;A Gallery of Voilà Examples&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you check out the Voilà gallery, don’t miss Jeremy Tuloup’s GPX loader demo!&lt;/p&gt;
&lt;h2 id="jupyter-for-geo-sciences"&gt;Jupyter for Geo Sciences&lt;/h2&gt;
&lt;p&gt;Jupyter’s adoption is exploding in the GeoScience space. Notable projects building upon Jupyter include&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jeodpp.jrc.ec.europa.eu/home/"&gt;&lt;em&gt;&lt;strong&gt;JEODPP&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; (JRC Earth Observation Data and Processing Platform) is a EU project providing petabyte scale storage and high-throughput computing capacities to facilitate large scale analysis of Earth Observation data. The main front-end to the platform is base on Jupyter. The mapping capability is based on &lt;strong&gt;ipyleaflet&lt;/strong&gt;. End users can request custom visualization that are returned to them in the form of lazily computed tile layers.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pangeo.io"&gt;&lt;em&gt;&lt;strong&gt;Pangeo&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; is a community platform providing open, reproducible, and scalable sciences. The Pangeo software ecosystem involves open source tools such as xarray, Iris, Dask, Jupyter, and many other packages.&lt;/li&gt;
&lt;li&gt;It was &lt;a href="https://jupyter.org/blog/posts/2019/jupyter-meets-the-earth/"&gt;recently announced&lt;/a&gt; that the NSF would be funding the UC Berkeley + NCAR “&lt;em&gt;&lt;strong&gt;EarthCube&lt;/strong&gt;&lt;/em&gt;” proposal “Jupyter meets the Earth: Enabling discovery in geoscience through interactive computing at scale”. The plan involves the development of interactive dashboards with &lt;strong&gt;Voilà&lt;/strong&gt; and contributions to the Voilà codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="related-projects"&gt;Related Projects&lt;/h2&gt;
&lt;h3 id="jupyter-gmaps"&gt;Jupyter-gmaps&lt;/h3&gt;
&lt;p&gt;We should mention the &lt;a href="https://github.com/pbugnion/gmaps"&gt;jupyter-gmaps&lt;/a&gt; project by Pascal Bugnion. Jupyter-gmaps is a bridge between Google maps and Jupyter. Just like ipyleaflet, jupyter-gmaps is built upon the jupyter interactive widgets framework but relies on Google maps for the display instead of LeafletJS library.&lt;/p&gt;
&lt;p&gt;This is a high-quality widget by another core developer of ipywidgets. Pascal is also one of the people behind Voilà and the Voilà gallery.&lt;/p&gt;
&lt;h3 id="folium"&gt;Folium&lt;/h3&gt;
&lt;p&gt;The &lt;a href="https://github.com/python-visualization/folium"&gt;Folium&lt;/a&gt; project enables maps visualization in the Jupyter notebook. Just like ipyleaflet, it is based on LeafletJS. Folium was created by Rob Story and is now maintained by Frank Conengmo and Filipe Fernandes.&lt;/p&gt;
&lt;p&gt;A key difference between Folium and ipyleaflet is that ipyleaflet is built upon ipywidgets and allows bidirectional communication between the front-end and the backend enabling the use of the map to capture user input, while Folium is meant for displaying static data only. Folium enables many LeafletJS extensions, some of which may not be available in ipyleaflet at the moment.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;The ipyleaflet project was started in 2015 by &lt;a href="https://twitter.com/ellisonbg?lang=en"&gt;Brian Granger&lt;/a&gt;, and funded by the &lt;a href="https://www.erdc.usace.army.mil/"&gt;ERDC&lt;/a&gt;. The further development by Sylvain Corlay and Martin Renou was supported by &lt;a href="https://quantstack.net/"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are grateful to &lt;a href="https://www.ovh.com"&gt;OVH&lt;/a&gt; for kindly hosting the &lt;a href="http://voila-gallery.org"&gt;Voilà gallery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other key contributors to Voilà and ipyleaflet that should be thanked here are Maarten Breddels, Pascal Bugnion, and Yuvi Panda. We should also mention the recent contributions by &lt;a href="https://twitter.com/VasavanT"&gt;Vasavan Thirusittampalam&lt;/a&gt; who worked on the full-screen control and better interoperability with geopandas.&lt;/p&gt;
&lt;h2 id="about-the-authors"&gt;About the Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, and &lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; are Scientific Software Developers at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="sylvain-corlay"&gt;Sylvain Corlay&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/017-1_6-g_O5JJQn4uSoAreSq9Pw_2x.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sylvain Corlay&lt;/strong&gt; is the founder and CEO of QuantStack.&lt;/p&gt;
&lt;p&gt;As an Open Source Developer, Sylvain contributes to Project Jupyter in the areas of interactive widgets and language kernels and is a steering committee member of the Project. Beyond QuantStack, Sylvain serves as a member of the board of directors of the NumFOCUS foundation. He also co-organizes the PyData Paris Meetup.&lt;/p&gt;
&lt;h3 id="martin-renou"&gt;Martin Renou&lt;/h3&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/interactive-gis-in-jupyter-with-ipyleaflet/images/018-1_eZ36LOdroOy_-KBEN8TLlg_2x.jpeg" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Martin Renou&lt;/strong&gt; is a Scientific Software Developer at QuantStack. Prior to joining QuantStack, Martin also worked as a Software developer at Enthought. He studied at the French Aerospace Engineering School ISAE-Supaero, with major in autonomous systems and programming.&lt;/p&gt;
&lt;p&gt;As an open source developer, Martin has worked on a variety of projects, such as SciviJS (a JavaScript 3-D mesh visualization library), Xtensor, and Xeus.&lt;/p&gt;
</content><category term="geoscience"/><category term="science"/><category term="visualization"/></entry><entry><title>A new Python kernel for Jupyter</title><link href="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/" rel="alternate"/><published>2019-01-09T09:16:00+00:00</published><updated>2019-09-30T07:04:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2019-01-09:/blog/posts/2019/a-new-python-kernel-for-jupyter/</id><summary type="html">&lt;p&gt;Project Jupyter aims at providing a consistent set of tools for interactive computing workflows across multiple programming languages. Jupyter projects are popular at all stages of a research project from the exploration phase to the communication of results and teaching.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Project Jupyter aims at providing a consistent set of tools for interactive computing workflows across multiple programming languages. Jupyter projects are popular at all stages of a research project from the exploration phase to the communication of results and teaching.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/001-1_ySP_XtCM_MMBawtlOOixag.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/002-1_u5Y0cs48UCc5bmGXP2rTIA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;The flagship project of Jupyter, the Notebook, and its modernized version, JupyterLab are web applications allowing the creation of documents including prose, executable code, and interactive visualizations.&lt;/p&gt;
&lt;p&gt;The kernel is the part of the backend responsible for executing code written by the user in the web application. For example, in the case of a Python notebook, execution of the code is typically handled by &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;, the reference implementation.&lt;/p&gt;
&lt;h2 id="history"&gt;History&lt;/h2&gt;
&lt;p&gt;Initially, the &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; project included everything from the notebook web application to the kernel and server implementation. Later on, the language-agnostic parts (the notebook format, messaging protocol, qtconsole, notebook web application) were split into separate projects with a clearer scope, together forming &lt;em&gt;Project Jupyter&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="The Big Split(TM) of IPython" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/003-1_PlpiXwbaiHo8VtTqcFyzGA.jpeg" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;The Big Split(TM) of IPython&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Splitting &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; into multiple packages was a good decision in that it brought a clear separation of concerns between the projects. The &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; project was elected as the reference implementation of the Jupyter kernel protocol.&lt;/p&gt;
&lt;p&gt;This came at a cost since &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; brought all the history and technical debt of &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; with it. Besides, Python is not a natural language for a base implementation. As a result, R and Julia kernels don’t use the reference implementation but use their own implementation of the protocol.&lt;/p&gt;
&lt;p&gt;Furthermore, the standard implementation of the Jupyter Interactive Widgets lies in the Python package &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt;. That means that once you, as a kernel developer, implemented the Jupyter kernel protocol, you would still need to make your own backend for the interactive widgets if you want widgets support (and you should want it, honestly…).&lt;/p&gt;
&lt;p&gt;To prevent this useless duplication of effort, which harms sustainability, we set ourselves to implement a solid reusable implementation of the Jupyter kernel protocol, &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="c-implementation-of-the-kernel-protocol"&gt;C++ implementation of the kernel protocol&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/004-1_OWq9aDu1wOvYig3AalBvFg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is a C++ implementation of the Jupyter kernel protocol. It is not a kernel by itself but a library that helps kernel authoring. &lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is very helpful when developing a kernel for a language that has a C or a C++API (Python, Lua, SQL, etc.). It takes the cumbersome task of implementing the &lt;a href="https://jupyter-client.readthedocs.io/en/stable/messaging.html"&gt;Jupyter messaging protocol&lt;/a&gt; for you so you just can focus on the core interpreter tasks: executing code, inspecting, completing, etc.&lt;/p&gt;
&lt;p&gt;C++ is a good choice for a standard implementation of the protocol, it is a common denominator of most of the languages out there, it has a massive developer community and is widely adopted in the industry for performance middleware applications.&lt;/p&gt;
&lt;p&gt;With &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, it is also very easy to reimplement core logic (server, kernel, history management etc.), if need be, by simply inheriting from &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; library classes.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;Xeus&lt;/a&gt; is already known for being used as a base for the C++ kernel &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-xeus-based-c-kernel"&gt;A xeus-based C++ Kernel&lt;/h2&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/005-1_vrE1i_8405140XOHfx77LA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus-cling"&gt;Xeus-cling&lt;/a&gt; is a &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;-based C++ kernel for the Jupyter Notebook. It’s very useful for teaching or learning C++. C++ has never been this interactive, thanks to the combined power of Jupyter, &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, and &lt;a href="https://github.com/root-project/cling"&gt;cling&lt;/a&gt;. And even more impressive than executing interpreted C++, it supports interactive widgets, thanks to the &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; project.&lt;/p&gt;
&lt;p&gt;Just like &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; is a C++ implementation of the Jupyter kernel protocol, &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt; is a C++ implementation of the Jupyter Interactive Widgets protocol, and it can be used as a base for other implementations.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/006-1_kA8toRCXwwnPmrsSIT7vhw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;You can try it right now with &lt;a href="https://mybinder.org/"&gt;binder&lt;/a&gt;, without the need of installing anything on your computer, just by clicking on &lt;a href="https://mybinder.org/v2/gh/QuantStack/xeus-cling/stable?filepath=notebooks/xcpp.ipynb"&gt;&lt;strong&gt;this link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Interactive C++ in the Jupyter Notebook" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/007-1_OJYy6QP8HSEPUQHhyyCOcQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Interactive C++ in the Jupyter Notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id="a-xeus-based-python-kernel"&gt;A xeus-based Python kernel&lt;/h2&gt;
&lt;p&gt;Today, I am pleased to announce a new Python kernel based on &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;: &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/008-1_YIXmS4xfX9MxQ6dHZLU8-g.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/QuantStack/xeus-python"&gt;Xeus-python&lt;/a&gt; supports error formatting, rich display, interactive widgets, input requests, code completion, code inspection, etc.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt; and &lt;a href="https://github.com/pybind/pybind11"&gt;pybind11&lt;/a&gt;, it was very straightforward to have a first simple version of a Python kernel written in C++. It took a couple of months to have the features listed above, with a relatively small amount of code (&amp;lt; 3000 lines of C++) and a good coverage of &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;’s features.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Simple code execution" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/009-1_2hHrN4ucrKKv68BJU9hRXQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Simple code execution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Error formatting" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/010-1_ewhjr2dkosifi7Qky1A83g.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Error formatting&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Code completion" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/011-1_LgaJ9RcNs0YZK7qaySX4NQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Code completion&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure&gt;
&lt;img alt="Ipywidgets support" src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/012-1_3XxIdWaB7HRmRDY_PzOGaQ.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Ipywidgets support&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Just like with &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt;, you can try it online without the need of installing anything on your computer following &lt;a href="https://mybinder.org/v2/gh/QuantStack/xeus-python/stable?filepath=notebooks/xeus-python.ipynb"&gt;&lt;strong&gt;this link&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="why-another-python-kernel"&gt;Why another Python kernel?&lt;/h2&gt;
&lt;p&gt;Obviously, &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; does not cover 100% of the features of &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt;. For examples, &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; magics are not supported yet by &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;. However:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt; is a lot lighter than &lt;a href="https://github.com/ipython/ipykernel"&gt;ipykernel&lt;/a&gt; and &lt;a href="https://ipython.org/"&gt;IPython&lt;/a&gt; combined, which makes it a lot easier to implement new features on top of it. Our next goal is to augment the protocol to implement a Python debugger in JupyterLab.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;-based kernels are more versatile in that one can overload e.g. the concurrency model. This is something that &lt;a href="https://www.kitware.com/"&gt;Kitware&lt;/a&gt;’s &lt;a href="https://github.com/Slicer/SlicerJupyter"&gt;SlicerJupyter&lt;/a&gt; project takes advantage of to integrate with the Qt event loop of their Qt-based desktop application.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="acknowledgments"&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;The development of &lt;a href="https://github.com/QuantStack/xeus"&gt;xeus&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xwidgets"&gt;xwidgets&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xeus-python"&gt;xeus-python&lt;/a&gt;, and related packages are led by &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt;.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;a href="http://quantstack.net/"&gt;&lt;img src="https://jupyter.org/blog/posts/2019/a-new-python-kernel-for-jupyter/images/013-1_1YuyD-AQ0fzVOStuxhChWw.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This development is sponsored by &lt;a href="https://www.techatbloomberg.com/"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software Engineer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;. Before joining &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, he studied at the French Aerospace Engineering School &lt;a href="https://www.isae-supaero.fr/en"&gt;SUPAERO&lt;/a&gt;. He also worked at Logilab in Paris and Enthought in Cambridge. As an open source developer at &lt;a href="http://quantstack.net/"&gt;QuantStack&lt;/a&gt;, Martin worked on a variety of projects, from &lt;a href="https://github.com/QuantStack/xsimd"&gt;xsimd&lt;/a&gt;, &lt;a href="https://github.com/QuantStack/xtensor"&gt;xtensor&lt;/a&gt;, and &lt;a href="https://github.com/QuantStack/xframe"&gt;xframe&lt;/a&gt; in C++ to &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; and &lt;a href="https://github.com/maartenbreddels/ipywebrtc"&gt;ipywebrtc&lt;/a&gt; in Python and JavaScript.&lt;/p&gt;
</content><category term="C++"/><category term="kernels"/></entry><entry><title>Interpreted C++ for GIS with Jupyter</title><link href="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/" rel="alternate"/><published>2018-04-24T08:35:00+00:00</published><updated>2019-09-30T07:04:00+00:00</updated><author><name>Martin Renou</name></author><id>tag:jupyter.org,2018-04-24:/blog/posts/2018/interpreted-c-for-gis-with-jupyter/</id><summary type="html">&lt;p&gt;The recent release of the Jupyter kernel for C++, based on the Cling interpreter enabled a number of new workflows for the users of the C++ programming language.&lt;/p&gt;</summary><content type="html">&lt;figure&gt;
&lt;img alt="A live interactive map in a C++ Jupyter notebook" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/001-1_FzUw4j635uJgWHZzc8_QiQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A live interactive map in a C++ Jupyter notebook&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The &lt;a href="https://jupyter.org/blog/posts/2017/interactive-workflows-for-c-with-jupyter/"&gt;recent release&lt;/a&gt; of the Jupyter kernel for C++, based on the Cling interpreter enabled a number of new workflows for the users of the C++ programming language.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/002-1_vrE1i_8405140XOHfx77LA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Features of the &lt;a href="https://github.com/QuantStack/xeus-cling"&gt;xeus-cling&lt;/a&gt; C++ kernel for Project Jupyter include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Showing quick-help pages for functions and classes of the STL and user-defined types, by prefixing them with a question mark:&lt;/em&gt;&lt;br&gt;
For example, typing &lt;code&gt;?std::vector&lt;/code&gt; results in a pager displaying the page from &lt;a href="http://en.cppreference.com/w/"&gt;cppreference&lt;/a&gt; on &lt;code&gt;std::vector&lt;/code&gt;.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Quick-help page for classes and functions of the STL" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/003-1_B77yBeBtyeIs3CqA2jlxKg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Quick-help page for classes and functions of the STL&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Making use of the rich display features of the Jupyter stack, for user-defined types.&lt;/em&gt;&lt;br&gt;
This can be enabled simply by overloading &lt;code&gt;mime_bundle_repr&lt;/code&gt; in the namespace of the class for which we wish to have a rich representation in the front-end. The overload is picked up by the display system through argument-dependent lookup (ADL).&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using Jupyter’s rich display mechanism in C++" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/004-1_GZkL0WWGqeuBDrs-INUkgg.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using Jupyter’s rich display mechanism in C++&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Another aspect of the newly released C++ kernel is the implementation of the Jupyter widgets protocol, enabling bi-directional communication between the front-end and the kernel.&lt;/em&gt; The &lt;a href="https://github.com/QuantStack/xwidgets/"&gt;xwidgets&lt;/a&gt; package, built upon xeus provides a complete implementation of the protocol, together with the implementation of most of the controls available in the reference &lt;a href="https://github.com/jupyter-widgets/ipywidgets"&gt;ipywidgets&lt;/a&gt; Python package.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Bidirectional communication with the front-end using Jupyter interactive widgets" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/005-1_GDwfwdQyqprIcHbXCCkDhA.mp4" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Bidirectional communication with the front-end using Jupyter interactive widgets&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More than a limited set of base controls, Jupyter widgets are a framework upon which one can build arbitrarily complex interactions. A large number of interactive widget libraries has been built upon ipywidgets. Popular examples include &lt;a href="https://github.com/jupyter-widgets/pythreejs"&gt;pythreejs&lt;/a&gt; (a Jupyter-threejs bridge), &lt;a href="https://github.com/bloomberg/bqplot"&gt;bqplot&lt;/a&gt; (an interactive plotting library for Jupyter), and &lt;a href="https://github.com/jupyter-widgets/ipyleaflet"&gt;ipyleaflet&lt;/a&gt; (a Jupyter-leafletjs bridge) allowing rich interactive maps in the Jupyter notebook.&lt;/p&gt;
&lt;p&gt;A common trait of most of these packages is that most of the logic is implemented in the front-end, while the back-end only involves synchronization of data attributes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A fully-specified communication protocol and a thin back-end architecture facilitate the job of kernel authors willing to bring the power of these visualization libraries to their language of choice.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hence, we have taken on the endeavor of providing a C++ implementation of the most popular Jupyter interactive widget libraries. These packages can be used in the C++ kernel, as well as in compiled application making use of the Jupyter kernel protocol.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/006-1_U88dDupn4NP1MVVvE30Twg.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;Today, we are proud to announce the first release of &lt;code&gt;xleaflet&lt;/code&gt;, the C++ counterpart to the popular &lt;code&gt;ipyleaflet&lt;/code&gt; package, and which makes use of the same front-end component.&lt;/p&gt;
&lt;p&gt;You can get started by simply creating a map inline in the Jupyter notebook.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specifying a center location and zoom level&lt;/li&gt;
&lt;li&gt;Specifying the tile layers to be displayed among the predefined base maps&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
&lt;img alt="A simple map with a specified center and zoom level, displaying the default tiles" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/007-1_BcnHhEfFYFPgBdQ6eyeKrA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;A simple map with a specified center and zoom level, displaying the default tiles&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A number of other attributes can be set in the map widget. To mimic named parameters, all widgets of &lt;code&gt;xwidgets&lt;/code&gt; and &lt;code&gt;xleaflet&lt;/code&gt; are provided with a generator class which can be used to initialize attributes using method-chaining syntax.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Making use of the generator class to specify any number of attributes of the map upon construction" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/001-1_FzUw4j635uJgWHZzc8_QiQ.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Making use of the generator class to specify any number of attributes of the map upon construction&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In addition to the base map feature, a broad number of features of the leaflet JavaScript library are exposed to the C++ backend directly. This includes markers, marker clusters, image overlays, a variety of controls.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Using the marker widget" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/008-1_BA8-dMRaOf4ikrYqBLnIjA.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Using the marker widget&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Whenever an attribute of a widget is modified in the front-end or in the back-end, the other side will properly reflect the data change.&lt;/p&gt;
&lt;p&gt;For example, setting &lt;code&gt;marker.location&lt;/code&gt; to a new value in the previous example will actually move the marker on the map. Reversely, if the &lt;code&gt;draggable&lt;/code&gt; attribute was set to &lt;code&gt;true&lt;/code&gt;, whenever the marker position changes in the front-end, the value is reflected in the C++ model.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Observer on the marker position" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/009-1_Acd0sgShjoe40M-Ust-aKQ.gif" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Observer on the marker position&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Another example is the support of the GeoJSON format, which allows one to load a JSON file locally and display its content on the map.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt="Support for the GeoJSON format" src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/010-1_ok5lH9V9NUwxMy-I5sey8A.webp" loading="lazy" data-body-image=""&gt;
&lt;figcaption&gt;Support for the GeoJSON format&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;The bidirectional communication between the front-end and the C++ back-end makes it easier for the end user to create interactive web applications without having to write any JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using the rich features of xleaflet, one can start building fully-fledged GIS application in C++.&lt;/p&gt;
&lt;p class="standalone-image"&gt;&lt;img src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/011-1_E2blHOSA9Gah1DZe1t8tKA.webp" alt="" loading="lazy" data-body-image=""&gt;&lt;/p&gt;
&lt;p&gt;If you are interested in trying xleaflet right now in your web browser, we provided a &lt;a href="https://mybinder.org/"&gt;binder&lt;/a&gt; for you.&lt;/p&gt;
&lt;p&gt;Simply click on the following binder link and start playing with interactive GIS in C++ in your web browser:&lt;/p&gt;
&lt;figure&gt;
&lt;a href="https://mybinder.org/v2/gh/QuantStack/xleaflet/0.2.0?filepath=notebooks"&gt;&lt;img alt="Click on the image to launch the live demo." src="https://jupyter.org/blog/posts/2018/interpreted-c-for-gis-with-jupyter/images/012-1_DodrT-K2jBSmbAbEhmfbEg.webp" loading="lazy" data-body-image=""&gt;&lt;/a&gt;
&lt;figcaption&gt;Click on the image to launch the live demo.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Check out the &lt;a href="http://xleaflet.readthedocs.io"&gt;documentation&lt;/a&gt; for more detailed information about xleaflet.&lt;/p&gt;
&lt;h2 id="aknowledgements"&gt;Aknowledgements&lt;/h2&gt;
&lt;p&gt;The software presented in this post was built upon the work of a large number of people including the &lt;strong&gt;Jupyter&lt;/strong&gt; team, the &lt;strong&gt;Cling&lt;/strong&gt; developers, the developers of &lt;strong&gt;xeus&lt;/strong&gt; and &lt;strong&gt;xwidgets&lt;/strong&gt;, and the developers of &lt;a href="http://leafletjs.com/"&gt;&lt;strong&gt;leafletjs&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We are especially grateful to &lt;a href="https://twitter.com/SylvainCorlay"&gt;Sylvain Corlay&lt;/a&gt;, &lt;a href="https://twitter.com/lgouarin"&gt;Loic Gouarin&lt;/a&gt;, &lt;a href="https://twitter.com/JohanMabille"&gt;Johan Mabille&lt;/a&gt;, and &lt;a href="https://github.com/wolfv"&gt;Wolf Vollprecht&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The development of xeus, xwidgets and related packages at &lt;a href="https://twitter.com/QuantStack"&gt;QuantStack&lt;/a&gt; is sponsored by &lt;a href="http://www.techatbloomberg.com"&gt;&lt;strong&gt;Bloomberg&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-the-author"&gt;About the Author&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/martinRenou"&gt;Martin Renou&lt;/a&gt; is a Scientific Software developer at &lt;a href="https://github.com/QuantStack/"&gt;QuantStack&lt;/a&gt;. Prior to joining QuantStack, Martin studied at the &lt;a href="https://www.isae-supaero.fr/en"&gt;French Institute of Aeronautics and Space&lt;/a&gt;. As an open source developer, he worked on a variety of projects, notably &lt;a href="https://demo.logilab.fr/SciviJS/"&gt;SciviJS&lt;/a&gt;, a JavaScript library for 3-D mesh visualization.&lt;/p&gt;
</content><category term="C++"/><category term="geoscience"/><category term="science"/></entry></feed>