I am a newcomer to the plot_ly package and am trying to produce a time series line plot with two variables on the y axis.
In my dataframe 'baro' I have 'DateTime' variable in POSIXct format, and 'Pressure' and 'Temperature' in numeric format.
I am basing my code off the example given here: https://plot.ly/r/multiple-axes/
p <- plot_ly(baro)
add_trace(p, x = ~DateTime, y = ~Pressure, type = "scatter",
mode = "lines", name = "Pressure")
add_trace(p, x = ~DateTime, y = ~Temperature, type = "scatter",
mode = "lines", name = "Temperature", yaxis = "y2")
layout(p,
title = "Pressure & Temperature", yaxis2 = ay,
xaxis = list(title="x")
)
This outputs a set of axes labelled -1 to 6 on the x axis and -1 to 4 on the y axis with no data plotted.
I prefer use pipes %>% rather than attribute an object to a plot.
When you have 2 Y-axis it's nice to set the layout of every one explicitly.
This should do what you want:
# Build randon data
set.seed(123)
baro = data.frame(DateTime = as.POSIXct(1:10,origin = "2019-01-01"),
Pressure = sample(1000:2000,10),
Temperature = sample(20:60,10)
)
# Build plot
baro %>%
plot_ly(type = "scatter", mode = "lines") %>%
add_trace(x = ~DateTime, y = ~Pressure, name = "Pressure")%>%
add_trace(x = ~DateTime, y = ~Temperature, name = "Temperature", yaxis = "y2") %>%
layout(title = "Pressure & Temperature",
yaxis = list(title = "Pressure"),
yaxis2 = list(title = "Temperature",
overlaying = "y",
side = "right"
)
)
Here the output:
Best regards.
Related
When using plotly (in R), after combining subplots there remains an unused and blank subplot. I've recreated the issue using the ggplot2 dataset mpg below.
library(dplyr)
library(ggplot2)
library(plotly)
audi <- mpg %>%
filter(manufacturer == "audi")
chevy <- mpg %>%
filter(manufacturer == "chevrolet")
fig1 <- plot_ly(audi, x = ~hwy, y = ~year, name = "", type = 'scatter',
mode = "markers", marker = list(color = "blue", symbol = 'x-dot'))
fig2 <- plot_ly(chevy, x = ~hwy, y = ~year, name = "", type = 'scatter',
mode = "markers", marker = list(color = "red", symbol = 'circle'))
fig <- subplot(fig1, fig2)
fig <- fig %>% subplot(shareX = TRUE,shareY = TRUE,which_layout = "merge")
fig <- fig %>% layout(
title = "Audi and Chevy",
xaxis = list(title = "Highway MPG"),
yaxis = list(title = "Year"),
margin = list(l = 100)
)
The only solution I've been able to find is tinkering with the width of the used subplot, but this leaves quite a bit of unused white space on the right and causes the title to be far off to the right (as it adjusts into the center of the used and unused subplots).
Is there a way to remove the unused subplot? If not, is there a way to organize/subset the dataframe such that only one plot needs to be used in the first place?
Thanks!
You can assign the colours based on the manufacturer column:
data.subs <- mpg %>%
filter(manufacturer == "audi" | manufacturer == "chevrolet")
fig <- plot_ly(data.subs, x = ~hwy, y = ~year, name = "",
type = 'scatter', mode = "markers",
marker = list(color = factor(data.subs$manufacturer,
labels = c("red", "blue")),
symbol = 'circle'),
text = factor(data.subs$manufacturer,
labels = c("audi", "chevy")), hoverinfo = 'text'))
fig <- fig %>% layout(
title = "Audi and Chevy",
xaxis = list(title = "Highway MPG"),
yaxis = list(title = "Year"),
margin = list(l = 100)
)
fig
This makes generating multiple subplots unnecessary.
I want to rename labels in a heatmap. for example:
instead of the label says "x:", I want the label to say "Hour:"
instead of the label says "y:", I want the label to say "Day:"
Library(plotly)
p <- plot_ly(z = volcano, colors = colorRamp(c("red", "green")), type = "heatmap")
furthermore, it would be useful, for example if we use a transformation of data in order to intensify contrast, still the html interactive label show real data.
Example
What about
library(plotly)
dat <- expand.grid(x = 1:nrow(volcano), y = 1:ncol(volcano))
dat$z <- c(volcano)
plot_ly(height = 500) %>%
layout(autosize = FALSE,
xaxis=list(title = "Hour", titlefont = list(size=20)),
yaxis=list(title = "Day", titlefont = list(size=20))) %>%
add_trace(data = dat, x = ~x, y = ~y, z = ~z, type = "heatmap",
hoverinfo = 'text',
text = ~paste("Hour:", dat$x,
"<br> Day:", dat$y,
"<br> z:", dat$z))
I'm trying to make a CPU Usage graph with Plotly and R, I want the max usage (100%, the blue bar) on top, and the other one on bottom, but when I try this code
plot_ly( x = cores, y = max, type = 'bar', name = 'Free') %>%
add_trace( y = data, name = 'Used') %>%
layout(
title = "CPU Usage",
font = list(family = 'Comic Sans MS'),
yaxis = list(title = 'Percent'),
xaxis = list(title = '', tickangle = -45),
barmode = 'stack')
})
It gives me the reverse, ordering the greater bar on bottom, and the orange one on top. I want to invert it.
I searched on some references but nothing was found about that...
We do not know your data but:
cores <- c("Average", "Core1", "Core2", "Core5")
Free <- c(65, 60, 80,50)
Used <- c(100-65, 40, 20,50)
data <- data.frame(cores, Free, Used)
plot_ly(data, x = ~cores, y = ~Used, type = 'bar', name = 'Used') %>%
add_trace(y = ~Free, name = 'Free') %>%
layout(yaxis = list(title = '%'), barmode = 'stack')
I have written below snippet of code to plot dual-axis charts using plotly in R.
Code:
## Date creation
dtMasterWithtotals <- data.table("Period_Month" = c('7/1/2017', '9/1/2017'), A = c(171, 448), B = c(0, 655), C = c(476, 812))
## Vectors to select categories for primary and secondary axis
vecPrimaryAxis <- c("A", "B")
vecSecondaryAxis <- c("C")
## X-axis properties
ax <- list(
type = "category",
categoryorder = "array",
categoryarray = dtMasterWithtotals[order(as.Date(dtMasterWithtotals[, Period_Month])),],
showgrid = TRUE,
showline = TRUE,
autorange = TRUE,
showticklabels = TRUE,
ticks = "outside",
tickangle = 0
)
## arrange columns in an order – TBD
## The plot function below assumes that the data will be in format, Period_Month, A, B,C.
## Plot function
plot <- plot_ly(dtMasterWithtotals, x = ~Period_Month, y = dtMasterWithtotals[[2]], type = "scatter", mode = 'lines', name = names(dtMasterWithtotals)[2])
if(length(vecPrimaryAxis) > 1){
t <- (3 + length(vecPrimaryAxis) - 2)
for (i in 3:t){
plot <- add_trace(plot, x = ~Period_Month, y = dtMasterWithtotals[[i]], type = "scatter", mode = "lines", name = names(dtMasterWithtotals)[i]) %>%
layout(xaxis = ax)
}
}
if(length(vecSecondaryAxis) > 0){
p <- 2 + length(vecPrimaryAxis)
q <- p + length(vecSecondaryAxis) - 1
for (j in (p:q)){
plot <- add_trace(plot, x = ~Period_Month, y = dtMasterWithtotals[[j]], type = "scatter", mode = "lines", yaxis = "y2", name = names(dtMasterWithtotals)[j]) %>%
layout(yaxis2 = list(overlaying = "y", side = "right"), xaxis = ax)
}
}
When trying to plot A and B on primary y-axis and C on secondary y-axis, the last trace (in this case C) overlaps the second trace (in this case B), resulting in two traces instead of three. However, on hover the new trace shows the correct value labels, but comes up incorrectly (at the wrong position) in the visualization.
Let me know if you require any other detail.
Thanks.
If I understand correctly what you want, in fact, there is no problem with your code. You just need to set manually your y and y2 axis. To make it easier to visualize I simply reversed the y2 axis. If you try this:
plot_ly() %>%
add_lines(data=dtMasterWithtotals, x = ~Period_Month, y = ~A, name = "A") %>%
add_lines(data=dtMasterWithtotals, x = ~Period_Month, y = ~B, name = "B") %>%
add_lines(data=dtMasterWithtotals, x = ~Period_Month, y = ~C, name = "C", yaxis = "y2") %>%
layout(xaxis = ax, yaxis2 = list(overlaying = "y", side = "right", autorange="reversed"))
It will give you this:
As you can see, all three lines are visible and all three displayed the right values.
I have spent time researching with no direction on how to create an orbit chart
I would ideally like to be able to create interactive versions (such as Plotly) but a ggplot2 would suffice as well.
Any suggestions are much appreciated!
For a weekly vis contest some time ago, I created some charts like this. I think the commonly accepted term now is "connected scatterplot".
Here is the skeleton plotly code I used.
plot_ly(
df,
x = x_var,
y = y_var,
group = group_var,
mode = "markers") %>%
add_trace(
x = x_var,
y = y_var,
xaxis = list(title = ""),
yaxis = list(title = ""),
group = group_var,
line = list(shape = "spline"),
showlegend = FALSE,
hoverinfo = "none")
You can look at the github repo for my submission which includes the code for both ggplot and plotly to produce connected scatterplots.
Using ggplot2:
geom_path() connects the observations in the order in which they appear in the data. geom_line() connects them in order of the variable on the x axis.
Taken from the ggplot manual page: http://docs.ggplot2.org/current/geom_path.html
You may also try out geom_curve and geom_segment if you want more control.
Thanks to #Bishop, I was able to formulate something really close to my ideal orbit chat. I included some chart annotations, for the start and end date and a label for which direction is the optimal solution.
max_date <- final_data_grp[which.max(final_data_grp$week_num), ]
min_date <- final_data_grp[which.min(final_data_grp$week_num), ]
end <- list(
x = max_date$AreaWOH,
y = max_date$SLevel,
text = paste('End', max_date$MondayDate),
xref = "x",
yref = "y"
)
start <- list(
x = min_date$AreaWOH,
y = min_date$SLevel,
text = paste('Start', min_date$MondayDate),
xref = "x",
yref = "y"
)
best_label = list(
x = min(final_data_grp$AreaWOH),
y = max(final_data_grp$SLevel),
text = 'Best Scenario',
showarrow = FALSE,
bordercolor='#c7c7c7',
borderwidth=2,
borderpad=4,
bgcolor='#ff7f0e',
opacity=.7
)
plot_ly(
final_data_grp,
x = AreaWOH,
y = SLevel,
group = MondayDate,
showlegend = FALSE,
marker = list(size = 8,
color = 'black',
opacity = .6)) %>%
add_trace(
x = AreaWOH,
y = SLevel,
line = list(shape = "spline"),
hoverinfo = "none",
showlegend = FALSE) %>%
layout(annotations = list(start, end, best_label))