Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:30:10 +08:00
commit f0bd18fb4e
824 changed files with 331919 additions and 0 deletions

View File

@@ -0,0 +1,488 @@
# Plotly Chart Types
Comprehensive guide to chart types organized by category.
## Basic Charts
### Scatter Plots
```python
import plotly.express as px
fig = px.scatter(df, x='x', y='y', color='category', size='size')
# With trendlines
fig = px.scatter(df, x='x', y='y', trendline='ols')
```
### Line Charts
```python
fig = px.line(df, x='date', y='value', color='group')
# Multiple lines from wide-form data
fig = px.line(df, x='date', y=['metric1', 'metric2', 'metric3'])
```
### Bar Charts
```python
# Vertical bars
fig = px.bar(df, x='category', y='value', color='group')
# Horizontal bars
fig = px.bar(df, x='value', y='category', orientation='h')
# Stacked bars
fig = px.bar(df, x='category', y='value', color='group', barmode='stack')
# Grouped bars
fig = px.bar(df, x='category', y='value', color='group', barmode='group')
```
### Pie Charts
```python
fig = px.pie(df, names='category', values='count')
# Donut chart
fig = px.pie(df, names='category', values='count', hole=0.4)
```
### Area Charts
```python
fig = px.area(df, x='date', y='value', color='category')
```
## Statistical Charts
### Histograms
```python
# Basic histogram
fig = px.histogram(df, x='values', nbins=30)
# With marginal plot
fig = px.histogram(df, x='values', marginal='box') # or 'violin', 'rug'
# 2D histogram
fig = px.density_heatmap(df, x='x', y='y', nbinsx=20, nbinsy=20)
```
### Box Plots
```python
fig = px.box(df, x='category', y='value', color='group')
# Notched box plot
fig = px.box(df, x='category', y='value', notched=True)
# Show all points
fig = px.box(df, x='category', y='value', points='all')
```
### Violin Plots
```python
fig = px.violin(df, x='category', y='value', color='group', box=True, points='all')
```
### Strip/Dot Plots
```python
fig = px.strip(df, x='category', y='value', color='group')
```
### Distribution Plots
```python
# Empirical cumulative distribution
fig = px.ecdf(df, x='value', color='group')
# Marginal distribution
fig = px.scatter(df, x='x', y='y', marginal_x='histogram', marginal_y='box')
```
### Error Bars
```python
fig = px.scatter(df, x='x', y='y', error_y='error', error_x='x_error')
# Using graph_objects for custom error bars
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x=[1, 2, 3],
y=[5, 10, 15],
error_y=dict(
type='data',
array=[1, 2, 3],
visible=True
)
))
```
## Scientific Charts
### Heatmaps
```python
# From matrix data
fig = px.imshow(z_matrix, color_continuous_scale='Viridis')
# With graph_objects
fig = go.Figure(data=go.Heatmap(
z=z_matrix,
x=x_labels,
y=y_labels,
colorscale='RdBu'
))
```
### Contour Plots
```python
# 2D contour
fig = px.density_contour(df, x='x', y='y')
# Filled contour
fig = go.Figure(data=go.Contour(
z=z_matrix,
contours=dict(
coloring='heatmap',
showlabels=True
)
))
```
### Ternary Plots
```python
fig = px.scatter_ternary(df, a='component_a', b='component_b', c='component_c')
```
### Log Scales
```python
fig = px.scatter(df, x='x', y='y', log_x=True, log_y=True)
```
### Image Display
```python
import plotly.express as px
fig = px.imshow(img_array) # img_array from PIL, numpy, etc.
```
## Financial Charts
### Candlestick Charts
```python
import plotly.graph_objects as go
fig = go.Figure(data=[go.Candlestick(
x=df['date'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close']
)])
```
### OHLC Charts
```python
fig = go.Figure(data=[go.Ohlc(
x=df['date'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close']
)])
```
### Waterfall Charts
```python
fig = go.Figure(go.Waterfall(
x=categories,
y=values,
measure=['relative', 'relative', 'total', 'relative', 'total']
))
```
### Funnel Charts
```python
fig = px.funnel(df, x='count', y='stage')
# Or with graph_objects
fig = go.Figure(go.Funnel(
y=['Stage 1', 'Stage 2', 'Stage 3'],
x=[100, 60, 40]
))
```
### Time Series
```python
fig = px.line(df, x='date', y='price')
# With rangeslider
fig.update_xaxes(rangeslider_visible=True)
# With range selector buttons
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')
])
)
)
```
## Maps and Geographic
### Scatter Maps
```python
# Geographic projection
fig = px.scatter_geo(df, lat='lat', lon='lon', color='value', size='size')
# Mapbox (requires token for some styles)
fig = px.scatter_mapbox(
df, lat='lat', lon='lon',
color='value',
zoom=10,
mapbox_style='open-street-map' # or 'carto-positron', 'carto-darkmatter'
)
```
### Choropleth Maps
```python
# Country-level
fig = px.choropleth(
df,
locations='iso_alpha',
color='value',
hover_name='country',
color_continuous_scale='Viridis'
)
# US States
fig = px.choropleth(
df,
locations='state_code',
locationmode='USA-states',
color='value',
scope='usa'
)
```
### Density Maps
```python
fig = px.density_mapbox(
df, lat='lat', lon='lon', z='value',
radius=10,
zoom=10,
mapbox_style='open-street-map'
)
```
## 3D Charts
### 3D Scatter
```python
fig = px.scatter_3d(df, x='x', y='y', z='z', color='category', size='size')
```
### 3D Line
```python
fig = px.line_3d(df, x='x', y='y', z='z', color='group')
```
### 3D Surface
```python
import plotly.graph_objects as go
fig = go.Figure(data=[go.Surface(z=z_matrix, x=x_array, y=y_array)])
fig.update_layout(scene=dict(
xaxis_title='X',
yaxis_title='Y',
zaxis_title='Z'
))
```
### 3D Mesh
```python
fig = go.Figure(data=[go.Mesh3d(
x=x_coords,
y=y_coords,
z=z_coords,
i=i_indices,
j=j_indices,
k=k_indices,
intensity=intensity_values,
colorscale='Viridis'
)]
```
### 3D Cone (Vector Field)
```python
fig = go.Figure(data=go.Cone(
x=x, y=y, z=z,
u=u, v=v, w=w,
colorscale='Blues',
sizemode='absolute',
sizeref=0.5
))
```
## Hierarchical Charts
### Sunburst
```python
fig = px.sunburst(
df,
path=['continent', 'country', 'city'],
values='population',
color='value'
)
```
### Treemap
```python
fig = px.treemap(
df,
path=['category', 'subcategory', 'item'],
values='count',
color='value',
color_continuous_scale='RdBu'
)
```
### Sankey Diagram
```python
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=15,
thickness=20,
line=dict(color='black', width=0.5),
label=['A', 'B', 'C', 'D', 'E'],
color='blue'
),
link=dict(
source=[0, 1, 0, 2, 3],
target=[2, 3, 3, 4, 4],
value=[8, 4, 2, 8, 4]
)
)])
```
## Specialized Charts
### Parallel Coordinates
```python
fig = px.parallel_coordinates(
df,
dimensions=['dim1', 'dim2', 'dim3', 'dim4'],
color='target',
color_continuous_scale='Viridis'
)
```
### Parallel Categories
```python
fig = px.parallel_categories(
df,
dimensions=['cat1', 'cat2', 'cat3'],
color='value'
)
```
### Scatter Matrix (SPLOM)
```python
fig = px.scatter_matrix(
df,
dimensions=['col1', 'col2', 'col3', 'col4'],
color='category'
)
```
### Indicator/Gauge
```python
fig = go.Figure(go.Indicator(
mode='gauge+number+delta',
value=75,
delta={'reference': 60},
gauge={'axis': {'range': [None, 100]},
'bar': {'color': 'darkblue'},
'steps': [
{'range': [0, 50], 'color': 'lightgray'},
{'range': [50, 100], 'color': 'gray'}
],
'threshold': {'line': {'color': 'red', 'width': 4},
'thickness': 0.75,
'value': 90}
}
))
```
### Table
```python
fig = go.Figure(data=[go.Table(
header=dict(values=['A', 'B', 'C']),
cells=dict(values=[col_a, col_b, col_c])
)])
```
## Bioinformatics
### Dendrogram
```python
from plotly.figure_factory import create_dendrogram
fig = create_dendrogram(data_matrix)
```
### Annotated Heatmap
```python
from plotly.figure_factory import create_annotated_heatmap
fig = create_annotated_heatmap(z_matrix, x=x_labels, y=y_labels)
```
### Volcano Plot
```python
# Typically built with scatter plot
fig = px.scatter(
df,
x='log2_fold_change',
y='neg_log10_pvalue',
color='significant',
hover_data=['gene_name']
)
fig.add_hline(y=-np.log10(0.05), line_dash='dash')
fig.add_vline(x=-1, line_dash='dash')
fig.add_vline(x=1, line_dash='dash')
```

