Files
gh-k-dense-ai-claude-scient…/skills/plotly/reference/export-interactivity.md
2025-11-30 08:30:10 +08:00

454 lines
9.0 KiB
Markdown

# Export and Interactivity
## Static Image Export
### Installation
Static image export requires Kaleido:
```bash
uv pip install kaleido
```
Kaleido v1+ requires Chrome/Chromium on your system.
### Supported Formats
- **Raster**: PNG, JPEG, WebP
- **Vector**: SVG, PDF
### Writing to File
```python
import plotly.express as px
fig = px.scatter(df, x='x', y='y')
# Format inferred from extension
fig.write_image('chart.png')
fig.write_image('chart.pdf')
fig.write_image('chart.svg')
# Explicit format
fig.write_image('chart', format='png')
```
### Converting to Bytes
```python
# Get image as bytes
img_bytes = fig.to_image(format='png')
# Display in Jupyter
from IPython.display import Image
Image(img_bytes)
# Save to file manually
with open('chart.png', 'wb') as f:
f.write(img_bytes)
```
### Customizing Export
```python
fig.write_image(
'chart.png',
format='png',
width=1200,
height=800,
scale=2 # Higher resolution
)
```
### Setting Export Defaults
```python
import plotly.io as pio
pio.kaleido.scope.default_format = 'png'
pio.kaleido.scope.default_width = 800
pio.kaleido.scope.default_height = 600
pio.kaleido.scope.default_scale = 2
```
### Exporting Multiple Figures
```python
import plotly.io as pio
# Kaleido v1+ only
pio.write_images(
fig=[fig1, fig2, fig3],
file=['chart1.png', 'chart2.png', 'chart3.png']
)
```
## Interactive HTML Export
### Basic Export
```python
# Full standalone HTML
fig.write_html('interactive_chart.html')
# Open in browser
fig.show()
```
### File Size Control
```python
# Full library embedded (~5MB file)
fig.write_html('chart.html', include_plotlyjs=True)
# CDN reference (~2KB file, requires internet)
fig.write_html('chart.html', include_plotlyjs='cdn')
# Local reference (requires plotly.min.js in same directory)
fig.write_html('chart.html', include_plotlyjs='directory')
# No library (for embedding in existing HTML with Plotly.js)
fig.write_html('chart.html', include_plotlyjs=False)
```
### HTML Configuration
```python
fig.write_html(
'chart.html',
config={
'displayModeBar': True,
'displaylogo': False,
'toImageButtonOptions': {
'format': 'png',
'filename': 'custom_image',
'height': 800,
'width': 1200,
'scale': 2
}
}
)
```
### Embedding in Templates
```python
# Get only the div (no full HTML structure)
html_div = fig.to_html(
full_html=False,
include_plotlyjs='cdn',
div_id='my-plot'
)
# Use in Jinja2 template
template = """
<html>
<body>
<h1>My Dashboard</h1>
{{ plot_div | safe }}
</body>
</html>
"""
```
## Interactivity Features
### Built-in Interactions
Plotly figures automatically support:
- **Hover tooltips** - Display data on hover
- **Pan and zoom** - Click and drag to pan, scroll to zoom
- **Box/lasso select** - Select multiple points
- **Legend toggling** - Click to hide/show traces
- **Double-click** - Reset axes
### Hover Customization
```python
# Hover mode
fig.update_layout(
hovermode='closest' # 'x', 'y', 'closest', 'x unified', False
)
# Custom hover template
fig.update_traces(
hovertemplate='<b>%{x}</b><br>' +
'Value: %{y:.2f}<br>' +
'Extra: %{customdata[0]}<br>' +
'<extra></extra>'
)
# Hover data in Plotly Express
fig = px.scatter(
df, x='x', y='y',
hover_data={
'extra_col': True, # Show column
'x': ':.2f', # Format column
'hidden': False # Hide column
},
hover_name='name_column' # Bold title
)
```
### Click Events (Dash/FigureWidget)
For web applications, use Dash or FigureWidget for click handling:
```python
# With FigureWidget in Jupyter
import plotly.graph_objects as go
fig = go.FigureWidget(data=[go.Scatter(x=[1, 2, 3], y=[4, 5, 6])])
def on_click(trace, points, selector):
print(f'Clicked on points: {points.point_inds}')
fig.data[0].on_click(on_click)
fig
```
### Zoom and Pan
```python
# Disable zoom/pan
fig.update_xaxes(fixedrange=True)
fig.update_yaxes(fixedrange=True)
# Set initial zoom
fig.update_xaxes(range=[0, 10])
fig.update_yaxes(range=[0, 100])
# Constrain zoom
fig.update_xaxes(
range=[0, 10],
constrain='domain'
)
```
### Rangeslider (Time Series)
```python
fig = px.line(df, x='date', y='value')
# Add rangeslider
fig.update_xaxes(rangeslider_visible=True)
# Customize rangeslider
fig.update_xaxes(
rangeslider=dict(
visible=True,
thickness=0.05,
bgcolor='lightgray'
)
)
```
### Range Selector Buttons
```python
fig.update_xaxes(
rangeselector=dict(
buttons=list([
dict(count=1, label='1m', step='month', stepmode='backward'),
dict(count=6, label='6m', step='month', stepmode='backward'),
dict(count=1, label='YTD', step='year', stepmode='todate'),
dict(count=1, label='1y', step='year', stepmode='backward'),
dict(step='all', label='All')
]),
x=0.0,
y=1.0,
xanchor='left',
yanchor='top'
)
)
```
### Buttons and Dropdowns
```python
fig.update_layout(
updatemenus=[
dict(
type='buttons',
direction='left',
buttons=list([
dict(
args=[{'type': 'scatter'}],
label='Scatter',
method='restyle'
),
dict(
args=[{'type': 'bar'}],
label='Bar',
method='restyle'
)
]),
x=0.1,
y=1.15
)
]
)
```
### Sliders
```python
fig.update_layout(
sliders=[
dict(
active=0,
steps=[
dict(
method='update',
args=[{'visible': [True, False]},
{'title': 'Dataset 1'}],
label='Dataset 1'
),
dict(
method='update',
args=[{'visible': [False, True]},
{'title': 'Dataset 2'}],
label='Dataset 2'
)
],
x=0.1,
y=0,
len=0.9
)
]
)
```
## Animations
### Using Plotly Express
```python
fig = px.scatter(
df, x='gdp', y='life_exp',
animation_frame='year', # Animate over this column
animation_group='country', # Group animated elements
size='population',
color='continent',
hover_name='country',
log_x=True,
range_x=[100, 100000],
range_y=[25, 90]
)
# Customize animation speed
fig.layout.updatemenus[0].buttons[0].args[1]['frame']['duration'] = 1000
fig.layout.updatemenus[0].buttons[0].args[1]['transition']['duration'] = 500
```
### Using Graph Objects
```python
import plotly.graph_objects as go
fig = go.Figure(
data=[go.Scatter(x=[1, 2], y=[1, 2])],
layout=go.Layout(
updatemenus=[dict(
type='buttons',
buttons=[dict(label='Play',
method='animate',
args=[None])]
)]
),
frames=[
go.Frame(data=[go.Scatter(x=[1, 2], y=[1, 2])]),
go.Frame(data=[go.Scatter(x=[1, 2], y=[2, 3])]),
go.Frame(data=[go.Scatter(x=[1, 2], y=[3, 4])])
]
)
```
## Displaying Figures
### In Jupyter
```python
# Default renderer
fig.show()
# Specific renderer
fig.show(renderer='notebook') # or 'jupyterlab', 'colab', 'kaggle'
```
### In Web Browser
```python
fig.show() # Opens in default browser
```
### In Dash Applications
```python
import dash
from dash import dcc, html
import plotly.express as px
app = dash.Dash(__name__)
fig = px.scatter(df, x='x', y='y')
app.layout = html.Div([
dcc.Graph(figure=fig)
])
app.run_server(debug=True)
```
### Saving and Loading
```python
# Save as JSON
fig.write_json('figure.json')
# Load from JSON
import plotly.io as pio
fig = pio.read_json('figure.json')
# Save as HTML
fig.write_html('figure.html')
```
## Configuration Options
### Display Config
```python
config = {
'displayModeBar': True, # Show toolbar
'displaylogo': False, # Hide Plotly logo
'modeBarButtonsToRemove': ['pan2d', 'lasso2d'], # Remove buttons
'toImageButtonOptions': {
'format': 'png',
'filename': 'custom_image',
'height': 500,
'width': 700,
'scale': 1
},
'scrollZoom': True, # Enable scroll zoom
'editable': True, # Enable editing
'responsive': True # Responsive sizing
}
fig.show(config=config)
fig.write_html('chart.html', config=config)
```
### Available Config Options
- `displayModeBar`: Show/hide toolbar ('hover', True, False)
- `displaylogo`: Show Plotly logo
- `modeBarButtonsToRemove`: List of buttons to hide
- `modeBarButtonsToAdd`: Custom buttons
- `scrollZoom`: Enable scroll to zoom
- `doubleClick`: Double-click behavior ('reset', 'autosize', 'reset+autosize', False)
- `showAxisDragHandles`: Show axis drag handles
- `editable`: Allow editing
- `responsive`: Responsive sizing