Problem with plotly Charts Being Deprecated in RStudio - r

I'm trying to get familiar with plotly's functionality and syntax and have tried several of the scripts provided to compose and render plots of data. However, when generating the plotly output using RStudio I'm getting the following error: "Warning message:
Specifying width/height in layout() is now deprecated.
Please specify in ggplotly() or plot_ly()"
The output image appears jumbled and uninterpretable in the RStudio console and I've tried a few changes like setting the plotly object's width and height equal to null etc without luck.
Here is one of the sample scripts I've used when experiencing this issue:
library(plotly)
trace1 <- list(
x = c("Aug-12", "Sep-12", "Oct-12", "Nov-12", "Dec-12", "Jan-12", "Feb-13", "Mar-13", "Apr-13", "May-13", "Jun-13", "Jul-13"),
y = c(65, 77, 112, 279, 172, 133, 152, 106, 79, 225, 99, 150),
hoverinfo = "x+y+name",
line = list(
color = "#5BC075",
width = "3"
),
mode = "lines",
name = "Median deal size",
type = "scatter",
uid = "a8e83b",
xsrc = "jackluo:508:b357d2",
ysrc = "jackluo:508:d19900"
)
trace2 <- list(
x = c("Aug-12", "Sep-12", "Oct-12", "Nov-12", "Dec-12", "Jan-12", "Feb-13", "Mar-13", "Apr-13", "May-13", "Jun-13", "Jul-13"),
y = c(116, 125, 126, 125, 244, 136, 80, 82, 89, 82, 95, 107),
hoverinfo = "x+y+name",
line = list(
color = "#CC6E55",
width = "3"
),
mode = "lines",
name = "Number of deals",
type = "scatter",
uid = "2be33b",
xsrc = "jackluo:508:b357d2",
ysrc = "jackluo:508:5d533d"
)
data <- list(trace1, trace2)
layout <- list(
autosize = TRUE,
font = list(
family = "Overpass",
size = 12
),
height = 720,
legend = list(
x = 0,
y = -0.1,
bgcolor = "rgba(255, 255, 255, 0)",
orientation = "h"
),
margin = list(
r = 40,
t = 40,
b = 40,
l = 40,
pad = 2
),
title = "",
width = 1280,
xaxis = list(
autorange = TRUE,
nticks = 12,
range = c(0, 11),
rangemode = "tozero",
type = "category"
),
yaxis = list(
autorange = TRUE,
range = c(0, 293.6842105263158),
rangemode = "tozero",
type = "linear"
)
)
p <- plot_ly()
p <- add_trace(p, x=trace1$x, y=trace1$y, hoverinfo=trace1$hoverinfo, line=trace1$line, mode=trace1$mode, name=trace1$name, type=trace1$type, uid=trace1$uid, xsrc=trace1$xsrc, ysrc=trace1$ysrc)
p <- add_trace(p, x=trace2$x, y=trace2$y, hoverinfo=trace2$hoverinfo, line=trace2$line, mode=trace2$mode, name=trace2$name, type=trace2$type, uid=trace2$uid, xsrc=trace2$xsrc, ysrc=trace2$ysrc)
p <- layout(p, autosize=layout$autosize, font=layout$font, height=layout$height, legend=layout$legend, margin=layout$margin, title=layout$title, width=layout$width, xaxis=layout$xaxis, yaxis=layout$yaxis)
p$x$layout$width <- NULL
p$x$layout$height <- NULL
p$width <- NULL
p$height <- NULL
p
Any help resolving this issue so charts are correctly scaled and legible would be much appreciated!

