/bio-data-visualization-ggplot2-fundamentals
<!--
$ npx -y skills add FreedomIntelligence/OpenClaw-Medical-Skills --skill bio-data-visualization-ggplot2-fundamentals --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/bio-data-visualization-ggplot2-fundamentals
Context preview
The summary Claude sees to decide when to auto-load this skill.
<!--
SKILL.md
bio-data-visualization-ggplot2-fundamentals.SKILL.md<!--
COPYRIGHT NOTICE
This file is part of the "Universal Biomedical Skills" project.
Copyright (c) 2026 MD BABU MIA, PhD <md.babu.mia@mssm.edu>
All Rights Reserved.
#
This code is proprietary and confidential.
Unauthorized copying of this file, via any medium is strictly prohibited.
#
Provenance: Authenticated by MD BABU MIA
-->
--- name: bio-data-visualization-ggplot2-fundamentals description: Create publication-quality scientific figures with ggplot2 including scatter plots, boxplots, heatmaps, and multi-panel layouts. Use when creating static figures for papers, presentations, or reports in R. tool_type: r primary_tool: ggplot2 measurable_outcome: Execute skill workflow successfully with valid output within 15 minutes. allowed-tools:
- read_file
- run_shell_command
---
ggplot2 Fundamentals
Basic Structure
library(ggplot2)
# Grammar of graphics: data + aesthetics + geometry
ggplot(data, aes(x = var1, y = var2)) +
geom_point()Common Geoms
# Scatter plot
ggplot(df, aes(x, y)) + geom_point()
# Line plot
ggplot(df, aes(x, y)) + geom_line()
# Bar plot
ggplot(df, aes(x, y)) + geom_col() # y values
ggplot(df, aes(x)) + geom_bar() # counts
# Boxplot
ggplot(df, aes(group, value)) + geom_boxplot()
# Violin plot
ggplot(df, aes(group, value)) + geom_violin()
# Histogram
ggplot(df, aes(x)) + geom_histogram(bins = 30)
# Density
ggplot(df, aes(x, fill = group)) + geom_density(alpha = 0.5)
# Heatmap
ggplot(df, aes(x, y, fill = value)) + geom_tile()
Aesthetic Mappings
# Color by group
ggplot(df, aes(x, y, color = group)) + geom_point()
# Size by value
ggplot(df, aes(x, y, size = value)) + geom_point()
# Shape by category
ggplot(df, aes(x, y, shape = category)) + geom_point()
# Fill for bars/boxes
ggplot(df, aes(x, y, fill = group)) + geom_boxplot()
# Alpha for transparency
ggplot(df, aes(x, y, alpha = value)) + geom_point()
Publication Theme
theme_publication <- function(base_size = 12) {
theme_bw(base_size = base_size) +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(color = 'black', linewidth = 0.5),
axis.text = element_text(color = 'black'),
axis.ticks = element_line(color = 'black'),
legend.key = element_blank(),
strip.background = element_blank(),
strip.text = element_text(face = 'bold')
)
}
# Usage
ggplot(df, aes(x, y)) +
geom_point() +
theme_publication()Color Palettes
library(RColorBrewer)
library(viridis)
# Qualitative (categorical)
scale_color_brewer(palette = 'Set1')
scale_fill_brewer(palette = 'Set2')
# Sequential (continuous)
scale_fill_viridis_c()
scale_color_gradient(low = 'white', high = 'red')
# Diverging
scale_fill_gradient2(low = 'blue', mid = 'white', high = 'red', midpoint = 0)
scale_fill_distiller(palette = 'RdBu')
# Manual colors
scale_color_manual(values = c('Control' = '#1f77b4', 'Treatment' = '#d62728'))Volcano Plot
volcano_plot <- function(res, fdr = 0.05, lfc = 1) {
res <- res %>%
mutate(
significance = case_when(
padj < fdr & log2FoldChange > lfc ~ 'Up',
padj < fdr & log2FoldChange < -lfc ~ 'Down',
TRUE ~ 'NS'
)
)
ggplot(res, aes(log2FoldChange, -log10(pvalue), color = significance)) +
geom_point(alpha = 0.6, size = 1) +
scale_color_manual(values = c('Up' = '#d62728', 'Down' = '#1f77b4', 'NS' = 'grey60')) +
geom_vline(xintercept = c(-lfc, lfc), linetype = 'dashed', color = 'grey40') +
geom_hline(yintercept = -log10(fdr), linetype = 'dashed', color = 'grey40') +
labs(x = 'Log2 Fold Change', y = '-Log10 P-value') +
theme_publication()
}MA Plot
ma_plot <- function(res, fdr = 0.05) {
res <- res %>%
mutate(significant = padj < fdr)
ggplot(res, aes(log10(baseMean), log2FoldChange, color = significant)) +
geom_point(alpha = 0.5, size = 1) +
scale_color_manual(values = c('TRUE' = 'red', 'FALSE' = 'grey60')) +
geom_hline(yintercept = 0, color = 'black') +
labs(x = 'Log10 Mean Expression', y = 'Log2 Fold Change') +
theme_publication()
}Boxplot with Points
ggplot(df, aes(group, value, fill = group)) +
geom_boxplot(outlier.shape = NA, alpha = 0.7) +
geom_jitter(width = 0.2, alpha = 0.5, size = 1) +
scale_fill_brewer(palette = 'Set2') +
labs(x = NULL, y = 'Expression') +
theme_publication() +
theme(legend.position = 'none')Faceting
# Wrap by one variable
ggplot(df, aes(x, y)) +
geom_point() +
facet_wrap(~ group, scales = 'free')
# Grid by two variables
ggplot(df, aes(x, y)) +
geom_point() +
facet_grid(rows = vars(condition), cols = vars(timepoint))Labels and Text
library(ggrepel)
ggplot(res, aes(log2FoldChange, -log10(pvalue))) +
geom_point() +
geom_text_repel(
data = subset(res, padj < 0.01),
aes(label = gene),
max.overlaps = 20,
size = 3
)Multi-Panel Figures
library(patchwork)
p1 <- ggplot(df, aes(x, y)) + geom_point()
p2 <- ggplot(df, aes(group, value)) + geom_boxplot()
p3 <- ggplot(df, aes(x)) + geom_histogram()
# Combine horizontally
p1 + p2 + p3
# Combine with layout
(p1 | p2) / p3
# Add labels
(p1 + p2 + p3) + plot_annotation(tag_levels = 'A')
# Shared legend
(p1 + p2) + plot_layout(guides = 'collect')
Saving Figures
# For publication (300 DPI)
ggsave('figure.pdf', p, width = 7, height = 5, units = 'in')
ggsave('figure.png', p, width = 7, height = 5, units = 'in', dpi = 300)
ggsave('figure.tiff', p, width = 7, height = 5, units = 'in', dpi = 300, compression = 'lzw')
# For presentations
ggsave('figure.png', p, width = 10, height = 6, dpi = 150)Axis Formatting
library(scales)
# Scientific notation
scale_y_continuous(l
Read more
<!--
COPYRIGHT NOTICE
This file is part of the "Universal Biomedical Skills" project.
Copyright (c) 2026 MD BABU MIA, PhD <md.babu.mia@mssm.edu>
All Rights Reserved.
#
This code is proprietary and confidential.
Unauthorized copying of this file, via any medium is strictly prohibited.
#
Provenance: Authenticated by MD BABU MIA
-->
--- name: bio-data-visualization-ggplot2-fundamentals description: Create publication-quality scientific figures with ggplot2 including scatter plots, boxplots, heatmaps, and multi-panel layouts. Use when creating static figures for papers, presentations, or reports in R. tool_type: r primary_tool: ggplot2 measurable_outcome: Execute skill workflow successfully with valid output within 15 minutes. allowed-tools:
- read_file
- run_shell_command
---
ggplot2 Fundamentals
Basic Structure
library(ggplot2)
# Grammar of graphics: data + aesthetics + geometry
ggplot(data, aes(x = var1, y = var2)) +
geom_point()Common Geoms
# Scatter plot ggplot(df, aes(x, y)) + geom_point() # Line plot ggplot(df, aes(x, y)) + geom_line() # Bar plot ggplot(df, aes(x, y)) + geom_col() # y values ggplot(df, aes(x)) + geom_bar() # counts # Boxplot ggplot(df, aes(group, value)) + geom_boxplot() # Violin plot ggplot(df, aes(group, value)) + geom_violin() # Histogram ggplot(df, aes(x)) + geom_histogram(bins = 30) # Density ggplot(df, aes(x, fill = group)) + geom_density(alpha = 0.5) # Heatmap ggplot(df, aes(x, y, fill = value)) + geom_tile()
Aesthetic Mappings
# Color by group ggplot(df, aes(x, y, color = group)) + geom_point() # Size by value ggplot(df, aes(x, y, size = value)) + geom_point() # Shape by category ggplot(df, aes(x, y, shape = category)) + geom_point() # Fill for bars/boxes ggplot(df, aes(x, y, fill = group)) + geom_boxplot() # Alpha for transparency ggplot(df, aes(x, y, alpha = value)) + geom_point()
Publication Theme
theme_publication <- function(base_size = 12) {
theme_bw(base_size = base_size) +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(color = 'black', linewidth = 0.5),
axis.text = element_text(color = 'black'),
axis.ticks = element_line(color = 'black'),
legend.key = element_blank(),
strip.background = element_blank(),
strip.text = element_text(face = 'bold')
)
}
# Usage
ggplot(df, aes(x, y)) +
geom_point() +
theme_publication()Color Palettes
library(RColorBrewer)
library(viridis)
# Qualitative (categorical)
scale_color_brewer(palette = 'Set1')
scale_fill_brewer(palette = 'Set2')
# Sequential (continuous)
scale_fill_viridis_c()
scale_color_gradient(low = 'white', high = 'red')
# Diverging
scale_fill_gradient2(low = 'blue', mid = 'white', high = 'red', midpoint = 0)
scale_fill_distiller(palette = 'RdBu')
# Manual colors
scale_color_manual(values = c('Control' = '#1f77b4', 'Treatment' = '#d62728'))Volcano Plot
volcano_plot <- function(res, fdr = 0.05, lfc = 1) {
res <- res %>%
mutate(
significance = case_when(
padj < fdr & log2FoldChange > lfc ~ 'Up',
padj < fdr & log2FoldChange < -lfc ~ 'Down',
TRUE ~ 'NS'
)
)
ggplot(res, aes(log2FoldChange, -log10(pvalue), color = significance)) +
geom_point(alpha = 0.6, size = 1) +
scale_color_manual(values = c('Up' = '#d62728', 'Down' = '#1f77b4', 'NS' = 'grey60')) +
geom_vline(xintercept = c(-lfc, lfc), linetype = 'dashed', color = 'grey40') +
geom_hline(yintercept = -log10(fdr), linetype = 'dashed', color = 'grey40') +
labs(x = 'Log2 Fold Change', y = '-Log10 P-value') +
theme_publication()
}MA Plot
ma_plot <- function(res, fdr = 0.05) {
res <- res %>%
mutate(significant = padj < fdr)
ggplot(res, aes(log10(baseMean), log2FoldChange, color = significant)) +
geom_point(alpha = 0.5, size = 1) +
scale_color_manual(values = c('TRUE' = 'red', 'FALSE' = 'grey60')) +
geom_hline(yintercept = 0, color = 'black') +
labs(x = 'Log10 Mean Expression', y = 'Log2 Fold Change') +
theme_publication()
}Boxplot with Points
ggplot(df, aes(group, value, fill = group)) +
geom_boxplot(outlier.shape = NA, alpha = 0.7) +
geom_jitter(width = 0.2, alpha = 0.5, size = 1) +
scale_fill_brewer(palette = 'Set2') +
labs(x = NULL, y = 'Expression') +
theme_publication() +
theme(legend.position = 'none')Faceting
# Wrap by one variable
ggplot(df, aes(x, y)) +
geom_point() +
facet_wrap(~ group, scales = 'free')
# Grid by two variables
ggplot(df, aes(x, y)) +
geom_point() +
facet_grid(rows = vars(condition), cols = vars(timepoint))Labels and Text
library(ggrepel)
ggplot(res, aes(log2FoldChange, -log10(pvalue))) +
geom_point() +
geom_text_repel(
data = subset(res, padj < 0.01),
aes(label = gene),
max.overlaps = 20,
size = 3
)Multi-Panel Figures
library(patchwork) p1 <- ggplot(df, aes(x, y)) + geom_point() p2 <- ggplot(df, aes(group, value)) + geom_boxplot() p3 <- ggplot(df, aes(x)) + geom_histogram() # Combine horizontally p1 + p2 + p3 # Combine with layout (p1 | p2) / p3 # Add labels (p1 + p2 + p3) + plot_annotation(tag_levels = 'A') # Shared legend (p1 + p2) + plot_layout(guides = 'collect')
Saving Figures
# For publication (300 DPI)
ggsave('figure.pdf', p, width = 7, height = 5, units = 'in')
ggsave('figure.png', p, width = 7, height = 5, units = 'in', dpi = 300)
ggsave('figure.tiff', p, width = 7, height = 5, units = 'in', dpi = 300, compression = 'lzw')
# For presentations
ggsave('figure.png', p, width = 10, height = 6, dpi = 150)Axis Formatting
library(scales) # Scientific notation scale_y_continuous(l
The largest open-source medical AI skill library for OpenClaw.
Other skills on openclaw-medical-skills.
adaptyv
Cloud laboratory platform for automated protein testing and validation. Use when designing proteins and needing experimental validation including binding…
adhd-daily-planner
Time-blind friendly planning, executive function support, and daily structure for ADHD brains. Specializes in realistic time estimation, dopamine-aware task…
aeon
This skill should be used for time series machine learning tasks including classification, regression, clustering, forecasting, anomaly detection,…
agent-browser
Browse the web for any task — research topics, read articles, interact with web apps, fill forms, take screenshots, extract data, and test web pages. Use…

