8.9 KiB
8.9 KiB
Layouts, Styling, and Customization
Subplots
Creating Subplots
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
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
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
# 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
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
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
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
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
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
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
# 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
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
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
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
fig.update_layout(
plot_bgcolor='#f0f0f0', # Plot area
paper_bgcolor='white' # Figure background
)
Legend
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
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
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
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
# 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
fig.update_layout(
title='New Title',
xaxis_title='X',
yaxis_title='Y'
)
Update Traces
# 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
fig.update_xaxes(showgrid=True, gridcolor='lightgray')
fig.update_yaxes(type='log')
Responsive Design
# Auto-resize to container
fig.update_layout(autosize=True)
# Responsive in HTML
fig.write_html('plot.html', config={'responsive': True})