As #NoahOlsen suggested, you need to format your x-axis values as a date.
trace1$x <- as.Date(paste0("01-", trace1$x), format = "%d-%b-%y")
trace2$x <- as.Date(paste0("01-", trace2$x), format = "%d-%b-%y")
Explanation
as.Date() tries to format an input into a date object. It works well with ISO date strings (e.g., 2019-04-21), but needs some help with more tricky formats.
From ?strptime:
%d - Day of the month as decimal number (01–31).
%b - Abbreviated month name in the current locale on this platform. (Also matches full name on input: in some locales there are no abbreviations of names.)
%Y - Year with century. Note that whereas there was no zero in the original Gregorian calendar, ISO 8601:2004 defines it to be valid (interpreted as 1BC): see https://en.wikipedia.org/wiki/0_(year). Note that the standards also say that years before 1582 in its calendar should only be used with agreement of the parties involved. For input, only years 0:9999 are accepted.
Furthermore, we also need a specific day of the month. As it does not exist in your data, I added 01- via paste0() to every value of the date vector. Other values, such as 15-, would also have been a valid choice (depending on your data and what type of output you expect). This way, we can make the function recognize your date via format = "%d-%b-%y".
Check out ?as.Date and ?strptime for more information. Ping me if you require further guidance. Happy to help.

It looks like your X axis is a character rather than a date so the axis is sorted alphabetically rather than chronologically. I would try making the x values dates.

Related

R Apexcharter: Formatting tooltip

I created an areaRange plot with the dreamRs apexcharter package and have a few issues formatting the hoverlabel/tooltip.
This is my sample code:
First, I installed the dreamRs apexcharter version using this:
#install.packages("remotes")
#remotes::install_github("dreamRs/apexcharter")
And then I loaded the following packages:
library(dplyr)
library(apexcharter)
The apexcharter version I have now is: apexcharter_0.3.1.9200
This is my example data:
test_data <- data.frame(seq(as.POSIXct('2022/09/04 22:00:00'), as.POSIXct('2022/09/08 10:00:00'), by="hour"))
test_data$MIN <- runif(n = 85, min = 70, max = 100)
test_data$MEDIAN <- runif(n = 85, min = 100, max = 120)
test_data$MAX <- runif(n = 85, min = 120, max = 150)
colnames(test_data) <- c("Date", "MIN", "MEDIAN", "MAX")
And this is my plot so far:
axc_plot <- apex(data = test_data, # plot the area range
mapping = aes(x = test_data[20:60,]$Date,
ymin = test_data[20:60,]$MIN,
ymax = rev(test_data[20:60,]$MAX)),
type = "rangeArea",
serie_name = "Vertrauensbereich") %>%
add_line(mapping = aes(x = Date, y = MEDIAN), # add the line
type = "line",
serie_name = "Median") %>%
ax_colors("lightblue", "red") %>% # why is the line not red?
ax_labs(x = "Zeit [h]",
y = "Q [m³/s]") %>%
ax_tooltip(enabled = T,
shared = T, # I want it shared but it's not
x = list(format = "dd.MM. HH:mm"), # changes grey hoverlabel at the bottom -> works
y = list(formatter = JS("function(seriesName) {return seriesName;}"), # instead of the time I want it to say "Median" and "Vertrauensbereich"
title = list(formatter = JS("function(test_data$Date) {return test_data$Date;}")))) # the title of the hoverlabel should be the time in the format "yyyy-MM-dd HH:mm:ss"
axc_plot
Here's how it looks:
rangeArea Plot with tooltip
As you can see the data in the tooltip is not displayed very well, so I want to format it using ax_tooltip but that hasn't worked very well so far. I found out that using x = will change the grey hoverlabel at the bottom of the plot and y = changes the label that runs along with the lines (which is the one I want to change). I tried to make a custom tooltip using formatter = but I don't really know how to work with it because all examples I see are made with Java Script and I don't know how to implement that in R. In ax_tooltip(y = ...) you can see how I tried to change the format using JS() because I saw it once somewhere (can't find the link anymore sadly) but I'm pretty sure that's not the way to do it as it doesn't change anything.
In the end, I'd like to achieve a tooltip that looks something like this with the Date at the top (as title) in the format "yyyy-MM-dd HH:mm:ss" if possible and then the series names with the corresponding values and hopefully also with the unit m³/s:
apex desired tooltip
Thanks in advance for any answers. I'm looking forward to hearing your suggestions!
I also asked this question on GitHub where pvictor solved my problem perfectly. This is what they answered and what works for me:
library(htmltools)
test_data <- data.frame(seq(as.POSIXct('2022/09/04 22:00:00'), as.POSIXct('2022/09/08 10:00:00'), by="hour"))
test_data$MIN <- runif(n = 85, min = 70, max = 100)
test_data$MEDIAN <- runif(n = 85, min = 100, max = 120)
test_data$MAX <- runif(n = 85, min = 120, max = 150)
colnames(test_data) <- c("Date", "MIN", "MEDIAN", "MAX")
# explicit NA if not used in area range
test_data$MIN[-c(20:60)] <- NA
test_data$MAX[-c(20:60)] <- NA
# Construct tooltip with HTML tags
test_data$tooltip <- unlist(lapply(
X = seq_len(nrow(test_data)),
FUN = function(i) {
d <- test_data[i, ]
doRenderTags(tags$div(
style = css(padding = "5px 10px;", border = "1px solid #FFF", borderRadius = "5px"),
format(d$Date, format = "%Y/%m/%d %H:%M"),
tags$br(),
tags$span("Q Median:", tags$b(round(d$MEDIAN), "m\u00b3/s")),
if (!is.na(d$MIN)) {
tagList(
tags$br(),
tags$span("Vertrauensbereich:", tags$b(round(d$MIN), "m\u00b3/s -", round(d$MAX), "m\u00b3/s"))
)
}
))
}
))
axc_plot <- apex(
data = test_data[20:60, ], # plot the area range
mapping = aes(
x = Date,
ymin = MIN,
ymax = rev(MAX),
tooltip = tooltip # variable containing the HTML tooltip
),
type = "rangeArea",
serie_name = "Vertrauensbereich"
) %>%
add_line(
data = test_data,
mapping = aes(x = Date, y = MEDIAN, tooltip = tooltip), # use same tooltip variable
type = "line",
serie_name = "Median"
) %>%
ax_colors(c("lightblue", "#FF0000")) %>% # use HEX code instaed of name
ax_theme(mode = "dark") %>%
ax_labs(
x = "Zeit [h]",
y = "Q [m³/s]"
) %>%
ax_tooltip(
# Custom tooltip: retrieve the HTML tooltip defined in data
custom = JS(
"function({series, seriesIndex, dataPointIndex, w}) {",
"var tooltip = w.config.series[seriesIndex].data[dataPointIndex].tooltip;",
"return typeof tooltip == 'undefined' ? null : tooltip;",
"}"
)
)
axc_plot
You can find the GitHub entry here: https://github.com/dreamRs/apexcharter/issues/62