View File

@@ -0,0 +1,453 @@
# 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

View File

@@ -0,0 +1,302 @@
# Graph Objects - Low-Level API
The `plotly.graph_objects` module provides fine-grained control over figure construction through Python classes representing Plotly components.
## Core Classes
- **`go.Figure`** - Main figure container
- **`go.FigureWidget`** - Jupyter-compatible interactive widget
- **Trace types** - 40+ chart types (Scatter, Bar, Heatmap, etc.)
- **Layout components** - Axes, annotations, shapes, etc.
## Key Advantages
1. **Data validation** - Helpful error messages for invalid properties
2. **Built-in documentation** - Accessible via docstrings
3. **Flexible syntax** - Dictionary or attribute access
4. **Convenience methods** - `.add_trace()`, `.update_layout()`, etc.
5. **Magic underscore notation** - Compact nested property access
6. **Integrated I/O** - `.show()`, `.write_html()`, `.write_image()`
## Basic Figure Construction
### Creating Empty Figure
```python
import plotly.graph_objects as go
fig = go.Figure()
```
### Adding Traces
```python
# Method 1: Add traces one at a time
fig = go.Figure()
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6], name='Line 1'))
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[2, 3, 4], name='Line 2'))
# Method 2: Pass data to constructor
fig = go.Figure(data=[
go.Scatter(x=[1, 2, 3], y=[4, 5, 6], name='Line 1'),
go.Scatter(x=[1, 2, 3], y=[2, 3, 4], name='Line 2')
])
```
## Common Trace Types
### Scatter (Lines and Markers)
```python
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[10, 11, 12, 13],
mode='lines+markers', # 'lines', 'markers', 'lines+markers', 'text'
name='Trace 1',
line=dict(color='red', width=2, dash='dash'),
marker=dict(size=10, color='blue', symbol='circle')
))
```
### Bar
```python
fig.add_trace(go.Bar(
x=['A', 'B', 'C'],
y=[1, 3, 2],
name='Bar Chart',
marker=dict(color='lightblue'),
text=[1, 3, 2],
textposition='auto'
))
```
### Heatmap
```python
fig.add_trace(go.Heatmap(
z=[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
x=['A', 'B', 'C'],
y=['X', 'Y', 'Z'],
colorscale='Viridis'
))
```
### 3D Scatter
```python
fig.add_trace(go.Scatter3d(
x=[1, 2, 3],
y=[4, 5, 6],
z=[7, 8, 9],
mode='markers',
marker=dict(size=5, color='red')
))
```
## Layout Configuration
### Update Layout
```python
fig.update_layout(
title='Figure Title',
title_font_size=20,
xaxis_title='X Axis',
yaxis_title='Y Axis',
width=800,
height=600,
template='plotly_white',
showlegend=True,
hovermode='closest' # 'x', 'y', 'closest', 'x unified', False
)
```
### Magic Underscore Notation
Compact way to set nested properties:
```python
# Instead of:
fig.update_layout(title=dict(text='Title', font=dict(size=20)))
# Use underscores:
fig.update_layout(
title_text='Title',
title_font_size=20
)
```
### Axis Configuration
```python
fig.update_xaxes(
title='X Axis',
range=[0, 10],
showgrid=True,
gridwidth=1,
gridcolor='lightgray',
type='log', # 'linear', 'log', 'date', 'category'
tickformat='.2f',
dtick=1 # Tick spacing
)
fig.update_yaxes(
title='Y Axis',
zeroline=True,
zerolinewidth=2,
zerolinecolor='black'
)
```
## Updating Traces
```python
# Update all traces
fig.update_traces(
marker=dict(size=10, opacity=0.7)
)
# Update specific trace
fig.update_traces(
marker=dict(color='red'),
selector=dict(name='Line 1')
)
# Update by position
fig.data[0].marker.size = 15
```
## Adding Annotations
```python
fig.add_annotation(
x=2, y=5,
text='Important Point',
showarrow=True,
arrowhead=2,
arrowsize=1,
arrowwidth=2,
arrowcolor='red',
ax=40, # Arrow x offset
ay=-40 # Arrow y offset
)
```
## Adding Shapes
```python
# Rectangle
fig.add_shape(
type='rect',
x0=1, y0=2, x1=3, y1=4,
line=dict(color='red', width=2),
fillcolor='lightblue',
opacity=0.3
)
# Line
fig.add_shape(
type='line',
x0=0, y0=0, x1=5, y1=5,
line=dict(color='green', width=2, dash='dash')
)
# Convenience methods for horizontal/vertical lines
fig.add_hline(y=5, line_dash='dash', line_color='red')
fig.add_vline(x=3, line_dash='dot', line_color='blue')
```
## Figure Structure
Figures follow a tree hierarchy:
```python
fig = go.Figure(data=[trace1, trace2], layout=go.Layout(...))
# Access via dictionary syntax
fig['layout']['title'] = 'New Title'
fig['data'][0]['marker']['color'] = 'red'
# Or attribute syntax
fig.layout.title = 'New Title'
fig.data[0].marker.color = 'red'
```
## Complex Chart Types
### Candlestick
```python
fig.add_trace(go.Candlestick(
x=df['date'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
name='Stock Price'
))
```
### Sankey Diagram
```python
fig = go.Figure(data=[go.Sankey(
node=dict(
label=['A', 'B', 'C', 'D'],
color='blue'
),
link=dict(
source=[0, 1, 0, 2],
target=[2, 3, 3, 3],
value=[8, 4, 2, 8]
)
)])
```
### Surface (3D)
```python
fig = go.Figure(data=[go.Surface(
z=z_data, # 2D array
x=x_data,
y=y_data,
colorscale='Viridis'
)])
```
## Working with DataFrames
Build traces from pandas DataFrames:
```python
import pandas as pd
df = pd.DataFrame({
'x': [1, 2, 3, 4],
'y': [10, 11, 12, 13]
})
fig = go.Figure()
for group_name, group_df in df.groupby('category'):
fig.add_trace(go.Scatter(
x=group_df['x'],
y=group_df['y'],
name=group_name,
mode='lines+markers'
))
```
## When to Use Graph Objects
Use graph_objects when:
- Creating chart types not available in Plotly Express
- Building complex multi-trace figures from scratch
- Need precise control over individual components
- Creating specialized visualizations (3D mesh, isosurface, custom shapes)
- Building subplots with mixed chart types
Use Plotly Express when:
- Creating standard charts quickly
- Working with tidy DataFrame data
- Want automatic styling and legends

