How to Set Themes in Seaborn
Seaborn's theming system transforms raw matplotlib plots into publication-ready visualizations with minimal code. Themes control the overall aesthetic of your plots—background colors, grid lines,...
Key Insights
- Seaborn provides five built-in theme styles (
darkgrid,whitegrid,dark,white,ticks) that control plot aesthetics like backgrounds, grids, and borders—distinct from color palettes which only affect data colors - Use
set_theme()for comprehensive styling including context scaling, orset_style()when you only need to change visual elements without affecting font sizes or line widths - The
axes_style()context manager allows temporary theme changes for specific plots without affecting global settings, essential for creating multi-panel figures with different styles
Introduction to Seaborn Themes
Seaborn’s theming system transforms raw matplotlib plots into publication-ready visualizations with minimal code. Themes control the overall aesthetic of your plots—background colors, grid lines, axis spines, and tick marks—while color palettes handle only the colors used to represent your data. This distinction matters because you might want a clean white background (theme) with vibrant categorical colors (palette), or a dark grid (theme) with muted sequential colors (palette).
The default matplotlib style works fine for quick exploration, but it lacks the polish needed for presentations or publications. Seaborn themes solve this by providing carefully designed presets that improve readability and visual appeal.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Generate sample data
np.random.seed(42)
x = np.random.randn(100)
y = 2 * x + np.random.randn(100)
# Plot without Seaborn theme (raw matplotlib)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.scatter(x, y)
plt.title('Default Matplotlib Style')
plt.xlabel('X Variable')
plt.ylabel('Y Variable')
# Plot with Seaborn theme
plt.subplot(1, 2, 2)
sns.set_theme()
sns.scatterplot(x=x, y=y)
plt.title('With Seaborn Theme')
plt.xlabel('X Variable')
plt.ylabel('Y Variable')
plt.tight_layout()
plt.show()
The difference is immediately apparent. The Seaborn version has better default colors, appropriate grid lines, and improved typography.
Built-in Theme Styles
Seaborn offers five preset themes, each suited for different visualization contexts:
darkgrid: Gray background with white grid lines. Best for dense plots where you need reference lines to read values accurately. Ideal for presentations on projectors where the contrast helps visibility.
whitegrid: White background with gray grid lines. The most versatile option, suitable for most business and academic contexts. Provides reference lines without overwhelming the data.
dark: Gray background without grid lines. Use when you want a modern look and your data doesn’t require precise value reading. Works well for trend visualization.
white: Clean white background without grids. Perfect for publications and reports where minimalism is valued. Best when your data patterns are clear without reference lines.
ticks: White background with tick marks only (no grids or spines except bottom and left). The most minimal option, ideal for high-impact visualizations where you want maximum focus on the data itself.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Create sample data
data = pd.DataFrame({
'x': range(20),
'y': [2*i + np.random.randn()*3 for i in range(20)]
})
styles = ['darkgrid', 'whitegrid', 'dark', 'white', 'ticks']
fig, axes = plt.subplots(2, 3, figsize=(15, 8))
axes = axes.flatten()
for idx, style in enumerate(styles):
sns.set_style(style)
plt.sca(axes[idx])
sns.lineplot(data=data, x='x', y='y', marker='o')
axes[idx].set_title(f'Style: {style}', fontsize=14, fontweight='bold')
# Hide the extra subplot
axes[-1].axis('off')
plt.tight_layout()
plt.show()
Setting Themes with set_theme() and set_style()
Seaborn provides two primary functions for applying themes, and understanding their difference prevents confusion.
set_theme() is the comprehensive option. It sets the style, context (scaling), palette, and matplotlib rcParams all at once. Use this when you want complete control over your visualization environment.
set_style() only changes the visual style elements—background, grids, spines. It doesn’t affect font sizes, line widths, or other scaling parameters. Use this when you’ve already set your context and just want to switch the visual appearance.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Using set_theme() - comprehensive approach
sns.set_theme(style='darkgrid', context='notebook', palette='deep')
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# First plot uses the theme settings
axes[0].plot(np.random.randn(50).cumsum())
axes[0].set_title('Using set_theme()')
# Using set_style() - style only
sns.set_style('whitegrid')
axes[1].plot(np.random.randn(50).cumsum())
axes[1].set_title('Using set_style()')
plt.tight_layout()
plt.show()
The key difference: set_theme() resets everything, while set_style() preserves your existing context and palette settings.
Customizing Theme Parameters
The real power comes from customizing themes to match your specific needs. Both set_theme() and set_style() accept an rc parameter that lets you override specific matplotlib rcParams.
Common customizations include grid line styles, spine visibility, and tick parameters. You can also pass a dictionary directly to modify multiple parameters at once.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Custom theme with modified parameters
custom_params = {
'axes.grid': True,
'grid.linestyle': '--',
'grid.linewidth': 0.5,
'grid.alpha': 0.7,
'axes.spines.top': False,
'axes.spines.right': False,
'axes.linewidth': 1.5
}
sns.set_theme(style='white', rc=custom_params)
# Create visualization
fig, ax = plt.subplots(figsize=(10, 6))
data = pd.DataFrame({
'Month': range(1, 13),
'Revenue': np.random.randint(50, 150, 12)
})
sns.barplot(data=data, x='Month', y='Revenue', ax=ax)
ax.set_title('Monthly Revenue with Custom Theme', fontsize=16, fontweight='bold')
ax.set_xlabel('Month', fontsize=12)
ax.set_ylabel('Revenue ($K)', fontsize=12)
plt.tight_layout()
plt.show()
This approach gives you the clean aesthetics of Seaborn themes while maintaining full control over specific visual elements.
Context-Specific Themes
Sometimes you need different themes for different plots in the same figure. The axes_style() context manager provides temporary theme changes that don’t affect your global settings.
This is particularly useful for creating complex multi-panel figures where different subplots benefit from different styling approaches.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Set a default theme
sns.set_theme(style='white')
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# First plot uses default theme
axes[0].plot(np.random.randn(50).cumsum())
axes[0].set_title('Default (white)')
# Second plot temporarily uses darkgrid
with sns.axes_style('darkgrid'):
axes[1].plot(np.random.randn(50).cumsum())
axes[1].set_title('Temporary (darkgrid)')
# Third plot reverts to default theme
axes[2].plot(np.random.randn(50).cumsum())
axes[2].set_title('Back to default (white)')
plt.tight_layout()
plt.show()
The context manager ensures your theme changes are scoped appropriately, preventing unintended side effects in other parts of your code.
Combining Themes with Context and Palettes
The most powerful approach combines themes, contexts, and palettes in a single set_theme() call. Context controls the scale of plot elements (paper, notebook, talk, poster), while palettes define your color scheme.
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Comprehensive theme setup for a presentation
sns.set_theme(
style='ticks',
context='talk', # Larger fonts and elements for presentations
palette='Set2', # Colorblind-friendly palette
rc={
'figure.figsize': (12, 6),
'axes.spines.top': False,
'axes.spines.right': False
}
)
# Create a complex visualization
tips = sns.load_dataset('tips')
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.boxplot(data=tips, x='day', y='total_bill', ax=axes[0])
axes[0].set_title('Daily Bill Distribution')
sns.scatterplot(data=tips, x='total_bill', y='tip', hue='time', ax=axes[1])
axes[1].set_title('Bill vs Tip by Time')
plt.tight_layout()
plt.show()
This configuration creates presentation-ready plots with appropriate scaling, clean styling, and accessible colors—all in one function call.
Best Practices and Common Patterns
Choose themes based on your output medium. For academic papers, use white or ticks with context='paper'. For presentations, use whitegrid or darkgrid with context='talk'. For dashboards, whitegrid with context='notebook' provides the best balance.
Always consider your audience. If presenting to colorblind individuals, combine your theme with colorblind-friendly palettes like 'colorblind' or 'Set2'.
Reset themes between different visualization sections using sns.reset_defaults() or sns.reset_orig() to avoid theme pollution across your codebase.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Before: Default styling
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
axes[0].scatter(np.random.randn(100), np.random.randn(100))
axes[0].set_title('Before: Default Styling')
# After: Publication-ready theme
sns.set_theme(
style='ticks',
context='paper',
palette='colorblind',
rc={
'figure.dpi': 300,
'savefig.dpi': 300,
'font.size': 10,
'axes.labelsize': 11,
'axes.titlesize': 12,
'xtick.labelsize': 9,
'ytick.labelsize': 9,
'legend.fontsize': 9
}
)
axes[1].scatter(np.random.randn(100), np.random.randn(100))
axes[1].set_title('After: Publication-Ready')
plt.tight_layout()
plt.show()
The optimized version includes higher DPI for crisp printing, appropriate font sizes for publications, and a colorblind-safe palette. These small adjustments make the difference between amateur and professional visualizations.
Master Seaborn’s theming system and you’ll spend less time tweaking individual plot elements and more time analyzing your data. The key is understanding which function to use (set_theme() vs set_style() vs axes_style()), choosing appropriate presets for your context, and knowing when to apply custom parameters for that final polish.