R: plotly graph with dual Y axis? - r

I've found this question but answer is not up to date to produce the correct result.
Second Y-Axis in a R plotly graph
How can I plot a dual y axis plot?
df <- data.frame(MediaDate = as.Date(c("2016-04-01","2016-05-01","2016-06-01"), format = "%Y-%m-%d"),
Spend = c(39654, 34446, 27402),
Visits = c(19970, 14450, 12419))
plot_ly(df, x = ~MediaDate, y = ~Spend, type = "bar", name = "Spend") %>%
add_trace(x = ~MediaDate, y = ~Visits, mode = "lines", yaxis = "y2", name = "Visits") %>%
layout(yaxis2 = list(overlaying = "y", side = "right"))
Produces:
What I need (but instead of a bar and a line, 2 lines):

Here's a way to do this:
df <- data.frame(MediaDate = as.Date(c("2016-04-01","2016-05-01","2016-06-01"),
format = "%Y-%m-%d"),
Spend = c(39654, 34446, 27402),
Visits = c(19970, 14450, 12419))
old.y <- list(
side = "left",
title = "Spend"
)
new.y <- list(
overlaying = "y",
side = "right",
title = "Visits"
)
plot_ly(df) %>%
add_lines(x = ~MediaDate, y = ~Spend, yaxis="y1") %>%
add_lines(x = ~MediaDate, y = ~Visits, yaxis = "y2") %>%
layout(yaxis2 = new.y, yaxis = old.y, xaxis = list(title="MediaDate"))

Related

R: subplot with plots that have multiple y-axis and x-axis

