4
votes

I am using plotly with Rshiny to create a scatter plot with text labels. Below is a reproducible example:

library(ggplot2)
library(plotly)
dat <- data.frame(LongExpressionValue = rnorm(1:100), 
                  LongMethylationValue = rnorm(1:100), 
                  LongCopyNumberValue = rnorm(1:100))

rownames(dat) <- paste0('n',seq(1:100))

# ggplot
p <- ggplot(data = dat, aes(x = LongExpressionValue, y = LongMethylationValue)) + 
  geom_point(size = 2) + geom_smooth(method = lm) +
  geom_text(aes(label = rownames(dat)), vjust=-1.5, size = 3)

# ggplotly
ggplotly(p)

This creates a plot like:

enter image description here

How do I adjust my geom_text options so that the labels appear above and not overlapping the points? I do want to retain my ggplot code for it to be used across applications.

Thanks!

3
Is it necessary to use ggplot2 and not call plot_ly directly? I find the solutions for those to be much easier, configs are all just lists of lists etc.. Specifically, the reference page on plotly's site allows positioning of all parts, and the hoverinfo and text options are amazingShape
What if you want to use aes_string instead of aes?Komal Rathi
I usually just use as.name if I need to work with programmatically-generated plotsShape
That's not working for me. Plus, I do want to retain my code in ggplot2 for it to be used across applications. Thanks though.Komal Rathi

3 Answers

3
votes

Try this:

plot_ly(data = dat, 
        x = LongExpressionValue, 
        y = LongMethylationValue, 
        text = rownames(dat), 
        marker = list(size = 10), 
        mode = "markers+text",
        textposition = 'top center')

it's not worth working too hard at ggplot2 when you can go directly to the source. this is invaluable: https://plot.ly/r/reference/

Everything in plot_ly or in layout is a list of lists, so you can set your parameters easily (notice marker = list(size = 10))

EDIT: A slightly more complicated one showing the power of hoverinfo + text together:

plot_ly(data = dat, 
        x = LongExpressionValue, 
        y = LongMethylationValue, 
        text = paste0(rownames(dat), 
                      '<br>A:', 1:nrow(dat), #Examples of additional text
                      '<br>B:', sample(nrow(dat))), #Examples of additional text
        hoverinfo = 'text+x+y',
        marker = list(size = 10), 
        mode = "markers+text",
        hoverinfo = 'text',
        textposition = 'top right')
1
votes

If you want to stick with ggplot2 and keep your smooth line, you could increase slightly the size of your point and add your label inside each point:

p <- ggplot(data = dat, aes(x = LongExpressionValue, y = LongMethylationValue)) + 
  geom_point(size = 7) + geom_smooth(method = lm) +
  geom_text(aes(label = rownames(dat)), size = 2, color="white")

# ggplotly
ggplotly(p)

enter image description here

1
votes

If you would like to stay in ggplot2 you have to append a textposition element to the plotly_build list. textposition is missing in the original plotly_build even if hjust and vjust options are set.

So this works:

#devtools::install_github("ropensci/plotly") # if not already done
library(ggplot2)
library(plotly) 
dat <- data.frame(LongExpressionValue = rnorm(1:100),
              LongMethylationValue = rnorm(1:100),
              LongCopyNumberValue = rnorm(1:100))

rownames(dat) <- paste0('n',seq(1:100))  

gg <- ggplot(data = dat, aes(x = LongExpressionValue, y =LongMethylationValue)) + 
geom_point(size = 1) +
geom_smooth(method = lm) +
geom_text(aes(label = rownames(dat)), size = 3)

p <- plotly_build(gg)

length<-length(p$x$data)
invisible(lapply(1:length, function(x) p$x$data[[x]]<<-c(p$x$data[[x]], textposition ='top center')))

p