library(wikiprofiler)
library(clusterProfiler)
library(DOSE)
library(org.Hs.eg.db)
library(knitr)wikiprofiler is designed around a pipe-friendly grammar for pathway graphics. The core idea is simple: start with a pathway plot, add a data-mapping layer, and then add optional visual refinements. The newer APIs extend that same design upstream and downstream: wp_map() prepares data before plotting, wp_comparefill() adds a comparison layer, and wp_render() scales the workflow to pathway batches.
This vignette walks through the current workflow in English, with the wp_* functions written in a pipe-oriented style whenever composition makes sense.
library(wikiprofiler)
library(clusterProfiler)
library(DOSE)
library(org.Hs.eg.db)
library(knitr)The example below uses DOSE::geneList together with clusterProfiler::enrichWP() so that the same objects can be reused across the basic plotting, comparison plotting, and batch rendering sections.
data(geneList, package = "DOSE")
de <- names(geneList)[1:100]
wp_res <- enrichWP(de, organism = "Homo sapiens")
wp_tbl <- as.data.frame(wp_res)
de_symbol <- bitr(
de,
fromType = "ENTREZID",
toType = "SYMBOL",
OrgDb = "org.Hs.eg.db"
)
value <- stats::setNames(geneList[de_symbol[, 1]], de_symbol[, 2])
pathway_id <- wp_tbl$ID[1]
kable(head(wp_tbl[, c("ID", "Description", "p.adjust")], 5), digits = 4)| ID | Description | p.adjust | |
|---|---|---|---|
| WP2446 | WP2446 | Retinoblastoma gene in cancer | 0.0000 |
| WP2361 | WP2361 | Gastric cancer network 1 | 0.0000 |
| WP179 | WP179 | Cell cycle | 0.0011 |
| WP5039 | WP5039 | SARS CoV 2 innate immunity evasion and cell specific immune response | 0.0043 |
| WP4240 | WP4240 | Regulation of sister chromatid separation at the metaphase anaphase transition | 0.0043 |
The most direct workflow starts with wpplot(), adds a fill layer with wp_bgfill(), and then improves label readability with wp_shadowtext().
wpplot(pathway_id) |>
wp_bgfill(
value = value,
low = "darkgreen",
high = "firebrick",
legend_x = 0.88,
legend_y = 0.95
) |>
wp_shadowtext(bg.r = 2, bg.col = "white")If you want to save the final plot, keep the piped object and pass it to wpsave().
p_single <- wpplot(pathway_id) |>
wp_bgfill(
value = value,
low = "darkgreen",
high = "firebrick",
legend_x = 0.88,
legend_y = 0.95
) |>
wp_shadowtext()
single_png <- file.path(tempdir(), "wikiprofiler-single-demo.png")
wpsave(p_single, single_png, width = 11, height = 7)
single_png
#> [1] "C:\\Users\\HUAWEI\\AppData\\Local\\Temp\\RtmpKqDcnS/wikiprofiler-single-demo.png"wp_map()wp_bgfill() expects a named numeric vector keyed by gene symbol. In real analyses, that is often not the format you start with. wp_map() fills that gap by:
ENTREZID to SYMBOLThe next example intentionally duplicates part of the table so that the aggregation step is visible.
expr_tbl <- de_symbol[1:40, c("ENTREZID", "SYMBOL")]
expr_tbl$score <- unname(geneList[expr_tbl$ENTREZID])
expr_tbl_dup <- expr_tbl[1:10, ]
expr_tbl_dup$score <- expr_tbl_dup$score * 0.5
expr_tbl2 <- rbind(expr_tbl, expr_tbl_dup)
mapped_value <- wp_map(
expr_tbl2,
value_col = "score",
id_col = "ENTREZID",
mapping = de_symbol[, c("ENTREZID", "SYMBOL")],
mapping_from = "ENTREZID",
mapping_to = "SYMBOL",
aggregator = "mean"
)
head(mapped_value, 10)
#> APOBEC3B ASPM BCL2A1 CCNB2 CDC20 CDC45 CDCA3 CDCA8
#> 2.674310 2.877002 2.967223 3.125239 2.758393 3.385945 2.595700 3.108056
#> CENPE CEP55
#> 2.414821 2.784238wp_map() also stores a mapping table as an attribute so that you can inspect how each symbol-level value was produced.
mapping_table <- attr(mapped_value, "mapping_table")
kable(head(mapping_table, 10), digits = 4)| input_id | symbol | value | aggregated_value |
|---|---|---|---|
| 4312 | MMP1 | 4.5726 | 3.4295 |
| 8318 | CDC45 | 4.5146 | 3.3859 |
| 10874 | NMU | 4.4182 | 3.3137 |
| 55143 | CDCA8 | 4.1441 | 3.1081 |
| 55388 | MCM10 | 3.8763 | 2.9072 |
| 991 | CDC20 | 3.6779 | 2.7584 |
| 6280 | S100A9 | 3.5020 | 2.6265 |
| 2305 | FOXM1 | 3.2918 | 2.4689 |
| 9493 | KIF23 | 3.2862 | 2.4647 |
| 1062 | CENPE | 3.2198 | 2.4148 |
Once the values are prepared, they drop directly into the same pipe-oriented plotting workflow.
wpplot(pathway_id) |>
wp_bgfill(
value = mapped_value,
low = "navy",
high = "goldenrod",
legend_x = 0.88,
legend_y = 0.95
) |>
wp_shadowtext()wp_comparefill()When both conditions are already represented as named numeric vectors keyed by symbol, wp_comparefill() computes the comparison values and reuses the same plotting grammar.
Here the second condition is simulated from mapped_value only to illustrate the API. The point is the workflow shape, not the biology of this toy example.
control_value <- mapped_value
case_value <- mapped_value + rep(c(-0.6, 0.9), length.out = length(mapped_value))
p_compare <- wpplot(pathway_id) |>
wp_comparefill(
value = case_value,
control = control_value,
mode = "difference",
low = "steelblue4",
high = "darkorange2",
legend_x = 0.88,
legend_y = 0.95
) |>
wp_shadowtext()
p_compareThe comparison table is stored on the returned wpplot object.
kable(head(p_compare$comparison, 10), digits = 4)| symbol | case | control | comparison |
|---|---|---|---|
| APOBEC3B | 2.0743 | 2.6743 | -0.6 |
| ASPM | 3.7770 | 2.8770 | 0.9 |
| BCL2A1 | 2.3672 | 2.9672 | -0.6 |
| CCNB2 | 4.0252 | 3.1252 | 0.9 |
| CDC20 | 2.1584 | 2.7584 | -0.6 |
| CDC45 | 4.2859 | 3.3859 | 0.9 |
| CDCA3 | 1.9957 | 2.5957 | -0.6 |
| CDCA8 | 4.0081 | 3.1081 | 0.9 |
| CENPE | 1.8148 | 2.4148 | -0.6 |
| CEP55 | 3.6842 | 2.7842 | 0.9 |
If you prefer ratio-based contrasts, switch the mode to log2_ratio.
wpplot(pathway_id) |>
wp_comparefill(
value = case_value,
control = control_value,
mode = "log2_ratio",
pseudocount = 1
) |>
wp_shadowtext()wp_render()wp_render() is the batch entry point. It accepts pathway IDs directly, a data.frame, or an enrichment-like S4 object with a result slot. It can return a named list of wpplot objects, write files to disk, or do both.
The example below renders the top two enriched pathways and writes them with a filename template that combines rank, pathway ID, and pathway name.
batch_dir <- file.path(tempdir(), "wikiprofiler-batch-demo")
if (dir.exists(batch_dir)) {
unlink(batch_dir, recursive = TRUE)
}
batch_plots <- wp_render(
pathway = wp_tbl[, c("ID", "Description")],
value = mapped_value,
n = 2,
name_col = "Description",
dir = batch_dir,
file_ext = "png",
filename_template = "{index}_{id}_{name}",
shadowtext = TRUE,
width = 11,
height = 7
)
batch_files <- list.files(batch_dir, full.names = TRUE)
batch_files
#> [1] "C:\\Users\\HUAWEI\\AppData\\Local\\Temp\\RtmpKqDcnS/wikiprofiler-batch-demo/1_WP2446_Retinoblastoma_gene_in_cancer.png"
#> [2] "C:\\Users\\HUAWEI\\AppData\\Local\\Temp\\RtmpKqDcnS/wikiprofiler-batch-demo/2_WP2361_Gastric_cancer_network_1.png"The returned object is still useful even when you also export files.
names(batch_plots)
#> [1] "WP2446" "WP2361"To work entirely in memory, omit dir.
plots <- wp_render(
pathway = wp_res,
value = mapped_value,
n = 6,
shadowtext = TRUE
)In practice, the workflow often looks like this:
wp_res <- enrichWP(gene_ids, organism = "Homo sapiens")
mapped_value <- wp_map(
expr_table,
value_col = "logFC",
id_col = "ENTREZID",
mapping = id_map,
mapping_from = "ENTREZID",
mapping_to = "SYMBOL",
aggregator = "mean"
)
plots <- wp_render(
pathway = wp_res,
value = mapped_value,
n = 6,
dir = "wp_batch",
name_col = "Description",
filename_template = "{index}_{id}_{name}",
shadowtext = TRUE
)For two-condition analyses, pass both value and control.
plots <- wp_render(
pathway = wp_res,
value = case_value,
control = control_value,
n = 6,
dir = "wp_compare_batch",
name_col = "Description",
filename_template = "{index}_{id}_{name}",
shadowtext = TRUE
)The package now exposes a clearer layered workflow:
wpplot() starts a pathway graphicwp_bgfill() and wp_shadowtext() add visual layerswp_map() prepares data for plottingwp_comparefill() adds condition-to-condition contrastswp_render() scales the same grammar to pathway batchesThe important part is that the plotting grammar still reads from left to right. The newer APIs do not replace that design; they make the same modular approach easier to use in real analysis pipelines.