
Scientific Visualization
- 45 installs
- 16 repo stars
- Updated November 20, 2025
- jackspace/claudeskillz
This is a copy of scientific-visualization by davila7 - installs and ranking accrue to the original listing.
Helps with ai & agent building tasks.
About
scientific-visualization is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- scientific-visualization
- AI & Agent Building
- AI-coding skill
Scientific Visualization by the numbers
- 45 all-time installs (skills.sh)
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jackspace/claudeskillz --skill scientific-visualizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 45 |
|---|---|
| repo stars | ★ 16 |
| Last updated | November 20, 2025 |
| Repository | jackspace/claudeskillz ↗ |
What it does
Helps with ai & agent building tasks.
Files
Scientific Visualization
Overview
Scientific visualization transforms data into clear, accurate figures for publication. Create journal-ready plots with multi-panel layouts, error bars, significance markers, and colorblind-safe palettes. Export as PDF/EPS/TIFF using matplotlib, seaborn, and plotly for manuscripts.
When to Use This Skill
This skill should be used when:
- Creating plots or visualizations for scientific manuscripts
- Preparing figures for journal submission (Nature, Science, Cell, PLOS, etc.)
- Ensuring figures are colorblind-friendly and accessible
- Making multi-panel figures with consistent styling
- Exporting figures at correct resolution and format
- Following specific publication guidelines
- Improving existing figures to meet publication standards
- Creating figures that need to work in both color and grayscale
Quick Start Guide
Basic Publication-Quality Figure
import matplotlib.pyplot as plt
import numpy as np
# Apply publication style (from scripts/style_presets.py)
from style_presets import apply_publication_style
apply_publication_style('default')
# Create figure with appropriate size (single column = 3.5 inches)
fig, ax = plt.subplots(figsize=(3.5, 2.5))
# Plot data
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
# Proper labeling with units
ax.set_xlabel('Time (seconds)')
ax.set_ylabel('Amplitude (mV)')
ax.legend(frameon=False)
# Remove unnecessary spines
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Save in publication formats (from scripts/figure_export.py)
from figure_export import save_publication_figure
save_publication_figure(fig, 'figure1', formats=['pdf', 'png'], dpi=300)Using Pre-configured Styles
Apply journal-specific styles using the matplotlib style files in assets/:
import matplotlib.pyplot as plt
# Option 1: Use style file directly
plt.style.use('assets/nature.mplstyle')
# Option 2: Use style_presets.py helper
from style_presets import configure_for_journal
configure_for_journal('nature', figure_width='single')
# Now create figures - they'll automatically match Nature specifications
fig, ax = plt.subplots()
# ... your plotting code ...Quick Start with Seaborn
For statistical plots, use seaborn with publication styling:
import seaborn as sns
import matplotlib.pyplot as plt
from style_presets import apply_publication_style
# Apply publication style
apply_publication_style('default')
sns.set_theme(style='ticks', context='paper', font_scale=1.1)
sns.set_palette('colorblind')
# Create statistical comparison figure
fig, ax = plt.subplots(figsize=(3.5, 3))
sns.boxplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'], palette='Set2', ax=ax)
sns.stripplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'],
color='black', alpha=0.3, size=3, ax=ax)
ax.set_ylabel('Response (μM)')
sns.despine()
# Save figure
from figure_export import save_publication_figure
save_publication_figure(fig, 'treatment_comparison', formats=['pdf', 'png'], dpi=300)Core Principles and Best Practices
1. Resolution and File Format
Critical requirements (detailed in references/publication_guidelines.md):
- Raster images (photos, microscopy): 300-600 DPI
- Line art (graphs, plots): 600-1200 DPI or vector format
- Vector formats (preferred): PDF, EPS, SVG
- Raster formats: TIFF, PNG (never JPEG for scientific data)
Implementation:
# Use the figure_export.py script for correct settings
from figure_export import save_publication_figure
# Saves in multiple formats with proper DPI
save_publication_figure(fig, 'myfigure', formats=['pdf', 'png'], dpi=300)
# Or save for specific journal requirements
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', journal='nature', figure_type='combination')2. Color Selection - Colorblind Accessibility
Always use colorblind-friendly palettes (detailed in references/color_palettes.md):
Recommended: Okabe-Ito palette (distinguishable by all types of color blindness):
# Option 1: Use assets/color_palettes.py
from color_palettes import OKABE_ITO_LIST, apply_palette
apply_palette('okabe_ito')
# Option 2: Manual specification
okabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',
'#0072B2', '#D55E00', '#CC79A7', '#000000']
plt.rcParams['axes.prop_cycle'] = plt.cycler(color=okabe_ito)For heatmaps/continuous data:
- Use perceptually uniform colormaps:
viridis,plasma,cividis - Avoid red-green diverging maps (use
PuOr,RdBu,BrBGinstead) - Never use
jetorrainbowcolormaps
Always test figures in grayscale to ensure interpretability.
3. Typography and Text
Font guidelines (detailed in references/publication_guidelines.md):
- Sans-serif fonts: Arial, Helvetica, Calibri
- Minimum sizes at final print size:
- Axis labels: 7-9 pt
- Tick labels: 6-8 pt
- Panel labels: 8-12 pt (bold)
- Sentence case for labels: "Time (hours)" not "TIME (HOURS)"
- Always include units in parentheses
Implementation:
# Set fonts globally
import matplotlib as mpl
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = ['Arial', 'Helvetica']
mpl.rcParams['font.size'] = 8
mpl.rcParams['axes.labelsize'] = 9
mpl.rcParams['xtick.labelsize'] = 7
mpl.rcParams['ytick.labelsize'] = 74. Figure Dimensions
Journal-specific widths (detailed in references/journal_requirements.md):
- Nature: Single 89 mm, Double 183 mm
- Science: Single 55 mm, Double 175 mm
- Cell: Single 85 mm, Double 178 mm
Check figure size compliance:
from figure_export import check_figure_size
fig = plt.figure(figsize=(3.5, 3)) # 89 mm for Nature
check_figure_size(fig, journal='nature')5. Multi-Panel Figures
Best practices:
- Label panels with bold letters: A, B, C (uppercase for most journals, lowercase for Nature)
- Maintain consistent styling across all panels
- Align panels along edges where possible
- Use adequate white space between panels
Example implementation (see references/matplotlib_examples.md for complete code):
from string import ascii_uppercase
fig = plt.figure(figsize=(7, 4))
gs = fig.add_gridspec(2, 2, hspace=0.4, wspace=0.4)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
# ... create other panels ...
# Add panel labels
for i, ax in enumerate([ax1, ax2, ...]):
ax.text(-0.15, 1.05, ascii_uppercase[i], transform=ax.transAxes,
fontsize=10, fontweight='bold', va='top')Common Tasks
Task 1: Create a Publication-Ready Line Plot
See references/matplotlib_examples.md Example 1 for complete code.
Key steps: 1. Apply publication style 2. Set appropriate figure size for target journal 3. Use colorblind-friendly colors 4. Add error bars with correct representation (SEM, SD, or CI) 5. Label axes with units 6. Remove unnecessary spines 7. Save in vector format
Using seaborn for automatic confidence intervals:
import seaborn as sns
fig, ax = plt.subplots(figsize=(5, 3))
sns.lineplot(data=timeseries, x='time', y='measurement',
hue='treatment', errorbar=('ci', 95),
markers=True, ax=ax)
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Measurement (AU)')
sns.despine()Task 2: Create a Multi-Panel Figure
See references/matplotlib_examples.md Example 2 for complete code.
Key steps: 1. Use GridSpec for flexible layout 2. Ensure consistent styling across panels 3. Add bold panel labels (A, B, C, etc.) 4. Align related panels 5. Verify all text is readable at final size
Task 3: Create a Heatmap with Proper Colormap
See references/matplotlib_examples.md Example 4 for complete code.
Key steps: 1. Use perceptually uniform colormap (viridis, plasma, cividis) 2. Include labeled colorbar 3. For diverging data, use colorblind-safe diverging map (RdBu_r, PuOr) 4. Set appropriate center value for diverging maps 5. Test appearance in grayscale
Using seaborn for correlation matrices:
import seaborn as sns
fig, ax = plt.subplots(figsize=(5, 4))
corr = df.corr()
mask = np.triu(np.ones_like(corr, dtype=bool))
sns.heatmap(corr, mask=mask, annot=True, fmt='.2f',
cmap='RdBu_r', center=0, square=True,
linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)Task 4: Prepare Figure for Specific Journal
Workflow: 1. Check journal requirements: references/journal_requirements.md 2. Configure matplotlib for journal:
from style_presets import configure_for_journal
configure_for_journal('nature', figure_width='single')3. Create figure (will auto-size correctly) 4. Export with journal specifications:
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', journal='nature', figure_type='line_art')Task 5: Fix an Existing Figure to Meet Publication Standards
Checklist approach (full checklist in references/publication_guidelines.md):
1. Check resolution: Verify DPI meets journal requirements 2. Check file format: Use vector for plots, TIFF/PNG for images 3. Check colors: Ensure colorblind-friendly 4. Check fonts: Minimum 6-7 pt at final size, sans-serif 5. Check labels: All axes labeled with units 6. Check size: Matches journal column width 7. Test grayscale: Figure interpretable without color 8. Remove chart junk: No unnecessary grids, 3D effects, shadows
Task 6: Create Colorblind-Friendly Visualizations
Strategy: 1. Use approved palettes from assets/color_palettes.py 2. Add redundant encoding (line styles, markers, patterns) 3. Test with colorblind simulator 4. Ensure grayscale compatibility
Example:
from color_palettes import apply_palette
import matplotlib.pyplot as plt
apply_palette('okabe_ito')
# Add redundant encoding beyond color
line_styles = ['-', '--', '-.', ':']
markers = ['o', 's', '^', 'v']
for i, (data, label) in enumerate(datasets):
plt.plot(x, data, linestyle=line_styles[i % 4],
marker=markers[i % 4], label=label)Statistical Rigor
Always include:
- Error bars (SD, SEM, or CI - specify which in caption)
- Sample size (n) in figure or caption
- Statistical significance markers (, , **)
- Individual data points when possible (not just summary statistics)
Example with statistics:
# Show individual points with summary statistics
ax.scatter(x_jittered, individual_points, alpha=0.4, s=8)
ax.errorbar(x, means, yerr=sems, fmt='o', capsize=3)
# Mark significance
ax.text(1.5, max_y * 1.1, '***', ha='center', fontsize=8)Working with Different Plotting Libraries
Matplotlib
- Most control over publication details
- Best for complex multi-panel figures
- Use provided style files for consistent formatting
- See
references/matplotlib_examples.mdfor extensive examples
Seaborn
Seaborn provides a high-level, dataset-oriented interface for statistical graphics, built on matplotlib. It excels at creating publication-quality statistical visualizations with minimal code while maintaining full compatibility with matplotlib customization.
Key advantages for scientific visualization:
- Automatic statistical estimation and confidence intervals
- Built-in support for multi-panel figures (faceting)
- Colorblind-friendly palettes by default
- Dataset-oriented API using pandas DataFrames
- Semantic mapping of variables to visual properties
Quick Start with Publication Style
Always apply matplotlib publication styles first, then configure seaborn:
import seaborn as sns
import matplotlib.pyplot as plt
from style_presets import apply_publication_style
# Apply publication style
apply_publication_style('default')
# Configure seaborn for publication
sns.set_theme(style='ticks', context='paper', font_scale=1.1)
sns.set_palette('colorblind') # Use colorblind-safe palette
# Create figure
fig, ax = plt.subplots(figsize=(3.5, 2.5))
sns.scatterplot(data=df, x='time', y='response',
hue='treatment', style='condition', ax=ax)
sns.despine() # Remove top and right spinesCommon Plot Types for Publications
Statistical comparisons:
# Box plot with individual points for transparency
fig, ax = plt.subplots(figsize=(3.5, 3))
sns.boxplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'], palette='Set2', ax=ax)
sns.stripplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'],
color='black', alpha=0.3, size=3, ax=ax)
ax.set_ylabel('Response (μM)')
sns.despine()Distribution analysis:
# Violin plot with split comparison
fig, ax = plt.subplots(figsize=(4, 3))
sns.violinplot(data=df, x='timepoint', y='expression',
hue='treatment', split=True, inner='quartile', ax=ax)
ax.set_ylabel('Gene Expression (AU)')
sns.despine()Correlation matrices:
# Heatmap with proper colormap and annotations
fig, ax = plt.subplots(figsize=(5, 4))
corr = df.corr()
mask = np.triu(np.ones_like(corr, dtype=bool)) # Show only lower triangle
sns.heatmap(corr, mask=mask, annot=True, fmt='.2f',
cmap='RdBu_r', center=0, square=True,
linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)
plt.tight_layout()Time series with confidence bands:
# Line plot with automatic CI calculation
fig, ax = plt.subplots(figsize=(5, 3))
sns.lineplot(data=timeseries, x='time', y='measurement',
hue='treatment', style='replicate',
errorbar=('ci', 95), markers=True, dashes=False, ax=ax)
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Measurement (AU)')
sns.despine()Multi-Panel Figures with Seaborn
Using FacetGrid for automatic faceting:
# Create faceted plot
g = sns.relplot(data=df, x='dose', y='response',
hue='treatment', col='cell_line', row='timepoint',
kind='line', height=2.5, aspect=1.2,
errorbar=('ci', 95), markers=True)
g.set_axis_labels('Dose (μM)', 'Response (AU)')
g.set_titles('{row_name} | {col_name}')
sns.despine()
# Save with correct DPI
from figure_export import save_publication_figure
save_publication_figure(g.figure, 'figure_facets',
formats=['pdf', 'png'], dpi=300)Combining seaborn with matplotlib subplots:
# Create custom multi-panel layout
fig, axes = plt.subplots(2, 2, figsize=(7, 6))
# Panel A: Scatter with regression
sns.regplot(data=df, x='predictor', y='response', ax=axes[0, 0])
axes[0, 0].text(-0.15, 1.05, 'A', transform=axes[0, 0].transAxes,
fontsize=10, fontweight='bold')
# Panel B: Distribution comparison
sns.violinplot(data=df, x='group', y='value', ax=axes[0, 1])
axes[0, 1].text(-0.15, 1.05, 'B', transform=axes[0, 1].transAxes,
fontsize=10, fontweight='bold')
# Panel C: Heatmap
sns.heatmap(correlation_data, cmap='viridis', ax=axes[1, 0])
axes[1, 0].text(-0.15, 1.05, 'C', transform=axes[1, 0].transAxes,
fontsize=10, fontweight='bold')
# Panel D: Time series
sns.lineplot(data=timeseries, x='time', y='signal',
hue='condition', ax=axes[1, 1])
axes[1, 1].text(-0.15, 1.05, 'D', transform=axes[1, 1].transAxes,
fontsize=10, fontweight='bold')
plt.tight_layout()
sns.despine()Color Palettes for Publications
Seaborn includes several colorblind-safe palettes:
# Use built-in colorblind palette (recommended)
sns.set_palette('colorblind')
# Or specify custom colorblind-safe colors (Okabe-Ito)
okabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',
'#0072B2', '#D55E00', '#CC79A7', '#000000']
sns.set_palette(okabe_ito)
# For heatmaps and continuous data
sns.heatmap(data, cmap='viridis') # Perceptually uniform
sns.heatmap(corr, cmap='RdBu_r', center=0) # Diverging, centeredChoosing Between Axes-Level and Figure-Level Functions
Axes-level functions (e.g., scatterplot, boxplot, heatmap):
- Use when building custom multi-panel layouts
- Accept
ax=parameter for precise placement - Better integration with matplotlib subplots
- More control over figure composition
fig, ax = plt.subplots(figsize=(3.5, 2.5))
sns.scatterplot(data=df, x='x', y='y', hue='group', ax=ax)Figure-level functions (e.g., relplot, catplot, displot):
- Use for automatic faceting by categorical variables
- Create complete figures with consistent styling
- Great for exploratory analysis
- Use
heightandaspectfor sizing
g = sns.relplot(data=df, x='x', y='y', col='category', kind='scatter')Statistical Rigor with Seaborn
Seaborn automatically computes and displays uncertainty:
# Line plot: shows mean ± 95% CI by default
sns.lineplot(data=df, x='time', y='value', hue='treatment',
errorbar=('ci', 95)) # Can change to 'sd', 'se', etc.
# Bar plot: shows mean with bootstrapped CI
sns.barplot(data=df, x='treatment', y='response',
errorbar=('ci', 95), capsize=0.1)
# Always specify error type in figure caption:
# "Error bars represent 95% confidence intervals"Best Practices for Publication-Ready Seaborn Figures
1. Always set publication theme first:
sns.set_theme(style='ticks', context='paper', font_scale=1.1)2. Use colorblind-safe palettes:
sns.set_palette('colorblind')3. Remove unnecessary elements:
sns.despine() # Remove top and right spines4. Control figure size appropriately:
# Axes-level: use matplotlib figsize
fig, ax = plt.subplots(figsize=(3.5, 2.5))
# Figure-level: use height and aspect
g = sns.relplot(..., height=3, aspect=1.2)5. Show individual data points when possible:
sns.boxplot(...) # Summary statistics
sns.stripplot(..., alpha=0.3) # Individual points6. Include proper labels with units:
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Expression (AU)')7. Export at correct resolution:
from figure_export import save_publication_figure
save_publication_figure(fig, 'figure_name',
formats=['pdf', 'png'], dpi=300)Advanced Seaborn Techniques
Pairwise relationships for exploratory analysis:
# Quick overview of all relationships
g = sns.pairplot(data=df, hue='condition',
vars=['gene1', 'gene2', 'gene3'],
corner=True, diag_kind='kde', height=2)Hierarchical clustering heatmap:
# Cluster samples and features
g = sns.clustermap(expression_data, method='ward',
metric='euclidean', z_score=0,
cmap='RdBu_r', center=0,
figsize=(10, 8),
row_colors=condition_colors,
cbar_kws={'label': 'Z-score'})Joint distributions with marginals:
# Bivariate distribution with context
g = sns.jointplot(data=df, x='gene1', y='gene2',
hue='treatment', kind='scatter',
height=6, ratio=4, marginal_kws={'kde': True})Common Seaborn Issues and Solutions
Issue: Legend outside plot area
g = sns.relplot(...)
g._legend.set_bbox_to_anchor((0.9, 0.5))Issue: Overlapping labels
plt.xticks(rotation=45, ha='right')
plt.tight_layout()Issue: Text too small at final size
sns.set_context('paper', font_scale=1.2) # Increase if neededAdditional Resources
For more detailed seaborn information, see:
scientific-packages/seaborn/SKILL.md- Comprehensive seaborn documentationscientific-packages/seaborn/references/examples.md- Practical use casesscientific-packages/seaborn/references/function_reference.md- Complete API referencescientific-packages/seaborn/references/objects_interface.md- Modern declarative API
Plotly
- Interactive figures for exploration
- Export static images for publication
- Configure for publication quality:
fig.update_layout(
font=dict(family='Arial, sans-serif', size=10),
plot_bgcolor='white',
# ... see matplotlib_examples.md Example 8
)
fig.write_image('figure.png', scale=3) # scale=3 gives ~300 DPIResources
References Directory
Load these as needed for detailed information:
- `publication_guidelines.md`: Comprehensive best practices
- Resolution and file format requirements
- Typography guidelines
- Layout and composition rules
- Statistical rigor requirements
- Complete publication checklist
- `color_palettes.md`: Color usage guide
- Colorblind-friendly palette specifications with RGB values
- Sequential and diverging colormap recommendations
- Testing procedures for accessibility
- Domain-specific palettes (genomics, microscopy)
- `journal_requirements.md`: Journal-specific specifications
- Technical requirements by publisher
- File format and DPI specifications
- Figure dimension requirements
- Quick reference table
- `matplotlib_examples.md`: Practical code examples
- 10 complete working examples
- Line plots, bar plots, heatmaps, multi-panel figures
- Journal-specific figure examples
- Tips for each library (matplotlib, seaborn, plotly)
Scripts Directory
Use these helper scripts for automation:
- `figure_export.py`: Export utilities
save_publication_figure(): Save in multiple formats with correct DPIsave_for_journal(): Use journal-specific requirements automaticallycheck_figure_size(): Verify dimensions meet journal specs- Run directly:
python scripts/figure_export.pyfor examples
- `style_presets.py`: Pre-configured styles
apply_publication_style(): Apply preset styles (default, nature, science, cell)set_color_palette(): Quick palette switchingconfigure_for_journal(): One-command journal configuration- Run directly:
python scripts/style_presets.pyto see examples
Assets Directory
Use these files in figures:
- `color_palettes.py`: Importable color definitions
- All recommended palettes as Python constants
apply_palette()helper function- Can be imported directly into notebooks/scripts
- Matplotlib style files: Use with
plt.style.use() publication.mplstyle: General publication qualitynature.mplstyle: Nature journal specificationspresentation.mplstyle: Larger fonts for posters/slides
Workflow Summary
Recommended workflow for creating publication figures:
1. Plan: Determine target journal, figure type, and content 2. Configure: Apply appropriate style for journal
from style_presets import configure_for_journal
configure_for_journal('nature', 'single')3. Create: Build figure with proper labels, colors, statistics 4. Verify: Check size, fonts, colors, accessibility
from figure_export import check_figure_size
check_figure_size(fig, journal='nature')5. Export: Save in required formats
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', 'nature', 'combination')6. Review: View at final size in manuscript context
Common Pitfalls to Avoid
1. Font too small: Text unreadable when printed at final size 2. JPEG format: Never use JPEG for graphs/plots (creates artifacts) 3. Red-green colors: ~8% of males cannot distinguish 4. Low resolution: Pixelated figures in publication 5. Missing units: Always label axes with units 6. 3D effects: Distorts perception, avoid completely 7. Chart junk: Remove unnecessary gridlines, decorations 8. Truncated axes: Start bar charts at zero unless scientifically justified 9. Inconsistent styling: Different fonts/colors across figures in same manuscript 10. No error bars: Always show uncertainty
Final Checklist
Before submitting figures, verify:
- [ ] Resolution meets journal requirements (300+ DPI)
- [ ] File format is correct (vector for plots, TIFF for images)
- [ ] Figure size matches journal specifications
- [ ] All text readable at final size (≥6 pt)
- [ ] Colors are colorblind-friendly
- [ ] Figure works in grayscale
- [ ] All axes labeled with units
- [ ] Error bars present with definition in caption
- [ ] Panel labels present and consistent
- [ ] No chart junk or 3D effects
- [ ] Fonts consistent across all figures
- [ ] Statistical significance clearly marked
- [ ] Legend is clear and complete
Use this skill to ensure scientific figures meet the highest publication standards while remaining accessible to all readers.
{
"description": "\"Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, significance markers, colorblind-safe, export PDF/EPS/TIFF, for journal-ready scientific plots.\"",
"references": {
"files": [
"references/color_palettes.md",
"references/journal_requirements.md",
"references/matplotlib_examples.md",
"references/publication_guidelines.md"
]
},
"content": "### Basic Publication-Quality Figure\r\n\r\n```python\r\nimport matplotlib.pyplot as plt\r\nimport numpy as np\r\n\r\nfrom style_presets import apply_publication_style\r\napply_publication_style('default')\r\n\r\nfig, ax = plt.subplots(figsize=(3.5, 2.5))\r\n\r\nx = np.linspace(0, 10, 100)\r\nax.plot(x, np.sin(x), label='sin(x)')\r\nax.plot(x, np.cos(x), label='cos(x)')\r\n\r\nax.set_xlabel('Time (seconds)')\r\nax.set_ylabel('Amplitude (mV)')\r\nax.legend(frameon=False)\r\n\r\nax.spines['top'].set_visible(False)\r\nax.spines['right'].set_visible(False)\r\n\r\nfrom figure_export import save_publication_figure\r\nsave_publication_figure(fig, 'figure1', formats=['pdf', 'png'], dpi=300)\r\n```\r\n\r\n### Using Pre-configured Styles\r\n\r\nApply journal-specific styles using the matplotlib style files in `assets/`:\r\n\r\n```python\r\nimport matplotlib.pyplot as plt\r\n\r\nplt.style.use('assets/nature.mplstyle')\r\n\r\nfrom style_presets import configure_for_journal\r\nconfigure_for_journal('nature', figure_width='single')\r\n\r\nfig, ax = plt.subplots()\r\n```\r\n\r\n### Quick Start with Seaborn\r\n\r\nFor statistical plots, use seaborn with publication styling:\r\n\r\n```python\r\nimport seaborn as sns\r\nimport matplotlib.pyplot as plt\r\nfrom style_presets import apply_publication_style\r\n\r\napply_publication_style('default')\r\nsns.set_theme(style='ticks', context='paper', font_scale=1.1)\r\nsns.set_palette('colorblind')\r\n\r\nfig, ax = plt.subplots(figsize=(3.5, 3))\r\nsns.boxplot(data=df, x='treatment', y='response', \r\n order=['Control', 'Low', 'High'], palette='Set2', ax=ax)\r\nsns.stripplot(data=df, x='treatment', y='response',\r\n order=['Control', 'Low', 'High'], \r\n color='black', alpha=0.3, size=3, ax=ax)\r\nax.set_ylabel('Response (μM)')\r\nsns.despine()\r\n\r\n\r\n### 1. Resolution and File Format\r\n\r\n**Critical requirements** (detailed in `references/publication_guidelines.md`):\r\n- **Raster images** (photos, microscopy): 300-600 DPI\r\n- **Line art** (graphs, plots): 600-1200 DPI or vector format\r\n- **Vector formats** (preferred): PDF, EPS, SVG\r\n- **Raster formats**: TIFF, PNG (never JPEG for scientific data)\r\n\r\n**Implementation:**\r\n```python\r\nfrom figure_export import save_publication_figure\r\n\r\nsave_publication_figure(fig, 'myfigure', formats=['pdf', 'png'], dpi=300)\r\n\r\nfrom figure_export import save_for_journal\r\nsave_for_journal(fig, 'figure1', journal='nature', figure_type='combination')\r\n```\r\n\r\n### 2. Color Selection - Colorblind Accessibility\r\n\r\n**Always use colorblind-friendly palettes** (detailed in `references/color_palettes.md`):\r\n\r\n**Recommended: Okabe-Ito palette** (distinguishable by all types of color blindness):\r\n```python\r\nfrom color_palettes import OKABE_ITO_LIST, apply_palette\r\napply_palette('okabe_ito')\r\n\r\nokabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',\r\n '#0072B2', '#D55E00', '#CC79A7', '#000000']\r\nplt.rcParams['axes.prop_cycle'] = plt.cycler(color=okabe_ito)\r\n```\r\n\r\n**For heatmaps/continuous data:**\r\n- Use perceptually uniform colormaps: `viridis`, `plasma`, `cividis`\r\n- Avoid red-green diverging maps (use `PuOr`, `RdBu`, `BrBG` instead)\r\n- Never use `jet` or `rainbow` colormaps\r\n\r\n**Always test figures in grayscale** to ensure interpretability.\r\n\r\n### 3. Typography and Text\r\n\r\n**Font guidelines** (detailed in `references/publication_guidelines.md`):\r\n- Sans-serif fonts: Arial, Helvetica, Calibri\r\n- Minimum sizes at **final print size**:\r\n - Axis labels: 7-9 pt\r\n - Tick labels: 6-8 pt\r\n - Panel labels: 8-12 pt (bold)\r\n- Sentence case for labels: \"Time (hours)\" not \"TIME (HOURS)\"\r\n- Always include units in parentheses\r\n\r\n**Implementation:**\r\n```python\r\nimport matplotlib as mpl\r\nmpl.rcParams['font.family'] = 'sans-serif'\r\nmpl.rcParams['font.sans-serif'] = ['Arial', 'Helvetica']\r\nmpl.rcParams['font.size'] = 8\r\nmpl.rcParams['axes.labelsize'] = 9\r\nmpl.rcParams['xtick.labelsize'] = 7\r\nmpl.rcParams['ytick.labelsize'] = 7\r\n```\r\n\r\n### 4. Figure Dimensions\r\n\r\n**Journal-specific widths** (detailed in `references/journal_requirements.md`):\r\n- **Nature**: Single 89 mm, Double 183 mm\r\n- **Science**: Single 55 mm, Double 175 mm\r\n- **Cell**: Single 85 mm, Double 178 mm\r\n\r\n**Check figure size compliance:**\r\n```python\r\nfrom figure_export import check_figure_size\r\n\r\nfig = plt.figure(figsize=(3.5, 3)) # 89 mm for Nature\r\ncheck_figure_size(fig, journal='nature')\r\n```\r\n\r\n### 5. Multi-Panel Figures\r\n\r\n**Best practices:**\r\n- Label panels with bold letters: **A**, **B**, **C** (uppercase for most journals, lowercase for Nature)\r\n- Maintain consistent styling across all panels\r\n- Align panels along edges where possible\r\n- Use adequate white space between panels\r\n\r\n**Example implementation** (see `references/matplotlib_examples.md` for complete code):\r\n```python\r\nfrom string import ascii_uppercase\r\n\r\nfig = plt.figure(figsize=(7, 4))\r\ngs = fig.add_gridspec(2, 2, hspace=0.4, wspace=0.4)\r\n\r\nax1 = fig.add_subplot(gs[0, 0])\r\nax2 = fig.add_subplot(gs[0, 1])\r\n\r\n\r\n### Task 1: Create a Publication-Ready Line Plot\r\n\r\nSee `references/matplotlib_examples.md` Example 1 for complete code.\r\n\r\n**Key steps:**\r\n1. Apply publication style\r\n2. Set appropriate figure size for target journal\r\n3. Use colorblind-friendly colors\r\n4. Add error bars with correct representation (SEM, SD, or CI)\r\n5. Label axes with units\r\n6. Remove unnecessary spines\r\n7. Save in vector format\r\n\r\n**Using seaborn for automatic confidence intervals:**\r\n```python\r\nimport seaborn as sns\r\nfig, ax = plt.subplots(figsize=(5, 3))\r\nsns.lineplot(data=timeseries, x='time', y='measurement',\r\n hue='treatment', errorbar=('ci', 95), \r\n markers=True, ax=ax)\r\nax.set_xlabel('Time (hours)')\r\nax.set_ylabel('Measurement (AU)')\r\nsns.despine()\r\n```\r\n\r\n### Task 2: Create a Multi-Panel Figure\r\n\r\nSee `references/matplotlib_examples.md` Example 2 for complete code.\r\n\r\n**Key steps:**\r\n1. Use `GridSpec` for flexible layout\r\n2. Ensure consistent styling across panels\r\n3. Add bold panel labels (A, B, C, etc.)\r\n4. Align related panels\r\n5. Verify all text is readable at final size\r\n\r\n### Task 3: Create a Heatmap with Proper Colormap\r\n\r\nSee `references/matplotlib_examples.md` Example 4 for complete code.\r\n\r\n**Key steps:**\r\n1. Use perceptually uniform colormap (`viridis`, `plasma`, `cividis`)\r\n2. Include labeled colorbar\r\n3. For diverging data, use colorblind-safe diverging map (`RdBu_r`, `PuOr`)\r\n4. Set appropriate center value for diverging maps\r\n5. Test appearance in grayscale\r\n\r\n**Using seaborn for correlation matrices:**\r\n```python\r\nimport seaborn as sns\r\nfig, ax = plt.subplots(figsize=(5, 4))\r\ncorr = df.corr()\r\nmask = np.triu(np.ones_like(corr, dtype=bool))\r\nsns.heatmap(corr, mask=mask, annot=True, fmt='.2f',\r\n cmap='RdBu_r', center=0, square=True,\r\n linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)\r\n```\r\n\r\n### Task 4: Prepare Figure for Specific Journal\r\n\r\n**Workflow:**\r\n1. Check journal requirements: `references/journal_requirements.md`\r\n2. Configure matplotlib for journal:\r\n ```python\r\n from style_presets import configure_for_journal\r\n configure_for_journal('nature', figure_width='single')\r\n ```\r\n3. Create figure (will auto-size correctly)\r\n4. Export with journal specifications:\r\n ```python\r\n from figure_export import save_for_journal\r\n save_for_journal(fig, 'figure1', journal='nature', figure_type='line_art')\r\n ```\r\n\r\n### Task 5: Fix an Existing Figure to Meet Publication Standards\r\n\r\n**Checklist approach** (full checklist in `references/publication_guidelines.md`):\r\n\r\n1. **Check resolution**: Verify DPI meets journal requirements\r\n2. **Check file format**: Use vector for plots, TIFF/PNG for images\r\n3. **Check colors**: Ensure colorblind-friendly\r\n4. **Check fonts**: Minimum 6-7 pt at final size, sans-serif\r\n5. **Check labels**: All axes labeled with units\r\n6. **Check size**: Matches journal column width\r\n7. **Test grayscale**: Figure interpretable without color\r\n8. **Remove chart junk**: No unnecessary grids, 3D effects, shadows\r\n\r\n### Task 6: Create Colorblind-Friendly Visualizations\r\n\r\n**Strategy:**\r\n1. Use approved palettes from `assets/color_palettes.py`\r\n2. Add redundant encoding (line styles, markers, patterns)\r\n3. Test with colorblind simulator\r\n4. Ensure grayscale compatibility\r\n\r\n**Example:**\r\n```python\r\nfrom color_palettes import apply_palette\r\nimport matplotlib.pyplot as plt\r\n\r\napply_palette('okabe_ito')\r\n\r\n\r\n**Always include:**\r\n- Error bars (SD, SEM, or CI - specify which in caption)\r\n- Sample size (n) in figure or caption\r\n- Statistical significance markers (*, **, ***)\r\n- Individual data points when possible (not just summary statistics)\r\n\r\n**Example with statistics:**\r\n```python\r\nax.scatter(x_jittered, individual_points, alpha=0.4, s=8)\r\nax.errorbar(x, means, yerr=sems, fmt='o', capsize=3)\r\n\r\n\r\n### Matplotlib\r\n- Most control over publication details\r\n- Best for complex multi-panel figures\r\n- Use provided style files for consistent formatting\r\n- See `references/matplotlib_examples.md` for extensive examples\r\n\r\n### Seaborn\r\n\r\nSeaborn provides a high-level, dataset-oriented interface for statistical graphics, built on matplotlib. It excels at creating publication-quality statistical visualizations with minimal code while maintaining full compatibility with matplotlib customization.\r\n\r\n**Key advantages for scientific visualization:**\r\n- Automatic statistical estimation and confidence intervals\r\n- Built-in support for multi-panel figures (faceting)\r\n- Colorblind-friendly palettes by default\r\n- Dataset-oriented API using pandas DataFrames\r\n- Semantic mapping of variables to visual properties\r\n\r\n#### Quick Start with Publication Style\r\n\r\nAlways apply matplotlib publication styles first, then configure seaborn:\r\n\r\n```python\r\nimport seaborn as sns\r\nimport matplotlib.pyplot as plt\r\nfrom style_presets import apply_publication_style\r\n\r\napply_publication_style('default')\r\n\r\nsns.set_theme(style='ticks', context='paper', font_scale=1.1)\r\nsns.set_palette('colorblind') # Use colorblind-safe palette\r\n\r\nfig, ax = plt.subplots(figsize=(3.5, 2.5))\r\nsns.scatterplot(data=df, x='time', y='response', \r\n hue='treatment', style='condition', ax=ax)\r\nsns.despine() # Remove top and right spines\r\n```\r\n\r\n#### Common Plot Types for Publications\r\n\r\n**Statistical comparisons:**\r\n```python\r\nfig, ax = plt.subplots(figsize=(3.5, 3))\r\nsns.boxplot(data=df, x='treatment', y='response', \r\n order=['Control', 'Low', 'High'], palette='Set2', ax=ax)\r\nsns.stripplot(data=df, x='treatment', y='response',\r\n order=['Control', 'Low', 'High'], \r\n color='black', alpha=0.3, size=3, ax=ax)\r\nax.set_ylabel('Response (μM)')\r\nsns.despine()\r\n```\r\n\r\n**Distribution analysis:**\r\n```python\r\nfig, ax = plt.subplots(figsize=(4, 3))\r\nsns.violinplot(data=df, x='timepoint', y='expression',\r\n hue='treatment', split=True, inner='quartile', ax=ax)\r\nax.set_ylabel('Gene Expression (AU)')\r\nsns.despine()\r\n```\r\n\r\n**Correlation matrices:**\r\n```python\r\nfig, ax = plt.subplots(figsize=(5, 4))\r\ncorr = df.corr()\r\nmask = np.triu(np.ones_like(corr, dtype=bool)) # Show only lower triangle\r\nsns.heatmap(corr, mask=mask, annot=True, fmt='.2f',\r\n cmap='RdBu_r', center=0, square=True,\r\n linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)\r\nplt.tight_layout()\r\n```\r\n\r\n**Time series with confidence bands:**\r\n```python\r\nfig, ax = plt.subplots(figsize=(5, 3))\r\nsns.lineplot(data=timeseries, x='time', y='measurement',\r\n hue='treatment', style='replicate',\r\n errorbar=('ci', 95), markers=True, dashes=False, ax=ax)\r\nax.set_xlabel('Time (hours)')\r\nax.set_ylabel('Measurement (AU)')\r\nsns.despine()\r\n```\r\n\r\n#### Multi-Panel Figures with Seaborn\r\n\r\n**Using FacetGrid for automatic faceting:**\r\n```python\r\ng = sns.relplot(data=df, x='dose', y='response',\r\n hue='treatment', col='cell_line', row='timepoint',\r\n kind='line', height=2.5, aspect=1.2,\r\n errorbar=('ci', 95), markers=True)\r\ng.set_axis_labels('Dose (μM)', 'Response (AU)')\r\ng.set_titles('{row_name} | {col_name}')\r\nsns.despine()\r\n\r\nfrom figure_export import save_publication_figure\r\nsave_publication_figure(g.figure, 'figure_facets', \r\n formats=['pdf', 'png'], dpi=300)\r\n```\r\n\r\n**Combining seaborn with matplotlib subplots:**\r\n```python\r\nfig, axes = plt.subplots(2, 2, figsize=(7, 6))\r\n\r\nsns.regplot(data=df, x='predictor', y='response', ax=axes[0, 0])\r\naxes[0, 0].text(-0.15, 1.05, 'A', transform=axes[0, 0].transAxes,\r\n fontsize=10, fontweight='bold')\r\n\r\nsns.violinplot(data=df, x='group', y='value', ax=axes[0, 1])\r\naxes[0, 1].text(-0.15, 1.05, 'B', transform=axes[0, 1].transAxes,\r\n fontsize=10, fontweight='bold')\r\n\r\nsns.heatmap(correlation_data, cmap='viridis', ax=axes[1, 0])\r\naxes[1, 0].text(-0.15, 1.05, 'C', transform=axes[1, 0].transAxes,\r\n fontsize=10, fontweight='bold')\r\n\r\nsns.lineplot(data=timeseries, x='time', y='signal', \r\n hue='condition', ax=axes[1, 1])\r\naxes[1, 1].text(-0.15, 1.05, 'D', transform=axes[1, 1].transAxes,\r\n fontsize=10, fontweight='bold')\r\n\r\nplt.tight_layout()\r\nsns.despine()\r\n```\r\n\r\n#### Color Palettes for Publications\r\n\r\nSeaborn includes several colorblind-safe palettes:\r\n\r\n```python\r\nsns.set_palette('colorblind')\r\n\r\nokabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',\r\n '#0072B2', '#D55E00', '#CC79A7', '#000000']\r\nsns.set_palette(okabe_ito)\r\n\r\nsns.heatmap(data, cmap='viridis') # Perceptually uniform\r\nsns.heatmap(corr, cmap='RdBu_r', center=0) # Diverging, centered\r\n```\r\n\r\n#### Choosing Between Axes-Level and Figure-Level Functions\r\n\r\n**Axes-level functions** (e.g., `scatterplot`, `boxplot`, `heatmap`):\r\n- Use when building custom multi-panel layouts\r\n- Accept `ax=` parameter for precise placement\r\n- Better integration with matplotlib subplots\r\n- More control over figure composition\r\n\r\n```python\r\nfig, ax = plt.subplots(figsize=(3.5, 2.5))\r\nsns.scatterplot(data=df, x='x', y='y', hue='group', ax=ax)\r\n```\r\n\r\n**Figure-level functions** (e.g., `relplot`, `catplot`, `displot`):\r\n- Use for automatic faceting by categorical variables\r\n- Create complete figures with consistent styling\r\n- Great for exploratory analysis\r\n- Use `height` and `aspect` for sizing\r\n\r\n```python\r\ng = sns.relplot(data=df, x='x', y='y', col='category', kind='scatter')\r\n```\r\n\r\n#### Statistical Rigor with Seaborn\r\n\r\nSeaborn automatically computes and displays uncertainty:\r\n\r\n```python\r\nsns.lineplot(data=df, x='time', y='value', hue='treatment',\r\n errorbar=('ci', 95)) # Can change to 'sd', 'se', etc.\r\n\r\nsns.barplot(data=df, x='treatment', y='response',\r\n errorbar=('ci', 95), capsize=0.1)\r\n\r\n```\r\n\r\n#### Best Practices for Publication-Ready Seaborn Figures\r\n\r\n1. **Always set publication theme first:**\r\n ```python\r\n sns.set_theme(style='ticks', context='paper', font_scale=1.1)\r\n ```\r\n\r\n2. **Use colorblind-safe palettes:**\r\n ```python\r\n sns.set_palette('colorblind')\r\n ```\r\n\r\n3. **Remove unnecessary elements:**\r\n ```python\r\n sns.despine() # Remove top and right spines\r\n ```\r\n\r\n4. **Control figure size appropriately:**\r\n ```python\r\n # Axes-level: use matplotlib figsize\r\n fig, ax = plt.subplots(figsize=(3.5, 2.5))\r\n \r\n # Figure-level: use height and aspect\r\n g = sns.relplot(..., height=3, aspect=1.2)\r\n ```\r\n\r\n5. **Show individual data points when possible:**\r\n ```python\r\n sns.boxplot(...) # Summary statistics\r\n sns.stripplot(..., alpha=0.3) # Individual points\r\n ```\r\n\r\n6. **Include proper labels with units:**\r\n ```python\r\n ax.set_xlabel('Time (hours)')\r\n ax.set_ylabel('Expression (AU)')\r\n ```\r\n\r\n7. **Export at correct resolution:**\r\n ```python\r\n from figure_export import save_publication_figure\r\n save_publication_figure(fig, 'figure_name', \r\n formats=['pdf', 'png'], dpi=300)\r\n ```\r\n\r\n#### Advanced Seaborn Techniques\r\n\r\n**Pairwise relationships for exploratory analysis:**\r\n```python\r\ng = sns.pairplot(data=df, hue='condition', \r\n vars=['gene1', 'gene2', 'gene3'],\r\n corner=True, diag_kind='kde', height=2)\r\n```\r\n\r\n**Hierarchical clustering heatmap:**\r\n```python\r\ng = sns.clustermap(expression_data, method='ward', \r\n metric='euclidean', z_score=0,\r\n cmap='RdBu_r', center=0, \r\n figsize=(10, 8), \r\n row_colors=condition_colors,\r\n cbar_kws={'label': 'Z-score'})\r\n```\r\n\r\n**Joint distributions with marginals:**\r\n```python",
"name": "scientific-visualization",
"id": "scientific-thinking-scientific-visualization",
"sections": {
"Core Principles and Best Practices": "for i, ax in enumerate([ax1, ax2, ...]):\r\n ax.text(-0.15, 1.05, ascii_uppercase[i], transform=ax.transAxes,\r\n fontsize=10, fontweight='bold', va='top')\r\n```",
"Quick Start Guide": "from figure_export import save_publication_figure\r\nsave_publication_figure(fig, 'treatment_comparison', formats=['pdf', 'png'], dpi=300)\r\n```",
"Workflow Summary": "**Recommended workflow for creating publication figures:**\r\n\r\n1. **Plan**: Determine target journal, figure type, and content\r\n2. **Configure**: Apply appropriate style for journal\r\n ```python\r\n from style_presets import configure_for_journal\r\n configure_for_journal('nature', 'single')\r\n ```\r\n3. **Create**: Build figure with proper labels, colors, statistics\r\n4. **Verify**: Check size, fonts, colors, accessibility\r\n ```python\r\n from figure_export import check_figure_size\r\n check_figure_size(fig, journal='nature')\r\n ```\r\n5. **Export**: Save in required formats\r\n ```python\r\n from figure_export import save_for_journal\r\n save_for_journal(fig, 'figure1', 'nature', 'combination')\r\n ```\r\n6. **Review**: View at final size in manuscript context",
"Statistical Rigor": "ax.text(1.5, max_y * 1.1, '***', ha='center', fontsize=8)\r\n```",
"Common Tasks": "line_styles = ['-', '--', '-.', ':']\r\nmarkers = ['o', 's', '^', 'v']\r\n\r\nfor i, (data, label) in enumerate(datasets):\r\n plt.plot(x, data, linestyle=line_styles[i % 4],\r\n marker=markers[i % 4], label=label)\r\n```",
"Overview": "Scientific visualization transforms data into clear, accurate figures for publication. Create journal-ready plots with multi-panel layouts, error bars, significance markers, and colorblind-safe palettes. Export as PDF/EPS/TIFF using matplotlib, seaborn, and plotly for manuscripts.",
"Working with Different Plotting Libraries": "g = sns.jointplot(data=df, x='gene1', y='gene2',\r\n hue='treatment', kind='scatter',\r\n height=6, ratio=4, marginal_kws={'kde': True})\r\n```\r\n\r\n#### Common Seaborn Issues and Solutions\r\n\r\n**Issue: Legend outside plot area**\r\n```python\r\ng = sns.relplot(...)\r\ng._legend.set_bbox_to_anchor((0.9, 0.5))\r\n```\r\n\r\n**Issue: Overlapping labels**\r\n```python\r\nplt.xticks(rotation=45, ha='right')\r\nplt.tight_layout()\r\n```\r\n\r\n**Issue: Text too small at final size**\r\n```python\r\nsns.set_context('paper', font_scale=1.2) # Increase if needed\r\n```\r\n\r\n#### Additional Resources\r\n\r\nFor more detailed seaborn information, see:\r\n- `scientific-packages/seaborn/SKILL.md` - Comprehensive seaborn documentation\r\n- `scientific-packages/seaborn/references/examples.md` - Practical use cases\r\n- `scientific-packages/seaborn/references/function_reference.md` - Complete API reference\r\n- `scientific-packages/seaborn/references/objects_interface.md` - Modern declarative API\r\n\r\n### Plotly\r\n- Interactive figures for exploration\r\n- Export static images for publication\r\n- Configure for publication quality:\r\n```python\r\nfig.update_layout(\r\n font=dict(family='Arial, sans-serif', size=10),\r\n plot_bgcolor='white',\r\n # ... see matplotlib_examples.md Example 8\r\n)\r\nfig.write_image('figure.png', scale=3) # scale=3 gives ~300 DPI\r\n```",
"When to Use This Skill": "This skill should be used when:\r\n- Creating plots or visualizations for scientific manuscripts\r\n- Preparing figures for journal submission (Nature, Science, Cell, PLOS, etc.)\r\n- Ensuring figures are colorblind-friendly and accessible\r\n- Making multi-panel figures with consistent styling\r\n- Exporting figures at correct resolution and format\r\n- Following specific publication guidelines\r\n- Improving existing figures to meet publication standards\r\n- Creating figures that need to work in both color and grayscale",
"Resources": "### References Directory\r\n\r\n**Load these as needed for detailed information:**\r\n\r\n- **`publication_guidelines.md`**: Comprehensive best practices\r\n - Resolution and file format requirements\r\n - Typography guidelines\r\n - Layout and composition rules\r\n - Statistical rigor requirements\r\n - Complete publication checklist\r\n\r\n- **`color_palettes.md`**: Color usage guide\r\n - Colorblind-friendly palette specifications with RGB values\r\n - Sequential and diverging colormap recommendations\r\n - Testing procedures for accessibility\r\n - Domain-specific palettes (genomics, microscopy)\r\n\r\n- **`journal_requirements.md`**: Journal-specific specifications\r\n - Technical requirements by publisher\r\n - File format and DPI specifications\r\n - Figure dimension requirements\r\n - Quick reference table\r\n\r\n- **`matplotlib_examples.md`**: Practical code examples\r\n - 10 complete working examples\r\n - Line plots, bar plots, heatmaps, multi-panel figures\r\n - Journal-specific figure examples\r\n - Tips for each library (matplotlib, seaborn, plotly)\r\n\r\n### Scripts Directory\r\n\r\n**Use these helper scripts for automation:**\r\n\r\n- **`figure_export.py`**: Export utilities\r\n - `save_publication_figure()`: Save in multiple formats with correct DPI\r\n - `save_for_journal()`: Use journal-specific requirements automatically\r\n - `check_figure_size()`: Verify dimensions meet journal specs\r\n - Run directly: `python scripts/figure_export.py` for examples\r\n\r\n- **`style_presets.py`**: Pre-configured styles\r\n - `apply_publication_style()`: Apply preset styles (default, nature, science, cell)\r\n - `set_color_palette()`: Quick palette switching\r\n - `configure_for_journal()`: One-command journal configuration\r\n - Run directly: `python scripts/style_presets.py` to see examples\r\n\r\n### Assets Directory\r\n\r\n**Use these files in figures:**\r\n\r\n- **`color_palettes.py`**: Importable color definitions\r\n - All recommended palettes as Python constants\r\n - `apply_palette()` helper function\r\n - Can be imported directly into notebooks/scripts\r\n\r\n- **Matplotlib style files**: Use with `plt.style.use()`\r\n - `publication.mplstyle`: General publication quality\r\n - `nature.mplstyle`: Nature journal specifications\r\n - `presentation.mplstyle`: Larger fonts for posters/slides",
"Final Checklist": "Before submitting figures, verify:\r\n\r\n- [ ] Resolution meets journal requirements (300+ DPI)\r\n- [ ] File format is correct (vector for plots, TIFF for images)\r\n- [ ] Figure size matches journal specifications\r\n- [ ] All text readable at final size (≥6 pt)\r\n- [ ] Colors are colorblind-friendly\r\n- [ ] Figure works in grayscale\r\n- [ ] All axes labeled with units\r\n- [ ] Error bars present with definition in caption\r\n- [ ] Panel labels present and consistent\r\n- [ ] No chart junk or 3D effects\r\n- [ ] Fonts consistent across all figures\r\n- [ ] Statistical significance clearly marked\r\n- [ ] Legend is clear and complete\r\n\r\nUse this skill to ensure scientific figures meet the highest publication standards while remaining accessible to all readers.",
"Common Pitfalls to Avoid": "1. **Font too small**: Text unreadable when printed at final size\r\n2. **JPEG format**: Never use JPEG for graphs/plots (creates artifacts)\r\n3. **Red-green colors**: ~8% of males cannot distinguish\r\n4. **Low resolution**: Pixelated figures in publication\r\n5. **Missing units**: Always label axes with units\r\n6. **3D effects**: Distorts perception, avoid completely\r\n7. **Chart junk**: Remove unnecessary gridlines, decorations\r\n8. **Truncated axes**: Start bar charts at zero unless scientifically justified\r\n9. **Inconsistent styling**: Different fonts/colors across figures in same manuscript\r\n10. **No error bars**: Always show uncertainty"
}
}---
name: scientific-visualization
description: "Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, significance markers, colorblind-safe, export PDF/EPS/TIFF, for journal-ready scientific plots."
---
# Scientific Visualization
## Overview
Scientific visualization transforms data into clear, accurate figures for publication. Create journal-ready plots with multi-panel layouts, error bars, significance markers, and colorblind-safe palettes. Export as PDF/EPS/TIFF using matplotlib, seaborn, and plotly for manuscripts.
## When to Use This Skill
This skill should be used when:
- Creating plots or visualizations for scientific manuscripts
- Preparing figures for journal submission (Nature, Science, Cell, PLOS, etc.)
- Ensuring figures are colorblind-friendly and accessible
- Making multi-panel figures with consistent styling
- Exporting figures at correct resolution and format
- Following specific publication guidelines
- Improving existing figures to meet publication standards
- Creating figures that need to work in both color and grayscale
## Quick Start Guide
### Basic Publication-Quality Figure
```python
import matplotlib.pyplot as plt
import numpy as np
# Apply publication style (from scripts/style_presets.py)
from style_presets import apply_publication_style
apply_publication_style('default')
# Create figure with appropriate size (single column = 3.5 inches)
fig, ax = plt.subplots(figsize=(3.5, 2.5))
# Plot data
x = np.linspace(0, 10, 100)
ax.plot(x, np.sin(x), label='sin(x)')
ax.plot(x, np.cos(x), label='cos(x)')
# Proper labeling with units
ax.set_xlabel('Time (seconds)')
ax.set_ylabel('Amplitude (mV)')
ax.legend(frameon=False)
# Remove unnecessary spines
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Save in publication formats (from scripts/figure_export.py)
from figure_export import save_publication_figure
save_publication_figure(fig, 'figure1', formats=['pdf', 'png'], dpi=300)
```
### Using Pre-configured Styles
Apply journal-specific styles using the matplotlib style files in `assets/`:
```python
import matplotlib.pyplot as plt
# Option 1: Use style file directly
plt.style.use('assets/nature.mplstyle')
# Option 2: Use style_presets.py helper
from style_presets import configure_for_journal
configure_for_journal('nature', figure_width='single')
# Now create figures - they'll automatically match Nature specifications
fig, ax = plt.subplots()
# ... your plotting code ...
```
### Quick Start with Seaborn
For statistical plots, use seaborn with publication styling:
```python
import seaborn as sns
import matplotlib.pyplot as plt
from style_presets import apply_publication_style
# Apply publication style
apply_publication_style('default')
sns.set_theme(style='ticks', context='paper', font_scale=1.1)
sns.set_palette('colorblind')
# Create statistical comparison figure
fig, ax = plt.subplots(figsize=(3.5, 3))
sns.boxplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'], palette='Set2', ax=ax)
sns.stripplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'],
color='black', alpha=0.3, size=3, ax=ax)
ax.set_ylabel('Response (μM)')
sns.despine()
# Save figure
from figure_export import save_publication_figure
save_publication_figure(fig, 'treatment_comparison', formats=['pdf', 'png'], dpi=300)
```
## Core Principles and Best Practices
### 1. Resolution and File Format
**Critical requirements** (detailed in `references/publication_guidelines.md`):
- **Raster images** (photos, microscopy): 300-600 DPI
- **Line art** (graphs, plots): 600-1200 DPI or vector format
- **Vector formats** (preferred): PDF, EPS, SVG
- **Raster formats**: TIFF, PNG (never JPEG for scientific data)
**Implementation:**
```python
# Use the figure_export.py script for correct settings
from figure_export import save_publication_figure
# Saves in multiple formats with proper DPI
save_publication_figure(fig, 'myfigure', formats=['pdf', 'png'], dpi=300)
# Or save for specific journal requirements
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', journal='nature', figure_type='combination')
```
### 2. Color Selection - Colorblind Accessibility
**Always use colorblind-friendly palettes** (detailed in `references/color_palettes.md`):
**Recommended: Okabe-Ito palette** (distinguishable by all types of color blindness):
```python
# Option 1: Use assets/color_palettes.py
from color_palettes import OKABE_ITO_LIST, apply_palette
apply_palette('okabe_ito')
# Option 2: Manual specification
okabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',
'#0072B2', '#D55E00', '#CC79A7', '#000000']
plt.rcParams['axes.prop_cycle'] = plt.cycler(color=okabe_ito)
```
**For heatmaps/continuous data:**
- Use perceptually uniform colormaps: `viridis`, `plasma`, `cividis`
- Avoid red-green diverging maps (use `PuOr`, `RdBu`, `BrBG` instead)
- Never use `jet` or `rainbow` colormaps
**Always test figures in grayscale** to ensure interpretability.
### 3. Typography and Text
**Font guidelines** (detailed in `references/publication_guidelines.md`):
- Sans-serif fonts: Arial, Helvetica, Calibri
- Minimum sizes at **final print size**:
- Axis labels: 7-9 pt
- Tick labels: 6-8 pt
- Panel labels: 8-12 pt (bold)
- Sentence case for labels: "Time (hours)" not "TIME (HOURS)"
- Always include units in parentheses
**Implementation:**
```python
# Set fonts globally
import matplotlib as mpl
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['font.sans-serif'] = ['Arial', 'Helvetica']
mpl.rcParams['font.size'] = 8
mpl.rcParams['axes.labelsize'] = 9
mpl.rcParams['xtick.labelsize'] = 7
mpl.rcParams['ytick.labelsize'] = 7
```
### 4. Figure Dimensions
**Journal-specific widths** (detailed in `references/journal_requirements.md`):
- **Nature**: Single 89 mm, Double 183 mm
- **Science**: Single 55 mm, Double 175 mm
- **Cell**: Single 85 mm, Double 178 mm
**Check figure size compliance:**
```python
from figure_export import check_figure_size
fig = plt.figure(figsize=(3.5, 3)) # 89 mm for Nature
check_figure_size(fig, journal='nature')
```
### 5. Multi-Panel Figures
**Best practices:**
- Label panels with bold letters: **A**, **B**, **C** (uppercase for most journals, lowercase for Nature)
- Maintain consistent styling across all panels
- Align panels along edges where possible
- Use adequate white space between panels
**Example implementation** (see `references/matplotlib_examples.md` for complete code):
```python
from string import ascii_uppercase
fig = plt.figure(figsize=(7, 4))
gs = fig.add_gridspec(2, 2, hspace=0.4, wspace=0.4)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
# ... create other panels ...
# Add panel labels
for i, ax in enumerate([ax1, ax2, ...]):
ax.text(-0.15, 1.05, ascii_uppercase[i], transform=ax.transAxes,
fontsize=10, fontweight='bold', va='top')
```
## Common Tasks
### Task 1: Create a Publication-Ready Line Plot
See `references/matplotlib_examples.md` Example 1 for complete code.
**Key steps:**
1. Apply publication style
2. Set appropriate figure size for target journal
3. Use colorblind-friendly colors
4. Add error bars with correct representation (SEM, SD, or CI)
5. Label axes with units
6. Remove unnecessary spines
7. Save in vector format
**Using seaborn for automatic confidence intervals:**
```python
import seaborn as sns
fig, ax = plt.subplots(figsize=(5, 3))
sns.lineplot(data=timeseries, x='time', y='measurement',
hue='treatment', errorbar=('ci', 95),
markers=True, ax=ax)
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Measurement (AU)')
sns.despine()
```
### Task 2: Create a Multi-Panel Figure
See `references/matplotlib_examples.md` Example 2 for complete code.
**Key steps:**
1. Use `GridSpec` for flexible layout
2. Ensure consistent styling across panels
3. Add bold panel labels (A, B, C, etc.)
4. Align related panels
5. Verify all text is readable at final size
### Task 3: Create a Heatmap with Proper Colormap
See `references/matplotlib_examples.md` Example 4 for complete code.
**Key steps:**
1. Use perceptually uniform colormap (`viridis`, `plasma`, `cividis`)
2. Include labeled colorbar
3. For diverging data, use colorblind-safe diverging map (`RdBu_r`, `PuOr`)
4. Set appropriate center value for diverging maps
5. Test appearance in grayscale
**Using seaborn for correlation matrices:**
```python
import seaborn as sns
fig, ax = plt.subplots(figsize=(5, 4))
corr = df.corr()
mask = np.triu(np.ones_like(corr, dtype=bool))
sns.heatmap(corr, mask=mask, annot=True, fmt='.2f',
cmap='RdBu_r', center=0, square=True,
linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)
```
### Task 4: Prepare Figure for Specific Journal
**Workflow:**
1. Check journal requirements: `references/journal_requirements.md`
2. Configure matplotlib for journal:
```python
from style_presets import configure_for_journal
configure_for_journal('nature', figure_width='single')
```
3. Create figure (will auto-size correctly)
4. Export with journal specifications:
```python
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', journal='nature', figure_type='line_art')
```
### Task 5: Fix an Existing Figure to Meet Publication Standards
**Checklist approach** (full checklist in `references/publication_guidelines.md`):
1. **Check resolution**: Verify DPI meets journal requirements
2. **Check file format**: Use vector for plots, TIFF/PNG for images
3. **Check colors**: Ensure colorblind-friendly
4. **Check fonts**: Minimum 6-7 pt at final size, sans-serif
5. **Check labels**: All axes labeled with units
6. **Check size**: Matches journal column width
7. **Test grayscale**: Figure interpretable without color
8. **Remove chart junk**: No unnecessary grids, 3D effects, shadows
### Task 6: Create Colorblind-Friendly Visualizations
**Strategy:**
1. Use approved palettes from `assets/color_palettes.py`
2. Add redundant encoding (line styles, markers, patterns)
3. Test with colorblind simulator
4. Ensure grayscale compatibility
**Example:**
```python
from color_palettes import apply_palette
import matplotlib.pyplot as plt
apply_palette('okabe_ito')
# Add redundant encoding beyond color
line_styles = ['-', '--', '-.', ':']
markers = ['o', 's', '^', 'v']
for i, (data, label) in enumerate(datasets):
plt.plot(x, data, linestyle=line_styles[i % 4],
marker=markers[i % 4], label=label)
```
## Statistical Rigor
**Always include:**
- Error bars (SD, SEM, or CI - specify which in caption)
- Sample size (n) in figure or caption
- Statistical significance markers (*, **, ***)
- Individual data points when possible (not just summary statistics)
**Example with statistics:**
```python
# Show individual points with summary statistics
ax.scatter(x_jittered, individual_points, alpha=0.4, s=8)
ax.errorbar(x, means, yerr=sems, fmt='o', capsize=3)
# Mark significance
ax.text(1.5, max_y * 1.1, '***', ha='center', fontsize=8)
```
## Working with Different Plotting Libraries
### Matplotlib
- Most control over publication details
- Best for complex multi-panel figures
- Use provided style files for consistent formatting
- See `references/matplotlib_examples.md` for extensive examples
### Seaborn
Seaborn provides a high-level, dataset-oriented interface for statistical graphics, built on matplotlib. It excels at creating publication-quality statistical visualizations with minimal code while maintaining full compatibility with matplotlib customization.
**Key advantages for scientific visualization:**
- Automatic statistical estimation and confidence intervals
- Built-in support for multi-panel figures (faceting)
- Colorblind-friendly palettes by default
- Dataset-oriented API using pandas DataFrames
- Semantic mapping of variables to visual properties
#### Quick Start with Publication Style
Always apply matplotlib publication styles first, then configure seaborn:
```python
import seaborn as sns
import matplotlib.pyplot as plt
from style_presets import apply_publication_style
# Apply publication style
apply_publication_style('default')
# Configure seaborn for publication
sns.set_theme(style='ticks', context='paper', font_scale=1.1)
sns.set_palette('colorblind') # Use colorblind-safe palette
# Create figure
fig, ax = plt.subplots(figsize=(3.5, 2.5))
sns.scatterplot(data=df, x='time', y='response',
hue='treatment', style='condition', ax=ax)
sns.despine() # Remove top and right spines
```
#### Common Plot Types for Publications
**Statistical comparisons:**
```python
# Box plot with individual points for transparency
fig, ax = plt.subplots(figsize=(3.5, 3))
sns.boxplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'], palette='Set2', ax=ax)
sns.stripplot(data=df, x='treatment', y='response',
order=['Control', 'Low', 'High'],
color='black', alpha=0.3, size=3, ax=ax)
ax.set_ylabel('Response (μM)')
sns.despine()
```
**Distribution analysis:**
```python
# Violin plot with split comparison
fig, ax = plt.subplots(figsize=(4, 3))
sns.violinplot(data=df, x='timepoint', y='expression',
hue='treatment', split=True, inner='quartile', ax=ax)
ax.set_ylabel('Gene Expression (AU)')
sns.despine()
```
**Correlation matrices:**
```python
# Heatmap with proper colormap and annotations
fig, ax = plt.subplots(figsize=(5, 4))
corr = df.corr()
mask = np.triu(np.ones_like(corr, dtype=bool)) # Show only lower triangle
sns.heatmap(corr, mask=mask, annot=True, fmt='.2f',
cmap='RdBu_r', center=0, square=True,
linewidths=1, cbar_kws={'shrink': 0.8}, ax=ax)
plt.tight_layout()
```
**Time series with confidence bands:**
```python
# Line plot with automatic CI calculation
fig, ax = plt.subplots(figsize=(5, 3))
sns.lineplot(data=timeseries, x='time', y='measurement',
hue='treatment', style='replicate',
errorbar=('ci', 95), markers=True, dashes=False, ax=ax)
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Measurement (AU)')
sns.despine()
```
#### Multi-Panel Figures with Seaborn
**Using FacetGrid for automatic faceting:**
```python
# Create faceted plot
g = sns.relplot(data=df, x='dose', y='response',
hue='treatment', col='cell_line', row='timepoint',
kind='line', height=2.5, aspect=1.2,
errorbar=('ci', 95), markers=True)
g.set_axis_labels('Dose (μM)', 'Response (AU)')
g.set_titles('{row_name} | {col_name}')
sns.despine()
# Save with correct DPI
from figure_export import save_publication_figure
save_publication_figure(g.figure, 'figure_facets',
formats=['pdf', 'png'], dpi=300)
```
**Combining seaborn with matplotlib subplots:**
```python
# Create custom multi-panel layout
fig, axes = plt.subplots(2, 2, figsize=(7, 6))
# Panel A: Scatter with regression
sns.regplot(data=df, x='predictor', y='response', ax=axes[0, 0])
axes[0, 0].text(-0.15, 1.05, 'A', transform=axes[0, 0].transAxes,
fontsize=10, fontweight='bold')
# Panel B: Distribution comparison
sns.violinplot(data=df, x='group', y='value', ax=axes[0, 1])
axes[0, 1].text(-0.15, 1.05, 'B', transform=axes[0, 1].transAxes,
fontsize=10, fontweight='bold')
# Panel C: Heatmap
sns.heatmap(correlation_data, cmap='viridis', ax=axes[1, 0])
axes[1, 0].text(-0.15, 1.05, 'C', transform=axes[1, 0].transAxes,
fontsize=10, fontweight='bold')
# Panel D: Time series
sns.lineplot(data=timeseries, x='time', y='signal',
hue='condition', ax=axes[1, 1])
axes[1, 1].text(-0.15, 1.05, 'D', transform=axes[1, 1].transAxes,
fontsize=10, fontweight='bold')
plt.tight_layout()
sns.despine()
```
#### Color Palettes for Publications
Seaborn includes several colorblind-safe palettes:
```python
# Use built-in colorblind palette (recommended)
sns.set_palette('colorblind')
# Or specify custom colorblind-safe colors (Okabe-Ito)
okabe_ito = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',
'#0072B2', '#D55E00', '#CC79A7', '#000000']
sns.set_palette(okabe_ito)
# For heatmaps and continuous data
sns.heatmap(data, cmap='viridis') # Perceptually uniform
sns.heatmap(corr, cmap='RdBu_r', center=0) # Diverging, centered
```
#### Choosing Between Axes-Level and Figure-Level Functions
**Axes-level functions** (e.g., `scatterplot`, `boxplot`, `heatmap`):
- Use when building custom multi-panel layouts
- Accept `ax=` parameter for precise placement
- Better integration with matplotlib subplots
- More control over figure composition
```python
fig, ax = plt.subplots(figsize=(3.5, 2.5))
sns.scatterplot(data=df, x='x', y='y', hue='group', ax=ax)
```
**Figure-level functions** (e.g., `relplot`, `catplot`, `displot`):
- Use for automatic faceting by categorical variables
- Create complete figures with consistent styling
- Great for exploratory analysis
- Use `height` and `aspect` for sizing
```python
g = sns.relplot(data=df, x='x', y='y', col='category', kind='scatter')
```
#### Statistical Rigor with Seaborn
Seaborn automatically computes and displays uncertainty:
```python
# Line plot: shows mean ± 95% CI by default
sns.lineplot(data=df, x='time', y='value', hue='treatment',
errorbar=('ci', 95)) # Can change to 'sd', 'se', etc.
# Bar plot: shows mean with bootstrapped CI
sns.barplot(data=df, x='treatment', y='response',
errorbar=('ci', 95), capsize=0.1)
# Always specify error type in figure caption:
# "Error bars represent 95% confidence intervals"
```
#### Best Practices for Publication-Ready Seaborn Figures
1. **Always set publication theme first:**
```python
sns.set_theme(style='ticks', context='paper', font_scale=1.1)
```
2. **Use colorblind-safe palettes:**
```python
sns.set_palette('colorblind')
```
3. **Remove unnecessary elements:**
```python
sns.despine() # Remove top and right spines
```
4. **Control figure size appropriately:**
```python
# Axes-level: use matplotlib figsize
fig, ax = plt.subplots(figsize=(3.5, 2.5))
# Figure-level: use height and aspect
g = sns.relplot(..., height=3, aspect=1.2)
```
5. **Show individual data points when possible:**
```python
sns.boxplot(...) # Summary statistics
sns.stripplot(..., alpha=0.3) # Individual points
```
6. **Include proper labels with units:**
```python
ax.set_xlabel('Time (hours)')
ax.set_ylabel('Expression (AU)')
```
7. **Export at correct resolution:**
```python
from figure_export import save_publication_figure
save_publication_figure(fig, 'figure_name',
formats=['pdf', 'png'], dpi=300)
```
#### Advanced Seaborn Techniques
**Pairwise relationships for exploratory analysis:**
```python
# Quick overview of all relationships
g = sns.pairplot(data=df, hue='condition',
vars=['gene1', 'gene2', 'gene3'],
corner=True, diag_kind='kde', height=2)
```
**Hierarchical clustering heatmap:**
```python
# Cluster samples and features
g = sns.clustermap(expression_data, method='ward',
metric='euclidean', z_score=0,
cmap='RdBu_r', center=0,
figsize=(10, 8),
row_colors=condition_colors,
cbar_kws={'label': 'Z-score'})
```
**Joint distributions with marginals:**
```python
# Bivariate distribution with context
g = sns.jointplot(data=df, x='gene1', y='gene2',
hue='treatment', kind='scatter',
height=6, ratio=4, marginal_kws={'kde': True})
```
#### Common Seaborn Issues and Solutions
**Issue: Legend outside plot area**
```python
g = sns.relplot(...)
g._legend.set_bbox_to_anchor((0.9, 0.5))
```
**Issue: Overlapping labels**
```python
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
```
**Issue: Text too small at final size**
```python
sns.set_context('paper', font_scale=1.2) # Increase if needed
```
#### Additional Resources
For more detailed seaborn information, see:
- `scientific-packages/seaborn/SKILL.md` - Comprehensive seaborn documentation
- `scientific-packages/seaborn/references/examples.md` - Practical use cases
- `scientific-packages/seaborn/references/function_reference.md` - Complete API reference
- `scientific-packages/seaborn/references/objects_interface.md` - Modern declarative API
### Plotly
- Interactive figures for exploration
- Export static images for publication
- Configure for publication quality:
```python
fig.update_layout(
font=dict(family='Arial, sans-serif', size=10),
plot_bgcolor='white',
# ... see matplotlib_examples.md Example 8
)
fig.write_image('figure.png', scale=3) # scale=3 gives ~300 DPI
```
## Resources
### References Directory
**Load these as needed for detailed information:**
- **`publication_guidelines.md`**: Comprehensive best practices
- Resolution and file format requirements
- Typography guidelines
- Layout and composition rules
- Statistical rigor requirements
- Complete publication checklist
- **`color_palettes.md`**: Color usage guide
- Colorblind-friendly palette specifications with RGB values
- Sequential and diverging colormap recommendations
- Testing procedures for accessibility
- Domain-specific palettes (genomics, microscopy)
- **`journal_requirements.md`**: Journal-specific specifications
- Technical requirements by publisher
- File format and DPI specifications
- Figure dimension requirements
- Quick reference table
- **`matplotlib_examples.md`**: Practical code examples
- 10 complete working examples
- Line plots, bar plots, heatmaps, multi-panel figures
- Journal-specific figure examples
- Tips for each library (matplotlib, seaborn, plotly)
### Scripts Directory
**Use these helper scripts for automation:**
- **`figure_export.py`**: Export utilities
- `save_publication_figure()`: Save in multiple formats with correct DPI
- `save_for_journal()`: Use journal-specific requirements automatically
- `check_figure_size()`: Verify dimensions meet journal specs
- Run directly: `python scripts/figure_export.py` for examples
- **`style_presets.py`**: Pre-configured styles
- `apply_publication_style()`: Apply preset styles (default, nature, science, cell)
- `set_color_palette()`: Quick palette switching
- `configure_for_journal()`: One-command journal configuration
- Run directly: `python scripts/style_presets.py` to see examples
### Assets Directory
**Use these files in figures:**
- **`color_palettes.py`**: Importable color definitions
- All recommended palettes as Python constants
- `apply_palette()` helper function
- Can be imported directly into notebooks/scripts
- **Matplotlib style files**: Use with `plt.style.use()`
- `publication.mplstyle`: General publication quality
- `nature.mplstyle`: Nature journal specifications
- `presentation.mplstyle`: Larger fonts for posters/slides
## Workflow Summary
**Recommended workflow for creating publication figures:**
1. **Plan**: Determine target journal, figure type, and content
2. **Configure**: Apply appropriate style for journal
```python
from style_presets import configure_for_journal
configure_for_journal('nature', 'single')
```
3. **Create**: Build figure with proper labels, colors, statistics
4. **Verify**: Check size, fonts, colors, accessibility
```python
from figure_export import check_figure_size
check_figure_size(fig, journal='nature')
```
5. **Export**: Save in required formats
```python
from figure_export import save_for_journal
save_for_journal(fig, 'figure1', 'nature', 'combination')
```
6. **Review**: View at final size in manuscript context
## Common Pitfalls to Avoid
1. **Font too small**: Text unreadable when printed at final size
2. **JPEG format**: Never use JPEG for graphs/plots (creates artifacts)
3. **Red-green colors**: ~8% of males cannot distinguish
4. **Low resolution**: Pixelated figures in publication
5. **Missing units**: Always label axes with units
6. **3D effects**: Distorts perception, avoid completely
7. **Chart junk**: Remove unnecessary gridlines, decorations
8. **Truncated axes**: Start bar charts at zero unless scientifically justified
9. **Inconsistent styling**: Different fonts/colors across figures in same manuscript
10. **No error bars**: Always show uncertainty
## Final Checklist
Before submitting figures, verify:
- [ ] Resolution meets journal requirements (300+ DPI)
- [ ] File format is correct (vector for plots, TIFF for images)
- [ ] Figure size matches journal specifications
- [ ] All text readable at final size (≥6 pt)
- [ ] Colors are colorblind-friendly
- [ ] Figure works in grayscale
- [ ] All axes labeled with units
- [ ] Error bars present with definition in caption
- [ ] Panel labels present and consistent
- [ ] No chart junk or 3D effects
- [ ] Fonts consistent across all figures
- [ ] Statistical significance clearly marked
- [ ] Legend is clear and complete
Use this skill to ensure scientific figures meet the highest publication standards while remaining accessible to all readers.