Whitehot
Whitehot

Reputation: 497

Change colours of a ggplot object created by a function

I am using the fgsea library for some analyses, in particular I use the plotEnrichment function a lot. This function returns a ggplot object with all the layers, but I'd like to change the curve it shows from bright to something else. This code

library(fgsea)
data(examplePathways)
data(exampleRanks)
p = plotEnrichment(examplePathways[["5991130_Programmed_Cell_Death"]], exampleRanks)

will return this plot Basic fgsea plotEnrichment plot

Is there any way to change the colour once its created?

Note: I am pretty sure there are ways to do this fairly easily, but I did not create the plot so I don't know what each layer is called or how they were created.


As per BrianFisher's recommendations, I tried

p + scale_color_brewer(palette="GnBu")
p + scale_color_manual(values=c("blue","red"))

But they did not change anything on the plot, as far as I could tell.

Upvotes: 3

Views: 1914

Answers (2)

KoenV
KoenV

Reputation: 4283

Another way to achieve this is by changing the ggplot object directly by using the following code:

## change the aes parameter in the object
p$layers[[5]]$aes_params$colour <- 'blue'
## then plot p 
p

This yields the following graph:

enter image description here

A short walk-through

This technique has proven useful to me on numerous occasions. Hence, some more detail:

p$layers gives us the info we need to dig further: we need to access the geom_line configuration. So, after consulting the info below, we choose to continue with p$layers[[5]]

> p$layers
[[1]]
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

[[2]]
mapping: yintercept = ~yintercept 
geom_hline: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

[[3]]
mapping: yintercept = ~yintercept 
geom_hline: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

[[4]]
mapping: yintercept = ~yintercept 
geom_hline: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

[[5]]
geom_line: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

[[6]]
mapping: x = ~x, y = ~-diff/2, xend = ~x, yend = ~diff/2 
geom_segment: arrow = NULL, arrow.fill = NULL, lineend = butt, linejoin = round, na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

If we add an $ after p$layers[[5]], we get the possible choices to extend the code (in RStudio) like in the picture below:

enter image description here

We choose aes_params and add a new $. At that moment, the only choice is colour. We are at the endpoint: here we can set colour of the geom_line.

So, now you know where the hacky, mysterious code came from; and here it is for the very last time:

p$layers[[5]]$aes_params$colour <- 'blue'

Upvotes: 6

StupidWolf
StupidWolf

Reputation: 46908

If you look at plotEnrichment:

 plotEnrichment
function (pathway, stats, gseaParam = 1, ticksSize = 0.2)
{
    rnk <- rank(-stats)
    ord <- order(rnk)
    statsAdj <- stats[ord]
    statsAdj <- sign(statsAdj) * (abs(statsAdj)^gseaParam)
    statsAdj <- statsAdj/max(abs(statsAdj))
    pathway <- unname(as.vector(na.omit(match(pathway, names(statsAdj)))))
    pathway <- sort(pathway)
    gseaRes <- calcGseaStat(statsAdj, selectedStats = pathway,
        returnAllExtremes = TRUE)
    bottoms <- gseaRes$bottoms
    tops <- gseaRes$tops
    n <- length(statsAdj)
    xs <- as.vector(rbind(pathway - 1, pathway))
    ys <- as.vector(rbind(bottoms, tops))
    toPlot <- data.frame(x = c(0, xs, n + 1), y = c(0, ys, 0))
    diff <- (max(tops) - min(bottoms))/8
    x = y = NULL
    g <- ggplot(toPlot, aes(x = x, y = y)) + geom_point(color = "green",
        size = 0.1) + geom_hline(yintercept = max(tops), colour = "red",
        linetype = "dashed") + geom_hline(yintercept = min(bottoms),
        colour = "red", linetype = "dashed") + geom_hline(yintercept = 0,
        colour = "black") + geom_line(color = "green") + theme_bw() +
        geom_segment(data = data.frame(x = pathway), mapping = aes(x = x,
            y = -diff/2, xend = x, yend = diff/2), size = ticksSize) +
        theme(panel.border = element_blank(), panel.grid.minor = element_blank()) +
        labs(x = "rank", y = "enrichment score")
    g
}

The color is hardcoded in geom_line(color = "green"), partly because there is no column in the data.frame that specifies the color. so you have two options:

a) Plot over it

p + geom_line(color="steelblue")

enter image description here

b) change the function and save it as another function (e.g plotEnr below)

plotEnr = function (pathway, stats, gseaParam = 1, ticksSize = 0.2)
    {   
        LINECOL = "red"
        rnk <- rank(-stats)
        ord <- order(rnk)
        statsAdj <- stats[ord]
        statsAdj <- sign(statsAdj) * (abs(statsAdj)^gseaParam)
        statsAdj <- statsAdj/max(abs(statsAdj))
        pathway <- unname(as.vector(na.omit(match(pathway, names(statsAdj)))))
        pathway <- sort(pathway)
        gseaRes <- calcGseaStat(statsAdj, selectedStats = pathway,
            returnAllExtremes = TRUE)
        bottoms <- gseaRes$bottoms
        tops <- gseaRes$tops
        n <- length(statsAdj)
        xs <- as.vector(rbind(pathway - 1, pathway))
        ys <- as.vector(rbind(bottoms, tops))
        toPlot <- data.frame(x = c(0, xs, n + 1), y = c(0, ys, 0))
        diff <- (max(tops) - min(bottoms))/8
        x = y = NULL
        g <- ggplot(toPlot, aes(x = x, y = y)) + geom_point(size = 0.1) + 
        geom_hline(yintercept = max(tops), colour = "red",
        linetype = "dashed") + 
        geom_hline(yintercept = min(bottoms),
        colour = "red", linetype = "dashed") + geom_hline(yintercept = 0,
            colour = "black") + geom_line(col=LINECOL) + theme_bw() +
            geom_segment(data = data.frame(x = pathway), mapping = aes(x = x,
                y = -diff/2, xend = x, yend = diff/2), size = ticksSize) +
            theme(panel.border = element_blank(), panel.grid.minor = element_blank()) +
            labs(x = "rank", y = "enrichment score")
        g
    }

plotEnr(examplePathways[["5991130_Programmed_Cell_Death"]], exampleRanks)

enter image description here

Upvotes: 3

Related Questions