I am trying to draw a subplot that contains 2 plots. Each inner plots have two y-axis and two x-axis. I also want to match each y label with his lines color.
First I want to start with a simple example. Consider following code
library(plotly)
library(dplyr)
p1 <- economics %>% plot_ly()%>%
add_trace( x = ~date, y = ~unemploy,yaxis='y1',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout( yaxis2 = list(overlaying = "y1",side = "right"))
p2<-p1
>p1
The output:
subplot(p1, p2 , nrows = 2 , shareX = TRUE)
The output:
So the subplot does not work fine. How to fix it?
EDIT:
With a little change to the code as shown below and it work!
R code
library(plotly)
library(dplyr)
p1 <- economics %>% plot_ly()%>%
add_trace( x = ~date, y =~unemploy,yaxis='y',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout( yaxis = list(side = "left"),yaxis2 = list(overlaying = "y",side = "right"))
p2<-economics %>% plot_ly()%>%
add_trace( x = ~date, y = ~unemploy,yaxis='y',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout(yaxis = list(side = "left"), yaxis2 = list(overlaying = "y3",side = "right"))
subplot(p1,p2,nrows=2)
The output now is as follows:
To extend for have 3 plots:
library(plotly)
library(dplyr)
p1 <- economics %>% plot_ly()%>%
add_trace( x = ~date, y = ~unemploy,yaxis='y',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout( yaxis = list(side = "left"),yaxis2 = list(overlaying = "y",side = "right"))
p2<-economics %>% plot_ly()%>%
add_trace( x = ~date, y = ~unemploy,yaxis='y',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout(yaxis = list(side = "left"), yaxis2 = list(overlaying = "y3",side = "right"))
p3<-economics %>% plot_ly()%>%
add_trace( x = ~date, y = ~unemploy,yaxis='y',type='scatter',mode="lines+markers")%>%
add_trace(x = ~date, y = ~uempmed,yaxis='y2',type='scatter',mode="lines+markers") %>%
layout(yaxis = list(side = "left"), yaxis2 = list(overlaying = "y5",side = "right"))
subplot(p1,p2,p3,nrows=3)
The output:

Plotly: How to set a minimum value on secondary y-axis?

I want to set a minimum value on the secondary y-axis. This is my code :
library(plotly)
# my data
value <- c(300000,400000,500000,600000,500000,600000)
x1 <- c(3,4,5,5,4,3)
x2 <-c(3,4,5,5,4,3)
name <- c("martin","john","marc","igor","thea","julia")
df <- data.frame(value, x1, x2, name)
# graph with plotly
graph=df %>%
plot_ly(x = ~name) %>%
add_bars(y = ~x1,
name = "bar1") %>%
add_bars(y = ~x2,
name = "bar2") %>%
add_lines(y = ~value,
name = "line",
yaxis = "y2") %>%
layout(barmode = "bar",
yaxis2 = list(overlaying = "y",
side = "right"),
barmode = "bar",
legend = list(x = 1.1, y =1))
# showing graph
graph
and i get this :
but i want the secondary y-axis start at 200k (or 100k) instead of 300k.
How can we fix it ? Some help would be appreciated
Generally, if you've already got a fig set up:
fig <- fig %>% layout(yaxis2 = list(range = c(<min>, <max>)))
And in your specific case:
graph <- graph %>% layout(yaxis2 = list(range = c(200000,600000)))
Plot
Complete code:
library(plotly)
# my data
value <- c(300000,400000,500000,600000,500000,600000)
x1 <- c(3,4,5,5,4,3)
x2 <-c(3,4,5,5,4,3)
name <- c("martin","john","marc","igor","thea","julia")
df <- data.frame(value, x1, x2, name)
# graph with plotly
graph=df %>%
plot_ly(x = ~name) %>%
add_bars(y = ~x1,
name = "bar1") %>%
add_bars(y = ~x2,
name = "bar2") %>%
add_lines(y = ~value,
name = "line",
yaxis = "y2") %>%
layout(barmode = "bar",
yaxis2 = list(overlaying = "y",
side = "right"),
barmode = "bar",
legend = list(x = 1.1, y =1))
# showing graph
#graph
graph <- graph %>% layout(yaxis2 = list(
#scaleanchor = "x",
#scaleratio = 0.2,
range = c(200000,600000)
#title = "1:5"
))
graph

Change order of subplots

Is there a way to change the order of subplots in plotly for R? Is there a way to manually change the levels of a factor in this code?
I want a plot with Weight in the first plot followed by a,b,c in order above it. But what I get as output is Weight, c, a and b as shown in the image graph
Here is my code
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", id)
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
One way to do this is re-ordering factor levels as below:
# set.seed to keep the exact same results
set.seed(123)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
DF <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable)))
DF$variable <- factor(DF$variable, levels = c("Weight", "a", "b", "c")) #re-order
q <- DF %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", sort(id, decreasing =F))) %>% #sort the order
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
q
You will need sort(id, decreasing =F) to get exact same order of what you set in factor(DF$variable, levels = c("Weight", "a", "b", "c")).
Exchange the data, the name, and the line features of the top and bottom subplots as following code,
#assign q$x$data to one template variable p
p = q$x$data
#exchange the data, name, and line features of q$x$data[[1]] and q$x$data[[4]]
q$x$data[[1]]$x = p[[4]]$x
q$x$data[[1]]$y = p[[4]]$y
q$x$data[[1]]$name = p[[4]]$name
q$x$data[[1]]$line = p[[4]]$line
q$x$data[[4]]$x = p[[1]]$x
q$x$data[[4]]$y = p[[1]]$y
q$x$data[[4]]$name = p[[1]]$name
q$x$data[[4]]$line = p[[1]]$line
#show
q
The problem might have been caused by yaxis = ~paste0("y", id). I replaced it with yaxis = ~paste0(id, "y") to get the correct order. You may need to change some code to get the right format.
library(plotly)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0(id, "y")
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df), shareX = TRUE)
q

managing colors in R for plot.ly

