Hovermode using Plotly with R - r

Is there a way to code the hovermode when using plotly with R and ggplot2?
Currently, my code is:
plot <- ggplot(data, aes(var1, var2, text=var3)) +
geom_point()
py$ggplotly(plot)
And I want the plotly graph to automatically have the hover mode set to "show closest data on hover" rather than "compare data on hover".

The answer from 'mkcor' didn't work when trying to do the same in Shiny. I kept getting an 'unused argument' error. For anyone else with the same problem, this worked for me...
Suppose this is my basic plot:
p <- ggplot(myDf, aes(x=x, y=y )) + geom_point(size = 3, shape = 0)
You can convert the ggplot object to a plotly object:
ggObj <- plotly(p)
Then you can change the hovermode like this:
layout(ggObj, hovermode = 'closest')

Add the following argument when calling ggplotly:
py$ggplotly(plot, kwargs=list(layout=list(hovermode="closest")))

Related

Display ggplotly chart without toolbar

I am trying to hide the plotly toolbar when displaying a reactive ggplot chart within a Shiny app. Currently my code looks like this:
renderPlotly( ggplot(users_activated(), aes(x = month, y = n)) +
geom_bar(stat = "identity"))
I have tried config(displayModeBar = F) to no avail.
You need to convert your ggplot object to a plotly object before you can render it as one, or use plotly functions on it. ggplotly does that. Below, is an example using mpg dataset.
ggplotly(ggplot(mpg, aes(class, displ, color = manufacturer)) +
geom_point()
) %>%
config(displayModeBar = F)

ggplotly with long names in the labels

I have data with long names which i would like to plot using ggplotly.
That's my code:
library(ggplot2)
library(plotly)
temp<-data.frame(x=c("longgggggggggggggggggggggggg_nameeeeeeeeeeeeeee1", "longggggggggggggggggggggggggg_nameeeeeeeeeeeeeee2"),
y=c(5,10))
break_str<-function(str,n){
if(nchar(str)<=n)
return(str)
ans<-""
for(i in 1:ceiling(nchar(str)/n)){
if(i<ceiling(nchar(str)/n)){
ans<-paste0(ans,substr(str,start=((i-1)*n+1),stop=min(i*n,nchar(str))),"\n")
} else{
ans<-paste0(ans,substr(str,start=((i-1)*n+1),stop=min(i*n,nchar(str))))
}
}
return(ans)
}
p <- ggplot(temp, aes(x=x, y=y)) +
labs(x="x",y="y") + geom_bar(stat="identity") + coord_flip() +
scale_x_discrete(labels = function(x) lapply(x,function(str){break_str(str,10)}))
ggplotly(p)
As you can see I use a custom break_str function which works similar to stringr::str_wrap but still it doesn't remove the margin in the plot.
This problem doesn't show up when in the ggplot version of p.
Any help would be appreciated
Thanks
Looks like you stumbled over a bug in ggplotly (maybe you should raise an issue on github). I had a look into the source code. The issue is that ggplotly does not take linebreaks in the tick labels into account when computing the margins. Hence, the margin is set too wide. This problem does not arise if you make the plot using plotly. However, as a simple workaround you can force automargin to do its job by adding the layout option margin = list(l = 0) like so:
ggplotly(p) %>%
layout(
margin = list(l = 0)
)
which results in this plot:

ggplotly fails with geom_vline() with xintercept Date value

