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.
For layout and styling related parameters see the customization user guide.
object
(object): The Plotly figure being displayedclick_data
(dict): Click callback dataclickannotation_data
(dict): Clickannotation callback dataconfig
(dict): Config datahover_data
(dict): Hover callback datarelayout_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 parameterviewport_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, config={'responsive': True})
pn.Column('# A responsive plot', responsive, sizing_mode='stretch_width')
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)