View File

@@ -0,0 +1,457 @@
# Layouts, Styling, and Customization
## Subplots
### Creating Subplots
```python
from plotly.subplots import make_subplots
import plotly.graph_objects as go
# Basic grid
fig = make_subplots(rows=2, cols=2)
# Add traces to specific positions
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6]), row=1, col=1)
fig.add_trace(go.Bar(x=['A', 'B', 'C'], y=[1, 3, 2]), row=1, col=2)
fig.add_trace(go.Scatter(x=[1, 2, 3], y=[2, 3, 4]), row=2, col=1)
```
### Subplot Options
```python
fig = make_subplots(
rows=2, cols=2,
# Titles
subplot_titles=('Plot 1', 'Plot 2', 'Plot 3', 'Plot 4'),
# Custom dimensions
column_widths=[0.7, 0.3],
row_heights=[0.4, 0.6],
# Spacing
horizontal_spacing=0.1,
vertical_spacing=0.15,
# Shared axes
shared_xaxes=True, # or 'columns', 'rows', 'all'
shared_yaxes=False,
# Trace types (optional, for mixed types)
specs=[[{'type': 'scatter'}, {'type': 'bar'}],
[{'type': 'surface'}, {'type': 'table'}]]
)
```
### Mixed Subplot Types
```python
from plotly.subplots import make_subplots
import plotly.graph_objects as go
# 2D and 3D subplots
fig = make_subplots(
rows=1, cols=2,
specs=[[{'type': 'scatter'}, {'type': 'scatter3d'}]]
)
fig.add_trace(go.Scatter(x=[1, 2], y=[3, 4]), row=1, col=1)
fig.add_trace(go.Scatter3d(x=[1, 2], y=[3, 4], z=[5, 6]), row=1, col=2)
```
### Customizing Subplot Axes
```python
# Update specific subplot axes
fig.update_xaxes(title_text='X Label', row=1, col=1)
fig.update_yaxes(title_text='Y Label', range=[0, 100], row=2, col=1)
# Update all x-axes
fig.update_xaxes(showgrid=True, gridcolor='lightgray')
```
### Shared Colorscale
```python
fig = make_subplots(rows=1, cols=2)
fig.add_trace(go.Bar(x=['A', 'B'], y=[1, 2],
marker=dict(color=[1, 2], coloraxis='coloraxis')),
row=1, col=1)
fig.add_trace(go.Bar(x=['C', 'D'], y=[3, 4],
marker=dict(color=[3, 4], coloraxis='coloraxis')),
row=1, col=2)
fig.update_layout(coloraxis=dict(colorscale='Viridis'))
```
## Templates and Themes
### Built-in Templates
```python
import plotly.express as px
import plotly.io as pio
# Available templates
templates = [
'plotly', # Default
'plotly_white', # White background
'plotly_dark', # Dark theme
'ggplot2', # ggplot2 style
'seaborn', # Seaborn style
'simple_white', # Minimal white
'presentation', # For presentations
'xgridoff', # No x grid
'ygridoff', # No y grid
'gridon', # Grid on
'none' # No styling
]
# Use in Plotly Express
fig = px.scatter(df, x='x', y='y', template='plotly_dark')
# Use in graph_objects
fig.update_layout(template='seaborn')
# Set default template for session
pio.templates.default = 'plotly_white'
```
### Custom Templates
```python
import plotly.graph_objects as go
import plotly.io as pio
# Create custom template
custom_template = go.layout.Template(
layout=go.Layout(
font=dict(family='Arial', size=14),
plot_bgcolor='#f0f0f0',
paper_bgcolor='white',
colorway=['#1f77b4', '#ff7f0e', '#2ca02c'],
title_font_size=20
)
)
# Register template
pio.templates['custom'] = custom_template
# Use it
fig = px.scatter(df, x='x', y='y', template='custom')
```
## Styling with Plotly Express
### Built-in Arguments
```python
fig = px.scatter(
df, x='x', y='y',
# Dimensions
width=800,
height=600,
# Title
title='Figure Title',
# Labels
labels={'x': 'X Axis Label', 'y': 'Y Axis Label'},
# Colors
color='category',
color_discrete_sequence=px.colors.qualitative.Set2,
color_discrete_map={'A': 'red', 'B': 'blue'},
color_continuous_scale='Viridis',
# Ordering
category_orders={'category': ['A', 'B', 'C']},
# Template
template='plotly_white'
)
```
### Setting Defaults
```python
import plotly.express as px
# Session-wide defaults
px.defaults.template = 'plotly_white'
px.defaults.width = 800
px.defaults.height = 600
px.defaults.color_continuous_scale = 'Viridis'
```
## Color Scales
### Discrete Colors
```python
import plotly.express as px
# Named color sequences
color_sequences = [
px.colors.qualitative.Plotly,
px.colors.qualitative.D3,
px.colors.qualitative.G10,
px.colors.qualitative.Set1,
px.colors.qualitative.Pastel,
px.colors.qualitative.Dark2,
]
fig = px.scatter(df, x='x', y='y', color='category',
color_discrete_sequence=px.colors.qualitative.Set2)
```
### Continuous Colors
```python
# Named continuous scales
continuous_scales = [
'Viridis', 'Plasma', 'Inferno', 'Magma', 'Cividis', # Perceptually uniform
'Blues', 'Greens', 'Reds', 'YlOrRd', 'YlGnBu', # Sequential
'RdBu', 'RdYlGn', 'Spectral', 'Picnic', # Diverging
]
fig = px.scatter(df, x='x', y='y', color='value',
color_continuous_scale='Viridis')
# Reverse scale
fig = px.scatter(df, x='x', y='y', color='value',
color_continuous_scale='Viridis_r')
# Custom scale
fig = px.scatter(df, x='x', y='y', color='value',
color_continuous_scale=['blue', 'white', 'red'])
```
### Colorbar Customization
```python
fig.update_coloraxes(
colorbar=dict(
title='Value',
tickmode='linear',
tick0=0,
dtick=10,
len=0.7, # Length relative to plot
thickness=20,
x=1.02 # Position
)
)
```
## Layout Customization
### Title and Fonts
```python
fig.update_layout(
title=dict(
text='Main Title',
font=dict(size=24, family='Arial', color='darkblue'),
x=0.5, # Center title
xanchor='center'
),
font=dict(
family='Arial',
size=14,
color='black'
)
)
```
### Margins and Size
```python
fig.update_layout(
width=1000,
height=600,
margin=dict(
l=50, # left
r=50, # right
t=100, # top
b=50, # bottom
pad=10 # padding
),
autosize=True # Auto-resize to container
)
```
### Background Colors
```python
fig.update_layout(
plot_bgcolor='#f0f0f0', # Plot area
paper_bgcolor='white' # Figure background
)
```
### Legend
```python
fig.update_layout(
showlegend=True,
legend=dict(
title='Legend Title',
orientation='h', # 'h' or 'v'
x=0.5, # Position
y=-0.2,
xanchor='center',
yanchor='top',
bgcolor='rgba(255, 255, 255, 0.8)',
bordercolor='black',
borderwidth=1,
font=dict(size=12)
)
)
```
### Axes
```python
fig.update_xaxes(
title='X Axis Title',
title_font=dict(size=16, family='Arial'),
# Range
range=[0, 10],
autorange=True, # Auto range
# Grid
showgrid=True,
gridwidth=1,
gridcolor='lightgray',
# Ticks
showticklabels=True,
tickmode='linear',
tick0=0,
dtick=1,
tickformat='.2f',
tickangle=-45,
# Zero line
zeroline=True,
zerolinewidth=2,
zerolinecolor='black',
# Scale
type='linear', # 'linear', 'log', 'date', 'category'
)
fig.update_yaxes(
title='Y Axis Title',
# ... same options as xaxes
)
```
### Hover Behavior
```python
fig.update_layout(
hovermode='closest', # 'x', 'y', 'closest', 'x unified', False
)
# Customize hover template
fig.update_traces(
hovertemplate='<b>%{x}</b><br>Value: %{y:.2f}<extra></extra>'
)
```
### Annotations
```python
fig.add_annotation(
text='Important Note',
x=2,
y=5,
showarrow=True,
arrowhead=2,
arrowsize=1,
arrowwidth=2,
arrowcolor='red',
ax=40, # Arrow x offset
ay=-40, # Arrow y offset
font=dict(size=14, color='black'),
bgcolor='yellow',
opacity=0.8
)
```
### Shapes
```python
# Rectangle
fig.add_shape(
type='rect',
x0=1, y0=2, x1=3, y1=4,
line=dict(color='red', width=2),
fillcolor='lightblue',
opacity=0.3
)
# Circle
fig.add_shape(
type='circle',
x0=0, y0=0, x1=1, y1=1,
line_color='purple'
)
# Convenience methods
fig.add_hline(y=5, line_dash='dash', line_color='red',
annotation_text='Threshold')
fig.add_vline(x=3, line_dash='dot')
fig.add_vrect(x0=1, x1=2, fillcolor='green', opacity=0.2)
fig.add_hrect(y0=4, y1=6, fillcolor='red', opacity=0.2)
```
## Update Methods
### Update Layout
```python
fig.update_layout(
title='New Title',
xaxis_title='X',
yaxis_title='Y'
)
```
### Update Traces
```python
# Update all traces
fig.update_traces(marker=dict(size=10, opacity=0.7))
# Update with selector
fig.update_traces(
marker=dict(color='red'),
selector=dict(mode='markers', name='Series 1')
)
```
### Update Axes
```python
fig.update_xaxes(showgrid=True, gridcolor='lightgray')
fig.update_yaxes(type='log')
```
## Responsive Design
```python
# Auto-resize to container
fig.update_layout(autosize=True)
# Responsive in HTML
fig.write_html('plot.html', config={'responsive': True})
```

