Is it possible to create an interactive scatter plot between two variables (selected by user from multiple variables) in R, without using shiny. An example is here using shiny. Is it possible to make such interactive plot without using shiny?(For example using Rmarkdown)
An example is here that use one button to select a variable using a button on plotly:
library(plotly)
df <- data.frame(x = 1:5, y = 7:11, z = 10:14)
create_buttons <- function(df, y_axis_var_names) {
lapply(
y_axis_var_names,
FUN = function(var_name, df) {
button <- list(
method = 'restyle',
args = list('y'
, list(df[, var_name]))
, label = sprintf('Show %s', var_name)
)
},
df
)
}
y_axis_var_names <- colnames(df)
p <- plot_ly(df, x = ~x, y = ~y, mode = "markers", name = "A", visible = T) %>%
layout(
title = "Drop down menus - Styling",
xaxis = list(title = "x"),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = create_buttons(df, y_axis_var_names)
)
))
p
But I do not know how to add a second button to the second variable!
Related
I've created a graph that lets you pick which group's data to plot. I'd like to change the title when you pick the group, but I'm not sure how or if its possible. I'm having trouble learning which way to structure lists for certain plotly parameters. Even if I could add custom text to graph would probably work.
#Working Example so Far
library(plotly)
x <- c(1:100)
random_y <- rnorm(100, mean = 0)
random_y_prim <- rnorm(100, mean = 50)
mydata <- data.frame(x, random_y, random_y_prim, group = rep(letters[1:4], 25))
# Make Group List Button
groupList <- unique(mydata$group)
groupLoop <- list()
for (iter in 1:length(groupList)) {
groupLoop[[iter]] <- list(method = "restyle",
args = list("transforms[0].value", groupList[iter]),
label = groupList[iter])
}
# Set up Axis labeling
f <- list(
family = "Verdana",
size = 18,
color = "#7f7f7f"
)
xLab <- list(
title = "x Axis",
titlefont = f
)
yLab <- list(
title = "y Axis",
titlefont = f
)
fig <- plot_ly(mydata, x = ~x, y = ~random_y
, type = 'scatter', mode = 'lines',
transforms = list(
list(
type = 'filter',
target = ~mydata$group,
operation = '=',
value = groupList[1]
)
)
)
fig <- fig %>%
layout(
title = "Updating Practice",
xaxis = xLab,
yaxis = yLab,
updatemenus = list(
list(
type = 'dropdown',xanchor = 'center',
yanchor = "top",
active = 1,
buttons = groupLoop
)
)
)
fig
I want to add annotations with shapes in Highcharter
Here is my data
data <- data.frame(a=c(1:12), b=runif(12, 1, 100))
I want to do this columns with some annotations shapes
columns with multiple annotations shapes
I have already take reference with Highcharter annotation on date x-axis not working - R and Highcharter - add multiple text annotations
but I still can't make it, here is my example code
library(highcharter)
hc <- highchart() %>%
hc_add_series(data, type='column', hcaes(a,b), marker=list(enabled=FALSE))
hc %>%
hc_annotations(
list(
shapes = list(
list(
point = list(
x = data$a[5],
y = data$b[5],
xAxis = 0,
yAxis = 0
),
type = 'circle'
)
)
)
)
Thank you for considering my request!
Try it:
library(highcharter)
data <- data.frame(a=c(1:12), b=runif(12, 1, 100))
hc <- highchart() %>%
hc_add_series(data, type='column', hcaes(a,b), marker=list(enabled=FALSE))
hc<-hc%>%
hc_add_annotation(
labels = list(
list(
point = list(
xAxis =0 ,
yAxis =0 ,
x =data$a[5],
y = data$b[5],
xAxis=0,
yAxis=0
),
text = "Is it OK?"
)
)
)
hc%>%
hc_add_annotation(
shapes=list(
list(
point=list(
x=data$a[5],
y=data$b[5],
xAxis=0,
yAxis=0),
type= 'circle',
r=10)))
I want to create an interactive plotly 3d scatter with markers and lines in R. The graphic should be able to highlight individual traces, which is working. It should also be able to change the color according to other variables.
Here is an example of what I want to do, the highlighting works fine, changing the color does not work:
library(plotly)
irs <- data.table(iris)
setkey(irs, `Species`)
p <- plot_ly(type = "scatter3d", mode = "lines+markers")
for (i in levels(irs$Species)) {
xx <- irs[i]$Sepal.Length
yy <- irs[i]$Sepal.Width
zz <- irs[i]$Petal.Length
cc <- irs[i]$Petal.Width
p <- p %>% add_trace(x = xx, y = yy, z = zz, color = cc)
}
p <- p %>%
layout(
updatemenus = list(
## set opacity per trace to highlight a single trace
list(y = 0.6,
buttons = lapply(
levels(irs$Species),
function (x) {
list(method = "restyle",
args = list("opacity",
ifelse(levels(irs$Species) == x,
1, 0.1)),
label = x)
})),
## try to set different colors for points inside traces
## NOT WORKING
list(y = 0.4,
buttons = lapply(
names(irs),
function(x) {
list(
method = "restyle",
args = list(
"color",
split(irs[[x]], irs$Species)
),
label = x
)
}))
)
)
p
The following code solves only a small part of your problem: how to change colors of markers and lines for a single series.
I did not find a solution for the case with multiple series.
In addition, I did not find a way for an automatic rescaling of the color map after changing the color variable from the menu. Hence, I rescaled "by hand" all variables between 1 and 3.
I realise that this is a small contribution to the solution of the problem. Anyway, I hope it can help you.
library(plotly)
library(scales)
irs <- iris
irs[,1:4] <- apply(irs[,1:4],2, rescale, to=c(1,3))
p <- plot_ly(data = irs, type = "scatter3d", mode = "lines+markers")
p <- p %>% add_trace(x=~Sepal.Length, y=~Sepal.Width,
z=~Petal.Length, color=~Petal.Width)
p <- p %>%
layout(
updatemenus = list(
list(y = 0.4,
buttons = lapply(
names(irs),
function(x) {
cols <- as.numeric(irs[,x])
list(
method = "restyle",
label = x,
args = list(
list(marker.color=list(cols),
line.color=list(cols), autocolorscale=TRUE)
)
)
}))
)
)
p
I used plotly to create a plot with multiple annotations. This is my code and it works as intended:
library(plotly)
a <- 1:10
b <- 1:10
data <- data.frame(a,b)
annotations <- list(x = a[3:4],
y = b[3:4],
text = c("p1","p2"),
showarrow = TRUE)
p <- plot_ly(data = data, x = ~a, y = ~b, type = "scatter", mode = "lines")
p <- layout(p, annotations = annotations)
p
But I can't figure out how to properly implement buttons to turn the annotations on and off. My code below implements buttons, but when I use them, only one arrow is shown, that is out of place and has no text.
library(plotly)
a <- 1:10
b <- 1:10
data <- data.frame(a,b)
annotations <- list(x = a[3:4],
y = b[3:4],
text = c("p1","p2"),
showarrow = TRUE)
updatemenus <- list(
list(
type= 'buttons',
buttons = list(
list(
label = "ON",
method = "update",
args = list(list(),
list(annotations = list(annotations)))),
list(
label = "OFF",
method = "update",
args = list(list(),
list(annotations = list(c()))))
)
)
)
p <- plot_ly(data = data, x = ~a, y = ~b, type = "scatter", mode = "lines")
p <- layout(p, updatemenus = updatemenus)
p
It would be nice if anyone could help me out here, or show me some alternative way to implement annotations that can be toggled.
You could use a for loop or lapply. For example:
library(plotly)
a <- 1:10
b <- 1:10
text <- LETTERS[seq(1,10)]
data <- data.frame(a,b,text)
annotations = list()
for (i in 1:length(data[,1])) {
annotation <- list(x = data$a[i],
y = data$b[i],
text = data$text[i],
showarrow = TRUE)
annotations[[i]] <- annotation
}
updatemenus <- list(
list(
type= 'buttons',
buttons = list(
list(
label = "ON",
method = "update",
args = list(list(),
list(annotations = annotations))),
list(
label = "OFF",
method = "update",
args = list(list(),
list(annotations = list(c()))))
)
)
)
p <- plot_ly(data = data, x = ~a, y = ~b, type = "scatter", mode = "lines")
p <- layout(p, annotations = annotations, updatemenus = updatemenus)
p
I am not sure if this is possible, but here is what I would like to do. I would like to update the data in a plotly plot by selecting from a dropdown menu.
As a simple example, let's assume I have a data frame
df <- data.frame(x = runif(200), y = runif(200), z = runif(200))
from which I use df$x and df$y in a scatter plot. Two scenarios of data manipulation I would like to achieve using a dropdown:
Replace df$y with df$z
Plot only the first n values of df$x and df$y
I looked at the following two examples, which I can easily reproduce:
https://plot.ly/r/dropdowns/
However, I have no idea how to pass the information regarding the data to be plotted based on the dropdown selection. For scenario 2 e.g. I have tried it with args = list("data", df[1:n,]) which did not work.
For scenario 1 the (only?) way to go (according to the examples) seems to be hiding/showing the traces respectively. Is that the only way for scenario 2 as well?
Any alternative ideas?
Update 1: Add reproducible example
So here is an example which achieve what I would like in scenario 1.
require(plotly)
df <- data.frame(x = runif(200), y = runif(200), z = runif(200))
Sys.setenv("plotly_username"="xxx") #actual credentials replaced
Sys.setenv("plotly_api_key"="xxx") #actual credentials replaced
p <- plot_ly(df, x = df$x, y = df$y, mode = "markers", name = "A", visible = T) %>%
add_trace(mode = "markers", y = df$z, name = "B", visible = T) %>%
layout(
title = "Drop down menus - Styling",
xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = list(
list(method = "restyle",
args = list("visible", list(TRUE, TRUE)),
label = "Show All"),
list(method = "restyle",
args = list("visible", list(TRUE, FALSE)),
label = "Show A"),
list(method = "restyle",
args = list("visible", list(FALSE, TRUE)),
label = "Show B")))
))
plotly_POST(p)
Result here: https://plot.ly/~spietrzyk/96/drop-down-menus-styling/
This is based on the example from https://plot.ly/r/dropdowns/
However, I am wondering if one could pass the data to be plotted instead of triggering changes to the visible property of individual traces.
The one thing I tried was the following:
p <- plot_ly(df, x = df$x, y = df$y, mode = "markers", name = "A", visible = T) %>%
layout(
title = "Drop down menus - Styling",
xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = list(
list(method = "restyle",
args = list("y", df$y),
label = "Show A"),
list(method = "restyle",
args = list("y", df$z),
label = "Show B")))
))
Result here: https://plot.ly/~spietrzyk/98/drop-down-menus-styling/
This approach cannot work, as the data from df$z is not posted to the grid (https://plot.ly/~spietrzyk/99/).
So I was wondering is there anyway to manipulate the data to be plotted based on dropdown selection, beyond plotting all traces and than switching the visible property by dropdown selections.
Is this what you were after?
require(plotly)
df <- data.frame(x = runif(200), y = runif(200), z = runif(200))
p <- plot_ly(df, x = ~x, y = ~y, mode = "markers", name = "A", visible = T) %>%
layout(
title = "Drop down menus - Styling",
xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = list(
list(method = "restyle",
args = list("y", list(df$y)), # put it in a list
label = "Show A"),
list(method = "restyle",
args = list("y", list(df$z)), # put it in a list
label = "Show B")))
))
p
On the top of #jimmy G's answer.
You can automatically create the buttons so that you don't have to manually specify every single variable you want in the plot.
library(plotly)
df <- data.frame(x = runif(200), y = runif(200), z = runif(200), j = runif(200), k = rep(0.7, 200), i = rnorm(200,0.6,0.05))
create_buttons <- function(df, y_axis_var_names) {
lapply(
y_axis_var_names,
FUN = function(var_name, df) {
button <- list(
method = 'restyle',
args = list('y', list(df[, var_name])),
label = sprintf('Show %s', var_name)
)
},
df
)
}
y_axis_var_names <- c('y', 'z', 'j', 'k', 'i')
p <- plot_ly(df, x = ~x, y = ~y, mode = "markers", name = "A", visible = T) %>%
layout(
title = "Drop down menus - Styling",
xaxis = list(domain = c(0.1, 1)),
yaxis = list(title = "y"),
updatemenus = list(
list(
y = 0.7,
buttons = create_buttons(df, y_axis_var_names)
)
))
p
Hope you find it useful.