Trying to use ggplotly to graph time series data with a vertical line to indicate dates of interest.
Call fails with Error in Ops.Date(z[[xy]], 86400000) : * not defined for "Date" objects. I have tried unsuccessfully using both the latest CRAN and development versions of ggplot2 (as per plotly recommendation). Other SO questions (e.g., ggplotly and geom_bar when using dates - latest version of plotly (4.7.0)) do not address my concerns.
As illustrated below with plot object p - both ggplot and ggplotly work as expected. However, when a geom_vline() is added to the plot in p2, it only works correctly in ggplot, failing when calling ggplotly(p2).
library(plotly)
library(ggplot2)
library(magrittr)
set.seed(1)
df <- data.frame(date = seq(from = lubridate::ymd("2019-01-01"), by = 1, length.out = 10),
y = rnorm(10))
p <- df %>%
ggplot(aes(x = date, y = y)) +
geom_line()
p ## plots as expected
ggplotly(p) ## plots as expected
p2 <- p + geom_vline(xintercept = lubridate::ymd("2019-01-08"), linetype = "dashed")
p2 ## plots as expected
ggplotly(p2) ##fails
I just solved this using #Axeman's suggestion. In your case, you can just replace the date:
lubridate::ymd("2019-01-01")
becomes
as.numeric(lubridate::ymd("2019-01-01"))
Not pretty, but it works.
For future reference:
The pop-up window for vertical lines created via date (or POSIX*) to numeric conversions is rather blank. This is particularly valid for POSIX* applications where the exact time can often not be read off directly.
In case you need more significant pop-up content, the definition of a text aesthetic could be helpful (just ignore the 'unknown aesthetics' warning as it doesn't seem to apply). Then, simply specify what you want to see during mouse hover via the tooltip argument, ie. rule out xintercept, and you're all set.
p2 = p +
geom_vline(
aes(
xintercept = as.numeric(lubridate::ymd("2019-01-08"))
, text = "date: 2019-01-08"
)
, linetype = "dashed"
)
ggplotly(p2, tooltip = c("x", "y", "text"))

How to keep the format of plot generated by ggplot while converting to plotly by ggplotly?

Assuming generating a scatter plot with ggplot which has the gradient color and shape based on the variables in mtcars built-in database in R .
using the following script adopted from Nathan Day in my previous question:
library(ggplot2)
plot<- ggplot(mtcars, aes(mpg, hp, fill = cyl, size = cyl)) +
geom_point(shape = 21, stroke = 2) +
scale_fill_gradientn(colours = rainbow(7)) +
scale_size(range = c(2,6))
we would get the following plot
Now, when I am trying to convert it to ploty using the following script :
library(plotly)
ggploty (plot)
I would get the following plot which is basically change the color and I loose my gradient colour featur in my ggplot as can be seen in previous plot generated by ggplot.
Of course I would get the interactive image BUT I was not able to upload in this page so I just take a static image of the generated ploty image.
Can you please help me to know how I can keep the original format of ggplot when converting to ploty by ggploty command?

Recreating a ggplot2 geom_point() using base graphics

I've the following ggplot2 code and I'd like to use base graphics instead of ggplot2 to generate a similiar output - but I can't seem to find a way to differentiate more than one "attribute" with the normal plot. Am I missing something:
Ggplot2:
ggplot(data.df, aes(x=Axis1, y=Axis2, shape=Plant, color=Type)) +
geom_point()
My plot attempt (the inline help got me quite some way):
data.ma <- as.matrix(data.df)
plot(range(data.ma[,6]), range(data.ma[,7]),xlab="Axis 1",ylab="Axis 2")
points(data.ma[data.ma[,1] == 'Plant1',6],
data.ma[data.ma[,1] == 'Plant1',7], pch=2)
points(data.ma[data.ma[,1] == 'Plant2',6],
data.ma[data.ma[,1] == 'Plant2',7], pch=3)
legend(0,legend=c("Plant1","Plant2"))
This gives me a plot where at least the "Plant" type can be distinguished in the plot, but it does seem far to complicated and I can't figure out how to change the color of all points depending on the "Type" row.
Any suggestions?
Edit - an example with data // where I realize that my first attempt with plot doesn't even give a correct example :( :
library(ggplot2)
data.df <- data.frame(
Plant=c('Plant1','Plant1','Plant1','Plant2','Plant2','Plant2'),
Type=c(1,2,3,1,2,3),
Axis1=c(0.2,-0.4,0.8,-0.2,-0.7,0.1),
Axis2=c(0.5,0.3,-0.1,-0.3,-0.1,-0.8)
)
ggplot(data.df, aes(x=Axis1, y=Axis2, shape=Plant, color=Type)) +
geom_point()
data.ma <- as.matrix(data.df)
plot(range(data.ma[,3]), range(data.ma[,4]),xlab="Axis 1",ylab="Axis 2")
points(data.ma[data.ma[,1] == 'Plant1',3],
data.ma[data.ma[,1] == 'Plant1',4], pch=2)
points(data.ma[data.ma[,1] == 'Plant2',3],
data.ma[data.ma[,1] == 'Plant2',4], pch=3)
legend(0,legend=c("Plant1","Plant2"))
I was just about to post this and then I saw Justin beat to much of it. In any case, this includes some rudimentary legends:
color_foo <- colorRampPalette(c('lightblue','darkblue'))
colors <- color_foo(3)
plot(range(data.df[,3]), range(data.df[,4]),
xlab="Axis 1",ylab="Axis 2",type = "n")
points(data.df$Axis1,data.df$Axis2,
pch=c(3,4)[data.df$Plant],
col = colors[data.df$Type])
legend("topright",legend=c("Plant1","Plant2"),pch = 3:4)
legend("bottomright",legend=c("Type1","Type2","Type3"),
pch = 20,col = colors)
Using base plot and your data set:
with(data.df,
plot(x = Axis1,
y = Axis2,
col = factor(Type),
pch = as.integer(factor(Plant))))
Does that do what you're looking for? I'll leave the legend as an exercise for the reader...

Resources