Plotly#
Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).
import panel as pn
pn.extension('plotly')
The Plotly
pane renders Plotly plots inside a panel. It optimizes the plot rendering by using binary serialization for any array data found on the Plotly object, providing efficient updates. Note that to use the Plotly pane in a Jupyter notebook, the Panel extension has to be loaded with ‘plotly’ as an argument to ensure that Plotly.js is initialized.
Parameters:#
For details on other options for customizing the component see the layout and styling how-to guides.
object
(object): The Plotly figure being displayedclick_data
(dict): Click callback dataclickannotation_data
(dict): Clickannotation callback dataconfig
(dict): Config datahover_data
(dict): Hover callback datalink_figure
(bool): Attach callbacks to the Plotly figure to update output when it is modified in place.relayout_data
(dict): Relayout callback datarestyle_data
(dict): Restyle callback dataselected_data
(dict): Selected callback dataviewport
(dict): Current viewport stateviewport_update_policy
(str, default = ‘mouseup’): Policy by which the viewport parameter is updated during user interactionsmouseup
: updates are synchronized when mouse button is released after panningcontinuoius
: updates are synchronized continually while panningthrottle
: updates are synchronized while panning, at intervals determined by the viewport_update_throttle parameter
viewport_update_throttle
(int, default = 200, bounds = (0, None)): Time interval in milliseconds at which viewport updates are synchronized when viewport_update_policy is “throttle”.
As with most other types Panel
will automatically convert a Plotly figure to a Plotly
pane if it is passed to the pn.panel
function or a panel layout, but a Plotly
pane can be constructed directly using the pn.pane.Plotly
constructor:
import numpy as np
import plotly.graph_objs as go
xx = np.linspace(-3.5, 3.5, 100)
yy = np.linspace(-3.5, 3.5, 100)
x, y = np.meshgrid(xx, yy)
z = np.exp(-(x-1)**2-y**2)-(x**3+y**4-x/5)*np.exp(-(x**2+y**2))
surface = go.Surface(z=z)
layout = go.Layout(
title='Plotly 3D Plot',
autosize=False,
width=500,
height=500,
margin=dict(t=50, b=50, r=50, l=50)
)
fig = dict(data=[surface], layout=layout)
plotly_pane = pn.pane.Plotly(fig)
plotly_pane
Once created the plot can be updated by modifying the Plotly traces and then triggering an update by setting or triggering an event on the pane object
. Note that this only works if the Figure
is defined as a dictionary, since Plotly will make copies of the traces, which means that modifying them in place has no effect. Modifying an array will send just the array using a binary protocol, leading to fast and efficient updates.
surface.z = np.sin(z+1)
plotly_pane.object = fig
Similarly, modifying the plot layout
will only modify the layout, leaving the traces unaffected.
fig['layout']['width'] = 800
plotly_pane.object = fig
The Plotly pane supports layouts and subplots of arbitrary complexity, allowing even deeply nested Plotly figures to be displayed:
from plotly import subplots
heatmap = go.Heatmap(
z=[[1, 20, 30],
[20, 1, 60],
[30, 60, 1]],
showscale=False)
y0 = np.random.randn(50)
y1 = np.random.randn(50)+1
box_1 = go.Box(y=y0)
box_2 = go.Box(y=y1)
data = [heatmap, box_1, box_2]
fig = subplots.make_subplots(
rows=2, cols=2, specs=[[{}, {}], [{'colspan': 2}, None]],
subplot_titles=('First Subplot','Second Subplot', 'Third Subplot')
)
fig.append_trace(box_1, 1, 1)
fig.append_trace(box_2, 1, 2)
fig.append_trace(heatmap, 2, 1)
fig['layout'].update(height=600, width=600, title='i <3 subplots')
fig = fig.to_dict()
subplot_panel = pn.pane.Plotly(fig)
subplot_panel
Just like in the single-subplot case we can modify just certain aspects of a plot and then trigger an update. E.g. here we replace the overall title text:
fig['layout']['title']['text'] = 'i <3 updating subplots'
subplot_panel.object = fig
Lastly, Plotly plots can be made responsive using the autosize
option on a Plotly layout:
import pandas as pd
import plotly.express as px
data = pd.DataFrame([
('Monday', 7), ('Tuesday', 4), ('Wednesday', 9), ('Thursday', 4),
('Friday', 4), ('Saturday', 4), ('Sunay', 4)], columns=['Day', 'Orders']
)
fig = px.line(data, x="Day", y="Orders")
fig.update_traces(mode="lines+markers", marker=dict(size=10), line=dict(width=4))
fig.layout.autosize = True
responsive = pn.pane.Plotly(fig)
pn.Column('# A responsive plot', responsive, sizing_mode='stretch_width')
Controls#
The Plotly
pane exposes a number of options which can be changed from both Python and Javascript try out the effect of these parameters interactively:
pn.Row(responsive.controls(jslink=True), responsive)
Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).