I am using the plot.ly library for interactive charting in a shiny app however I am running up against some trouble with managing the colors in the chart.
Reproducible example using plotly 4.3.5 (from github):
library(data.table)
library(plotly)
dt <- data.table(campaign_week = c(1,2,3,1,2,3), category = c(rep("income",3),rep("cost",3)),
amount = c(100,50,35,-500,-20,-15))
dt_net <- dt[, .(amount = sum(amount)), by = campaign_week][,.(campaign_week, amount = cumsum(amount))]
y <- list(title = "Income", tickformat = "$,.0f",hoverformat = "$,.2f")
plot_ly(dt_net, x = ~campaign_week, y = ~amount, type = "scatter",
mode= "lines+markers",
line = list(color = "#00AEFF"), name = "Net Income") %>%
add_trace(data = dt, x = ~campaign_week, y = ~amount, color = ~category, type = "bar",
colors = c("#00ff00", "#ff0000")) %>%
layout(yaxis = y, barmode = "relative")
This creates the chart that I want, however the colours aren't being applied correctly to the trace. I am expecting one of the bars to be red, and the other to be green while the line is a shade of blue.
EDIT Add a screenshot of the plotly chart created
Based on the example at https://plot.ly/r/bar-charts/#bar-chart-with-relative-barmode a separate add_trace for each category is the way to go.
plot_ly(dt_net, x = ~campaign_week, y = ~amount, type = "scatter",
mode= "lines+markers",
line = list(color = "#00AEFF"), name = "Net Income") %>%
add_trace(data = dt[category=="income",] , x = ~campaign_week, y = ~amount, type = "bar", name = "income",
marker=list(color = "#00ff00")) %>%
add_trace(data = dt[category=="cost",] , x = ~campaign_week, y = ~amount, type = "bar", name = "cost",
marker=list(color = "#ff0000")) %>%
layout(yaxis = y, barmode = "relative")
Note, this gives a warning, because the bar chart traces inherit mode and line attributes from the scatter chart, but these attributes are not supported for bars. You can either ignore the warnings, or you can call the barchart before the scatter to avoid them... Like this:
plot_ly() %>%
add_trace(data = dt[category=="income",] , x = ~campaign_week, y = ~amount, type = "bar", name = "income",
marker=list(color = "#00ff00")) %>%
add_trace(data = dt[category=="cost",] , x = ~campaign_week, y = ~amount, type = "bar", name = "cost",
marker=list(color = "#ff0000")) %>%
add_trace(data = dt_net, x = ~campaign_week, y = ~amount, type = "scatter", mode= "lines+markers",
line = list(color = "#00AEFF"), name = "Net Income") %>%
layout(yaxis = y, barmode = "relative")
I reverted the calls and added the inherit=FALSE:
library(data.table)
library(plotly)
dt <- data.table(campaign_week = c(1,2,3,1,2,3), category = c(rep("income",3),rep("cost",3)),
amount = c(100,50,35,-500,-20,-15))
dt_net <- dt[, .(amount = sum(amount)), by = campaign_week][,.(campaign_week, amount = cumsum(amount))]
y <- list(title = "Income", tickformat = "$,.0f",hoverformat = "$,.2f")
plot_ly(data=dt, x = ~campaign_week, y = ~amount, color = ~category, type = "bar",
colors = c("#00ff00", "#ff0000")) %>%
add_trace( data=dt_net, x = ~campaign_week, y = dt_net$amount, type = "scatter",
mode= "lines+markers",
line = list(color = "#00AEFF"), name = "Net Income", inherit=FALSE) %>%
layout(yaxis = y, barmode = "relative")
Still have a problem with the legend:

Plot.ly Double- Axis Formatting Content in R

I am having trouble formatting an axis using Plot.ly Double Axis graph. I am trying to get one of the y-axis to contain the '$' symbol in front of the number but I wasn't able to find any code for this. Hope someone can help me figure this out.
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right"
)
p <- plot_ly(data = df, x = days, y = sales, name = "Sales",type="bar") %>%
add_trace(x = days, y = Sales/Day, name = "Sales/Day", yaxis = "y2") %>%
layout(title = "Double Y Axis", yaxis2 = ay)
So in the above code I want to add a '$' symbol to both y axes (Sales and Sales/day).
Since you did not provide a reproducible example, I will use an example from the plotly website. You could try:
library(plotly)
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right"
)
plot_ly(x = 1:3, y = 10*(1:3), name = "slope of 10") %>%
add_trace(x = 2:4, y = 1:3, name = "slope of 1", yaxis = "y2") %>%
layout(title = "Double Y Axis", yaxis2 = ay, yaxis = list(showtickprefix = "all", tickprefix = "$"))

Resources