I'm trying to overlay a line chart and bar chart in plotly (with a vertical line designating an important date) and I'm encountering this issue where the two zero lines are offset instead of on the same line. I've tried messing around with the overlaying = 'y' option within layout and tried changing the order of the three trace components but nothing seems to help. Any ideas how to fix? Below is my code with dummy data:
(Also, bonus points if you can fix my legend-overlapping-y2axis issue)
date <- seq(as.Date("2015/6/1"), by = "month", length.out = 19)
wires_mnth <- c(rep(0,8),100000,750000,1200000,2500000,3100000,5500000,7500000,8000000,9900000,11300000,11000000)
wires_cnt <- c(rep(0,8),100,200,250,325,475,600,750,800,1000,1150,1200)
data <- data.frame(date, wires_mnth)
plot_ly(data) %>%
add_trace(x = ~date, y = ~wires_cnt, type = 'bar', name = 'Wires Count',
yaxis = 'y2', opacity = .5) %>%
add_trace(x = ~date, y = ~wires_mnth, type = 'scatter', mode = 'lines', name
= 'Monthly Wires') %>%
add_trace(x = c(2016,2016), y = c(0, 12000000), type = 'scatter', mode =
"lines", name = 'Sanctions Removed') %>%
layout(title = 'Monthly Aggregate Wire Transfers to Iran',
xaxis = list(title = ''),
yaxis = list(side = 'left', title = 'Wire Amounts (USD)', showgrid =
FALSE, zeroline = FALSE),
yaxis2 = list(side = 'right', overlaying = 'y', title = 'Wires Count',
showgrid = FALSE, zeroline = FALSE)
)
You could add rangemode='nonnegative' to your layout or specify the range manually via range=list(0, max(wires_mnth).
For your bonus question, you can set the x-position of the legend, e.g.
legend = list(x = 1.2)
Related
I have a data.frame of regression coefficients with the associated p-values:
library(dplyr)
set.seed(1)
effects.df <- data.frame(contrast = paste0("C",1:5), effect = rnorm(5), stringsAsFactors = F) %>%
dplyr::mutate(effect.error = abs(effect)/sqrt(5)) %>%
dplyr::mutate(p.value = pnorm(effect/effect.error)) %>%
dplyr::arrange(p.value)
effects.df$contrast <- factor(effects.df$contrast,levels = effects.df$contrast)
Which I want to display as a forest plot (X-axis are the effect size and Y-axis are the 'contrast's), where the points and their associated error bars (effect.error) are color coded by 1-p.value, using R's plotly.
Here's what I'm trying:
library(plotly)
effects.plot <- plot_ly(x = effects.df$effect, y = effects.df$contrast, type = 'scatter', mode = "markers", marker = list(size = 8, colorbar = "Hot", color = 1-effects.df$p.value)) %>%
layout(xaxis=list(title = "Effect size",zerolinewidth = 2, zerolinecolor = plotly::toRGB('black'), showgrid = F), yaxis = list(showgrid = F)) %>%
add_trace(error_x = list(array = effects.df$effect.error, width = 5),marker = list(size = 8,colorbar = "Hot", color = 1-effects.df$p.value))
It's close because it's color-coding the points how I want them to but not the error bars.
Any idea how to:
Color the error bars similar to the points?
Get the color-bar to show?
I'm not sure that it will allow you to color the error bars separately without some (a lot) of creativity. If you created separate traces for each color, you might be able to force it to comply.
There are many ways you could show the color bar. Here's one way:
(effects.plot <- plot_ly(data = effects.df,
x = ~effect,
y = ~contrast,
error_x = list(array = ~effect.error,
width = 5,
color = "black"),
type = 'scatter',
mode = "markers",
marker = list(colorscale = "Hot",
colorbar = list(size = 8),
color = 1 - effects.df$p.value)) %>%
layout(xaxis=list(title = "Effect size",
zerolinewidth = 2,
zerolinecolor = plotly::toRGB('black'),
showgrid = F),
yaxis = list(showgrid = F)) # set the joined color axis
)
By the way, I noticed that the colors you have are gray and red, not black and white, as shown in my image. You're getting a different color scale than you were expecting.
You can see what I mean by plotting this a different way:
(effects.plot <- plot_ly(data = effects.df,
x = ~effect,
y = ~contrast,
error_x = list(array = ~effect.error,
width = 5,
color = "black"),
type = 'scatter',
mode = "markers",
marker = list(coloraxis = "coloraxis",
color = 1 - effects.df$p.value)) %>%
layout(xaxis=list(title = "Effect size",
zerolinewidth = 2,
zerolinecolor = plotly::toRGB('black'),
showgrid = F),
yaxis = list(showgrid = F),
coloraxis = list(colorbar = "Hot", size = 8))
)
This plot is not using the "Hot" color scale. That scale is shown in the first image.
The easiest way to solve this is to use ggplot2 and then to convert it to a plotly object:
Libraries and data:
library(dplyr)
library(plotly)
library(ggplot2)
set.seed(1)
effects.df <- data.frame(contrast = paste0("C",1:5), effect = rnorm(5), stringsAsFactors = F) %>%
dplyr::mutate(effect.error = abs(effect)/sqrt(5)) %>%
dplyr::mutate(p.value = pnorm(effect/effect.error)) %>%
dplyr::arrange(p.value)
Here I also add a horizontal dashed y-line to mark the p-value = 0.05 cutoff:
effects.df$contrast <- factor(effects.df$contrast,levels=effects.df$contrast)
y.intercept <- min(which(effects.df$p.value > 0.05))-0.5
pp <- ggplot(effects.df)+geom_vline(xintercept=0,color="black")+geom_point(aes(y=contrast,x=effect,color=p.value))+
geom_errorbarh(aes(y=contrast,xmin=effect-effect.error,xmax=effect+effect.error,x=effect,color=p.value,height=0.1))+
scale_color_continuous(low="darkred",high="gray")+theme_minimal()+xlab("Effect Size")+
geom_hline(yintercept=y.intercept,linetype="dashed",color="black",size=0.25)
Which gives:
And the plotly object:
ggplotly(pp)
I want to create a filled area plot with line and scatters like in the screenshot attached but I do not know how could add scatters for every year of x-axis and also annotate its value. My code is:
library(plotly)
data <- t(USPersonalExpenditure)
data <- data.frame("year"=rownames(data), data)
fig <- plot_ly(data, x = ~year, y = ~Food.and.Tobacco, name = 'Food and Tobacco', type = 'scatter', mode = 'line', stackgroup = 'one', fillcolor = '#F5FF8D')
fig
The mode lines+markers+text allows you to define a line plot with markers and add some text.
I changed the type of year from factor to numeric, because I had to expand the xaxis for readabilty of the annotations.
library(plotly)
data <- t(USPersonalExpenditure)
data <- data.frame("year" = as.numeric(rownames(data)), data)
plot_ly(data,
x = ~year,
y = ~Food.and.Tobacco,
text = ~Food.and.Tobacco) %>%
add_trace(
type = 'scatter',
mode = 'lines+markers+text',
fill = 'tozeroy',
fillcolor = '#F5FF8D',
marker = list(color = 'black'),
line = list(color = 'black'),
textposition = "top center",
hovertemplate = paste0("<b>%{x}</b>
Cummulative Food and Tobacco: %{y}
<extra></extra>"),
hoveron = 'points') %>%
layout(xaxis = list(
range= list(min(data$year) - 1, max(data$year) + 1)))
I'm trying to plot a 3D scatter using Plotly and R. Other than x, y and z I also would like to set the color of each point depending on a fourth variable.
I manage to set the plot correctly (the use of name = ~res is to show the value of res while hovering), but I am not able to change the name of the colorbar.
This is a mock code of what I've done:
library(tidyverse)
library(plotly)
a = seq(1,10,1)
b = seq(100,1000,100)
c = seq(1,4.9,0.4)
data = tibble(a,b,c)
data <- data %>% mutate(res = a+b+c)
layout_details <- list(xaxis = list(title = 'a [-]'),
yaxis = list(title = 'b [-]'),
zaxis = list(title = 'c [-]'),
coloraxis=list(colorbar=list(title=list(text='Here are the results'))))
p = plot_ly(data, x = ~a, y = ~b, z = ~c, color = ~res, type = 'scatter3d',
mode = 'markers', name = ~res, showlegend = FALSE, scene = 'scene1')
p <- p %>% layout(scene1 = layout_details)
p
I've noticed that a quite similar question was asked (R plotly to legend title value ignored for continuous color scatter plot), but without any answers.
Does anyone know how to solve this?
Thanks
You can define your colorbar inside the marker argument.
The name argument is interfering with the colorbar therefore I moved res from the name argument to the hovertemplate and the customdata.
Code
p = plot_ly(data, x = ~a, y = ~b, z = ~c,
name = "",
scene = 'scene1',
type = 'scatter3d',
mode = 'markers',
customdata = as.list(data$res),
hovertemplate = paste('x: %{x}',
'y: %{y}',
'z: %{z}',
'name: %{customdata}',
sep = "\n"),
marker = list(color = ~res,
colorbar = list(title = "Here are the results"),
colorscale='Viridis',
showscale = TRUE))
p <- p %>% layout(scene1 = layout_details)
p
Plot
This question already has answers here:
Horizontal/Vertical Line in plotly
(4 answers)
Closed 2 years ago.
I would like to add a vertical line on a special date to my plot. I am using the plot_ly() function from the plotly package in R.
p <- plot_ly(dt.allDataFvsS, x = dt.allDataFvsS$date, y = dt.allDataFvsS$meanDifference, mode = 'lines',
type = "scatter", line = list(color = " #007d3c")) %>%
layout(title = "Average Price Difference Forward vs. Spot", xaxis = list(title = "Date"),
yaxis = list(title = "EUR / MWh"))
The date has the following form: e.g. "2018-10-01" ("Y-M-D")
My plot looks like this:
PLOT
So, my question is how do I get a black vertical line at date "2018-10-01" ?
Is it also possible to have vertical lines at the beginning of each year? Or of every quarter (Jan - Apr - Jul - Oct) of each year?
I would be very happy if someone could help me? Unfortunately, after a day of browsing the internet, I couldn't find anything that worked.
As no data is provided to reproduce your issue, I would suggest next approach using add_trace() function where you define the coordinates for the line:
p <- plot_ly(dt.allDataFvsS, x = dt.allDataFvsS$date, y = dt.allDataFvsS$meanDifference, mode = 'lines',
type = "scatter", line = list(color = " #007d3c")) %>%
add_trace(x =as.Date("2018-10-01"),type = 'scatter', mode = 'lines',
line = list(color = 'black'),name = '') %>%
layout(title = "Average Price Difference Forward vs. Spot", xaxis = list(title = "Date"),
yaxis = list(title = "EUR / MWh"))
Let me know if that works!
Here is another approach based on shapes rather than adding another trace (you can see the difference when zooming out + there is no legend item for the vertical line):
library(plotly)
dates <- seq(from = as.Date("2018-08-01"), to = as.Date("2018-12-31"), by = 1)
dt.allDataFvsS <- data.frame(date = dates, meanDifference = sin(seq_along(dates)*0.1))
vline <- function(x = 0, color = "red") {
list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = x,
x1 = x,
line = list(color = color)
)
}
p <- plot_ly(dt.allDataFvsS, x = dt.allDataFvsS$date, y = dt.allDataFvsS$meanDifference, mode = 'lines',
type = "scatter", line = list(color = " #007d3c")) %>%
layout(title = "Average Price Difference Forward vs. Spot", xaxis = list(title = "Date"),
yaxis = list(title = "EUR / MWh"))
p %>% layout(shapes = list(vline(as.Date("2018-10-01"))))
Based on this answer.
I'm trying to overlay a barplot with a scatter plot in plotly. I've managed to plot both and everything looks nice using only markers, but I need to join the markers. Using lines+markers it joins every point with each other, like a closed path. I suppose the problem is that my x-axis variable is categorical and I don't know how to fix it. I can't write the original code but is something like:
to_plot2[, cat_var := as.factor(cat_var)]
pp2 = plot_ly(to_plot2) %>%
add_trace(x = ~cat_var, y = ~var_1, type = 'bar', name = 'bar',
marker = list(color = '#C9EFF9'),
hoverinfo = "text") %>%
add_trace(x = ~cat_var, y = ~var_2, type = 'scatter', mode = 'lines+markers', name = 'lines', yaxis = 'y2',
hoverinfo = "text") %>%
layout(title = 'foo',
xaxis = list(title = "", type = "category",
categoryorder = "'array'"),
yaxis = list(side = 'left', showgrid = FALSE, zeroline = FALSE),
yaxis2 = list(side = 'right', overlaying = "y", showgrid = FALSE, zeroline = FALSE))
and the output is:
Any help?
Thanks in advance
I've just solved the problem. Setting cat_var as key it reorders the dataframe in the appropiate manner.
Thanks!