View File

@@ -0,0 +1,213 @@
# Plotly Express - High-Level API
Plotly Express (px) is a high-level interface for creating data visualizations with minimal code (typically 1-5 lines).
## Installation
```bash
uv pip install plotly
```
## Key Advantages
- Concise syntax for common chart types
- Automatic color encoding and legends
- Works seamlessly with pandas DataFrames
- Smart defaults for layout and styling
- Returns graph_objects.Figure for further customization
## Basic Usage Pattern
```python
import plotly.express as px
import pandas as pd
# Most functions follow this pattern
fig = px.chart_type(
data_frame=df,
x="column_x",
y="column_y",
color="category_column", # Auto-color by category
size="size_column", # Size by values
title="Chart Title"
)
fig.show()
```
## 40+ Chart Types
### Basic Charts
- `px.scatter()` - Scatter plots with optional trendlines
- `px.line()` - Line charts for time series
- `px.bar()` - Bar charts (vertical/horizontal)
- `px.area()` - Area charts
- `px.pie()` - Pie charts
### Statistical Charts
- `px.histogram()` - Histograms with automatic binning
- `px.box()` - Box plots for distributions
- `px.violin()` - Violin plots
- `px.strip()` - Strip plots
- `px.ecdf()` - Empirical cumulative distribution
### Maps
- `px.scatter_geo()` - Geographic scatter plots
- `px.choropleth()` - Choropleth maps
- `px.scatter_mapbox()` - Mapbox scatter plots
- `px.density_mapbox()` - Density heatmaps on maps
### Specialized
- `px.sunburst()` - Hierarchical sunburst charts
- `px.treemap()` - Treemap visualizations
- `px.funnel()` - Funnel charts
- `px.parallel_coordinates()` - Parallel coordinates
- `px.scatter_matrix()` - Scatter matrix (SPLOM)
- `px.density_heatmap()` - 2D density heatmaps
- `px.density_contour()` - Density contours
### 3D Charts
- `px.scatter_3d()` - 3D scatter plots
- `px.line_3d()` - 3D line plots
## Common Parameters
All Plotly Express functions support these styling parameters:
```python
fig = px.scatter(
df, x="x", y="y",
# Dimensions
width=800,
height=600,
# Labels
title="Figure Title",
labels={"x": "X Axis", "y": "Y Axis"},
# Colors
color="category",
color_discrete_map={"A": "red", "B": "blue"},
color_continuous_scale="Viridis",
# Ordering
category_orders={"category": ["A", "B", "C"]},
# Theming
template="plotly_dark" # or "simple_white", "seaborn", "ggplot2"
)
```
## Data Format
Plotly Express works with:
- **Long-form data** (tidy): One row per observation
- **Wide-form data**: Multiple columns as separate traces
```python
# Long-form (preferred)
df_long = pd.DataFrame({
'fruit': ['apple', 'orange', 'apple', 'orange'],
'contestant': ['A', 'A', 'B', 'B'],
'count': [1, 3, 2, 4]
})
fig = px.bar(df_long, x='fruit', y='count', color='contestant')
# Wide-form
df_wide = pd.DataFrame({
'fruit': ['apple', 'orange'],
'A': [1, 3],
'B': [2, 4]
})
fig = px.bar(df_wide, x='fruit', y=['A', 'B'])
```
## Trendlines
Add statistical trendlines to scatter plots:
```python
fig = px.scatter(
df, x="x", y="y",
trendline="ols", # "ols", "lowess", "rolling", "ewm", "expanding"
trendline_options=dict(log_x=True) # Additional options
)
```
## Faceting (Subplots)
Create faceted plots automatically:
```python
fig = px.scatter(
df, x="x", y="y",
facet_row="category_1", # Separate rows
facet_col="category_2", # Separate columns
facet_col_wrap=3 # Wrap columns
)
```
## Animation
Create animated visualizations:
```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"
)
```
## Hover Data
Customize hover tooltips:
```python
fig = px.scatter(
df, x="x", y="y",
hover_data={
"extra_col": True, # Add column
"x": ":.2f", # Format existing
"hidden_col": False # Hide column
},
hover_name="name_column" # Bold title in hover
)
```
## Further Customization
Plotly Express returns a `graph_objects.Figure` that can be further customized:
```python
fig = px.scatter(df, x="x", y="y")
# Use graph_objects methods
fig.update_layout(
title="Custom Title",
xaxis_title="X Axis",
font=dict(size=14)
)
fig.update_traces(
marker=dict(size=10, opacity=0.7)
)
fig.add_hline(y=0, line_dash="dash")
```
## When to Use Plotly Express
Use Plotly Express when:
- Creating standard chart types quickly
- Working with pandas DataFrames
- Need automatic color/size encoding
- Want sensible defaults with minimal code
Use graph_objects when:
- Building custom chart types not in px
- Need fine-grained control over every element
- Creating complex multi-trace figures
- Building specialized visualizations