Why is hovertemplate not showing up correctly for some data points for plotly in R

mydat2 <- data.frame(subject = c("math", "english", "chemistry"), score = c(80, 50, 65), class = c("A", "B", "A"), count = c(50, 60, 70))
library(plotly)
plot_ly(data = mydat2,
x = ~score,
y = ~count,
color = ~class,
customdata= ~class,
hoverinfo = 'text',
text = ~subject,
hovertemplate = paste(
"<b>%{text}</b><br><br>",
"%{yaxis.title.text}: %{y:,.0f}<br>",
"%{xaxis.title.text}: %{x:,.0f}<br>",
"Class: %{customdata}",
"<extra></extra>"
))
I'm confused as to why the hover for the left most point shows up as %{text} instead of english. The hover labels for the other 2 points on the plot are perfectly fine.
Here is your graph, with the hover template that you're looking for. The explanation follows.
plot_ly(data = mydat2,
x = ~score,
y = ~count,
color = ~class,
type = "scatter",
mode = "markers",
customdata= ~class,
hoverinfo = 'text',
text = ~I(subject), # <---- I changed!!
hovertemplate = paste(
"<b>%{text}</b><br><br>",
"%{yaxis.title.text}: %{y:,.0f}<br>",
"%{xaxis.title.text}: %{x:,.0f}<br>",
"Class: %{customdata}",
"<extra></extra>"
))
I've seen this problem before. I've usually come up with a workaround, but never really figured out what went wrong until now. I found a closed ticket on GitHub for this issue (closed in 2019). (Ah, ya... so not fixed.) Apparently, it has to do with using color.
However, the bright spot...for a hot minute someone actually believed it was a problem and came up with a fix. #cpsievert wrote a bit of code that includes an lapply call (towards the middle of the page, if you visit the site). When I investigated what the code did, I realized it could be a lot simpler (and it was pretty simple, to begin with).
That ticket on GitHub is here if you wanted to check that out.
This is the code the maintainer provided (that you don't actually need).
l <- plotly_build(p)$x
l$data <- lapply(l$data, function(tr) { tr[["text"]] <- I(tr[["text"]]); tr })
as_widget(l)
The fix is the function I(). Instead of hovertext = or text = ~subject, you need hovertext = or text = ~I(subject). <-- note the I()

Display grouped percentages in Likert plot with Plotly R

I have a dataframe like this:
library(tidyverse)
data <- tibble(Question_num = rep(c("Question_1", "Question_2"),each= 5),
Answer = rep(c('Strongly disagree',
'Disagree',
'Neutral',
'Agree',
'Strongly agree'), 2),
n = c(792, 79, 69, 46, 24, 34, 34, 111, 229, 602),
prop = c(78.4, 7.82, 6.83, 4.55, 2.38, 3.37, 3.37, 11.0, 22.7, 59.6))
where:
Question_num is the label of a question;
Answer is the response mode;
n is a simple count for each response mode;
prop is proportion, in percentage;
I would like to represent it graphically through a dynamic bar graph with divergent colours. Perhaps, this would be a starting point:
library(plotly)
library(RcolorBrewer)
data %>%
plot_ly(x = ~prop,
y = ~Question_num,
color = ~Answer) %>%
add_bars(colors = "RdYlBu") %>%
layout(barmode = "stack")
Is it possible, with Plotly in R, to obtain an ordered plot, which has the neutral category clearly delineated (in the center) and the percentages summarised by grouping the extreme categories together (even if they are in their plotted in different colours)? What I would like to obtain is a plot similar to this one:
The plot in the picture is obtained from a dataset in a different format (wide, not long) and with the likert package, which computes everything automatically. Could such a result be achieved with plotly (both for percentages and for counts)? If so, how?
I could not find any documentation to answer this challenging question.
Thank you very much to those who can help me.
The following isn't addressing all of the issues your post is raising (It might be better to split this into multiple questions).
However, I'd like to share what I was able to get so far.
(Sorry for switching from tidyverse to data.table - I'm not familar with the tidyverse and I'm not planning to familiarize any time soon).
To get the desired plot we can switch to barmode = 'relative'
Run schema() and navigate:
object ► traces ► bar ► layoutAttributes ► barmode
Determines how bars at the same location coordinate are displayed on
the graph. With stack, the bars are stacked on top of one another.
With
relative, the bars are stacked on top of one another, with negative values below the axis, positive values above
library(data.table)
library(plotly)
DF <- data.frame(Question_num = rep(c("Question_1", "Question_2"),each= 5),
Answer = rep(c('E - Strongly disagree',
'D - Disagree',
'A - Neutral',
'B - Agree',
'C - Strongly agree'), 2),
n = c(792, 79, 69, 46, 24, 34, 34, 111, 229, 602),
prop = c(78.4, 7.82, 6.83, 4.55, 2.38, 3.37, 3.37, 11.0, 22.7, 59.6))
DT <- as.data.table(DF)
DT[, order := .GRP, by = Answer]
DT[Answer == "A - Neutral", c("n", "prop") := .(n/2, prop/2)][Answer %in% c("E - Strongly disagree", "D - Disagree"), prop := -prop]
DT <- rbindlist(list(DT, DT[Answer == "A - Neutral", .(Question_num = Question_num, Answer = Answer, n = n, prop = -prop, order = order-0.5)]))
setorder(DT, -Question_num, order)
# setorder(DT, order)
fig <- plot_ly(
data = DT,
type = "bar",
x = ~ prop,
y = ~ Question_num,
color = ~ Answer,
colors = c("E - Strongly disagree" = "#a6611a",
"D - Disagree" = "#d2b08c",
"A - Neutral" = "#b3b3b3",
"B - Agree" = "#80c2b8",
"C - Strongly agree" = "#018571"),
text = ~ paste0(prop, "%"),
textfont = list(
size = 12,
color = 'black')
)
fig <- layout(
fig,
barmode = "relative",
xaxis = list(title ="Percentage"),
yaxis = list(
categoryorder = "array",
categoryarray = sort(unique(DT$Question_num), decreasing = TRUE),
title = ""
),
legend = list(orientation = "h")
)
print(fig)
Here a related question can be found.

R plotly subplot warning 'layout' objects don't have these attributes: 'NA'

I am trying to combine a two plotly figures (type = 'mesh3d' and type = 'scatter3d'). Each of the single plots is perfectly fine without any warning. After I use subplot a warning occurs every time I try to display the plot.
warning 'layout' objects don't have these attributes: 'NA'
I have tried to suppressWarning but this does not have any effect.
Any ideas what I am missing here to get rid of the warning?
Plotly Version: 4.9.3
R Version: 4.0.1
# plot data
plt_data <- data.frame(maturity=rep(1:10, each=10),
tenor=rep(1:10, 10),
value=rnorm(100))
# plot 1
fig11 <- plot_ly(
data=plt_data, x=~maturity, y=~tenor, z = ~value,
type = "mesh3d",intensity = ~value,
colors = colorRamp(c(
rgb(168, 191, 173, max = 255),
rgb(100, 181, 117, max = 255),
rgb(0,100,80, max = 255)
)),
contour=list(show=T, width=4, color="#fff"),
showscale = F,
scene='scene1',
lighting = list(ambient = 0.9),
hoverinfo="skip",
source="myID"
)
# plot 2
fig12 <- plot_ly(
data=plt_data, x=~maturity, y=~tenor, z = ~value,
type = "scatter3d",
mode="markers",
hovertemplate="Maturity: %{x:.f}<br>Tenor: %{y:.f}<br>Value: %{z:.4f}<extra></extra>",
marker=list(
symbol="square-open",
size=4,
color="#3d543f"
),
scene='scene1',
source="myID",showlegend=F
)
# subplot which does throw a warning
subplot(fig11, fig12)
For R and Shinyapps, to suppress warnings like this:
options(warn = -1)
There is an open issue regarding the warning. Here's a workaround to hide the warnings for this case -
function_to_hide_plotly_warning <- function(...) {
plot <- subplot(...)
plot$x$layout <- plot$x$layout[grep('NA', names(plot$x$layout), invert = TRUE)]
plot
}
function_to_hide_plotly_warning(fig11, fig12)

How to plot multiple lines in radar chart using split in plotly

I have tried using split trace with scatterpolar and it seems to partly work but can't get it to plot the values for all 10 variables. So I want each row (identified by "ean") be plotted as its own line using the values from X1 to X10.
library(tidyverse)
library(vroom)
library(plotly)
types <- rep(times = 10, list(
col_integer(f = stats::runif,
min = 1,
max = 5)))
products = bind_cols(
tibble(ean = sample.int(1e9, 25)),
tibble(kategori = sample(c("kat1", "kat2", "kat3"), 25, replace = TRUE)),
gen_tbl(25, 10, col_types = types)
)
plot_ly(
products,
type = 'scatterpolar',
mode = "lines+markers",
r = ~X1,
theta = ~"X1",
split = ~ean
)
How can I get plotly to plot all variables in the radarchart (X1-X10)? Usually I would select the columns with X1:X10 but I can't do that here (I think it has to do with that ~ is used to select variable here).
So I want the result to look something like this (but I only show lines and not filled polygons and I would have more products). So in the end 25 products is a lot but I am connecting it so that the user can select the diagrams it wants to show.
In plotly it's convenient to use data in long format - see ?gather.
Please check the following:
library(dplyr)
library(tidyr)
library(vroom)
library(plotly)
types <- rep(times = 10, list(
col_integer(f = stats::runif,
min = 1,
max = 5)))
products = bind_cols(
tibble(ean = sample.int(1e9, 25)),
tibble(kategori = sample(c("kat1", "kat2", "kat3"), 25, replace = TRUE)),
gen_tbl(25, 10, col_types = types)
)
products_long <- gather(products, "key", "value", -ean, -kategori)
plot_ly(
products_long,
type = 'scatterpolar',
mode = "lines+markers",
r = ~value,
theta = ~key,
split = ~ean
)

Resources