/PlutoPlotly.jl

Primary LanguageJuliaThe UnlicenseUnlicense

PlutoPlotly.jl

Build Status Coverage Aqua QA

This package provides a wrapper type PlutoPlot around the Plot type from PlotlyBase.jl that exposes the plotly library.

The wrapper mostly defines a custom show method specifically optimized for displaying inside of Pluto.jl and adds the options of providing custom javascript functions to attach to the plolty JS events

You can load the PlutoPlotly package instead of PlotlyBase or PlotlyJS, and replace Plot with plot from PlutoPlotly. For example:

plot([5,6,7,2]; line_color="red")

You can also create a PlotlyBase Plot, and then wrap it inside a PlutoPlot object:

let
    # create a PlotlyBase function
    p = Plot(args...)
    # wrap it
    PlutoPlot(p)
end

(The function plot(args...) from PlutoPlotly is the same as PlutoPlot(Plot(args...)).)

Features

Persistent Layout

The custom show method relies on the Plotly.react function, which is optimized for updating or re-plotting data on an existing graph object, making it ideal in combination with Pluto's reactivity. The data transfer between Pluto and the browser also exploits Pluto's own publish_to_js function which is usually faster than standard JSON serialization, especially for big datasets.

One advantage of using react as opposed to newPlot from the Plotly library is that one can have the layout (e.g. zoom level, camera view angle, etc...) persist across reactive re-runs by exploiting the uirevision attribute of Plotly layouts:

60a529f3-c747-4259-bafb-ddcedcf5bfbc.mp4

Return values to Julia using @bind

The possibility of attaching event listeners to the plotly events allows to create nice interactivity between Julia and Pluto using the @bind macro

Coordinates of the clicked point

7ef3a455-4015-4012-9025-2415f8061851.mp4

Filtering only visible points in the plot

8a8b3f85-988b-4865-958f-da8a66ad008e.mp4

View the notebooks inside the notebook subfolder for more details and examples. Note that the notebooks have to be opened from the package folder as they directly load the latest version of the package (and do so from the path they are called from)