Change the 'Frame' Label in Plotly Animation - r

TLDR: I want to label the frame slider with the three letter abbreviation instead of the number for each month.
I created a bar chart showing average snow depth each month over a 40 year period. I'm pulling my data from NOAA and then grouping by year and month using lubridate. Here is the code:
snow_depth <- govy_data$snwd %>%
replace_na(list(snwd = 0)) %>%
mutate(month_char = month(date, label = TRUE, abbr = TRUE)) %>%
group_by(year = year(date), month = month(date), month_char) %>%
summarise(avg_depth = mean(snwd))
The mutate function creates a column (month_char) in the data frame holding the three letter abbreviation for each month. The class for this column is an ordered factor.
The code below shows how I'm creating the chart/animation:
snow_plot <- snow_depth %>% plot_ly(
x = ~year,
y = ~avg_depth,
color = ~avg_temp,
frame = ~month,
text = ~paste('<i>Month</i>: ', month_char,
'<br><b>Avg. Depth</b>: ', avg_depth,
'<br><b>Avg. Temp</b>: ', avg_temp),
hoverinfo = 'text',
type = 'bar'
)
snow_plot
This code generates a plot that animates well and looks like this:
What I'd like to do is change the labels on the slider so instead of numbers, it shows the three letter month abbreviation. I've tried switching the frame to ~month_char which is the ordered factor of three letter month abbreviations. What I end up with, isn't right at all:
The data frame looks like:

I fear, with the current implementation of animation sliders in R's plotly API the desired behaviour can't be realized. This is due to the fact, that no custom animation steps are allowed (this includes the labels). Please see (and support) my GitHub FR for further information.
This is the best I was currently able to come up with:
library(plotly)
DF <- data.frame(
year = rep(seq(1980L, 2020L), each = 12),
month = rep(1:12, 41),
month_char = rep(factor(month.abb), 41),
avg_depth = runif(492)
)
fig <- DF %>%
plot_ly(
x = ~year,
y = ~avg_depth,
frame = ~paste0(sprintf("%02d", month), " - ", month_char),
type = 'bar'
) %>%
animation_slider(
currentvalue = list(prefix = "Month: ")
)
fig
(Edit from OP) Here's the resulting graph using the above code:

Related

How to show only some hoverinfo points on a line graph with Plotly in R

I have traffic and article dfs as follows:
library(plotly)
library(dplyr)
set.seed(101)
traffic <- data.frame(Date = seq(as.Date("2021-06-01"), as.Date("2021-07-10"), by="days"),
Views = round(rnorm(40, 5000, 200),0))
articleData <- data.frame(Date = as.Date(c("2021-06-01", "2021-07-04", "2021-07-10")),
article = c("Article 1", "Article 2", "Article 3"))
joinedData <- left_join(traffic, articleData)
I want to make a plotly line graph that shows a line for traffic, but for the 3 dates where there were articles published I would like to add a dot that the person can cover over and it will show what article was published that day. Below is what I was able to put together:
plot_ly(data = joinedData, x = ~Date, y = ~Views, type = "scatter", mode = "lines") %>%
add_trace(hoverinfo = "text", text = ~article, mode = "markers")
This technically works, but it puts a marker on every single day, not just the 3 days that had articles. Is there a way to ignore marking the days that don't have articles? I really just want to draw attention to the days that have articles published and show whether that article shows a spike in traffic or not.
I think you were really close in your question. I think you just need to filter your data for those three articles and create a new dataframe. You can use the new dataset in add_trace. This will only put points on the dates that had articles published.
library(dplyr)
library(plotly)
filteredJoinedData <- joinedData %>%
filter(article != "NA")
plot_ly(data = joinedData, x = ~Date, y = ~Views, type = "scatter", mode = "lines") %>%
add_trace(data = filteredJoinedData, hoverinfo = "text", text = ~article, mode = "markers")
Giving you this graph

Cannot combine a Ribbon in highcharter (R) with normal line series

I am trying to produce a ribbon on my highcharter chart (roughly following is there an equivalent to geom_ribbon in highcharter?).
However, the following example to produce a highcharter graph in R produces an error:
library(quantmod)
library(dplyr)
library(highcharter)
getSymbols("VOD")
bb_data = BBands(Cl(VOD), n=20)
highchart(type = "stock") %>%
hc_add_series(bb_data, type = "arearange", hcaes(low = dn, high=up))
The error is:
Error: 'hcaes(low = dn, high = up)' argument is not named in hc_add_series
I have think this is because it is a time series object (xts).
It works if I cast it to a data.frame, but then I lose the date.
highchart(type = "stock") %>%
hc_add_series(as.data.frame(bb_data), type = "arearange", hcaes(low = dn, high=up))
I cannot combine it to with the moving average or price data as I would wish, as the ribbon is then missing from the subsequent plot:
highchart(type = "stock") %>%
hc_add_series(Cl(VOD), name = "VOD") %>%
hc_add_series(bb_data$mavg, name = "20d MA") %>%
hc_add_series(as.data.frame(bb_data), type = "arearange", hcaes(low = dn, high=up))
ok, so I had to first extract the date from the time series object and bind it with the time series object to form a data frame or data table and then plot using that.
bb_data2 = cbind(date = as.Date(index(bb_data)), data.table(bb_data))
highchart(type = "stock") %>%
hc_add_series(bb_data2, type = "arearange", hcaes(x=date, low = dn, high=up)) %>%
hc_add_series(Cl(VOD), name = "VOD") %>%
hc_add_series(bb_data$mavg, name = "20d MA")

rCharts Zeros instead of numbers in the y Axis

I get 0 values on the y Axis while plotting a discreteBarChart inside renderChart(), However, the highest value of yAxis appears (not 0) but also with some wierd format and commmas (see 2nd screenshot down named Chart Plot)
I want to plot 2 columns in rCharts, the x Axis is a character (countryname) and the yAxis is numeric (Collective_Turnover)
I created this variable (Collective_Turnover) from the data, it is the sum of the Net_Turnover
I tried to put as.numeric() before it, but still, getting 0 on the yAxis
data$countryname= as.character(data$countryname)
output$top10countries <-renderChart({
topcountries <-
arrange(data%>%
group_by(as.character(countryname)) %>%
summarise(
Collective_Turnover= sum(as.numeric(`Net turnover`))
), desc(Collective_Turnover))
colnames(topcountries )[colnames(topcountries )=="as.character(countryname)"] <- "Country"
topcountries <- subset(topcountries [1:10,], select = c(Country, Collective_Turnover))
p <- nPlot(Collective_Turnover~Country, data = topcountries , type = "discreteBarChart", dom = "top10countries")
p$params$width <- 1000
p$params$height <- 200
p$xAxis(staggerLabels = TRUE)
# p$yAxis(axisLabel = "CollectiveTO", width = 50)
return(p)
})
The output of topcountries in R is a table like this:
that is arranged in descending order...
and the plot that i get is this:
The ticks labels are truncated because they are too long. You need to set the left margin and a padding. To get rid of the commas, use a number formatter.
dat <- data.frame(
Country = c("Russian", "Italy", "Spain"),
x = c(12748613.6, 5432101.2, 205789.7)
)
p <- nPlot(x ~ Country, data = dat, type = "discreteBarChart")
p$yAxis(tickPadding = 15, tickFormat = "#! function(d) {return d3.format('.1')(d)} !#")
p$chart(margin = list(left = 100))
p

Multiple y-axes in shiny app w/ highcharter

I'm trying to render a graph in a shiny app using highcharter that shares an x-axis (days) but has multiple y-axes (a percent and a count). After some research it seems like I should use the 'hc_yAxis_multiples' method. On the left y-axis, I have % displayed. On the right y-axis, I want the count displayed. There is a line graph that is based on the left y-axis (%), and a stacked bar graph that is displayed based on the right y-axis.
I have been able to overlay the two graphs, but the bar chart portion based on the right y-axis is not formatted to the corresponding y-axis. Based on what I have been looking at, it seems like something like this would produce a result that I want:
##This first block is to show what the data types of the variables I'm using are and what the structure of my df looks like
df$inbox_rate <- df$total_inbox / df$total_volume
df$inbox_rate <- round((df$inbox_rate*100),0)
df$received_dt <- as.character(df$received_dt)
df$received_dt <- as.Date(df$received_dt, "%Y%m%d")
df <- df[order(df$received_dt),]
## This second block here is where I'm trying to build the chart with two Y-axes
hc <- highchart()%>%
hc_title(text = paste(domain_name,sep=""),align = "center") %>%
hc_legend(align = "center") %>%
hc_xAxis(type = "datetime", labels = list(format = '{value:%m/%d}')) %>%
hc_yAxis_multiples(list(title = list(text = "IPR"),labels=list(format = '{value}%'),min=0,
max=100,showFirstLabel = TRUE,showLastLabel=TRUE,opposite = FALSE),
list(title = list(text = "Total Subscribers"),min=0,max = max(df$total_users),
labels = list(format = "{value}"),showLastLabel = FALSE, opposite = TRUE)) %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_add_series(df,"column",hcaes(
x=received_dt,y=total_users,group=isp,yAxis=total_users)) %>%
hc_add_series(df,type="line",hcaes(
x=received_dt,y=inbox_rate,group=isp,yAxis=inbox_rate)) %>%
hc_exporting(enabled = TRUE) %>%
hc_add_theme(thm)
hc
However this produces something that looks like this.
To give more insight about the data I'm using, the domain_name is a string variable that looks like this: example.com. The total_users variable is a number that varies from 0 to about 50000. The received_dt variable is a date, formatted using as.Date(df$received_dt, "%Y%m%d"). The inbox_rate variable is a percent, from 0 to 100.
The bar counts are all displaying to the full height of the graph, even though the values of the bars vary widely. To reiterate, I want the right y-axis that the bar chart heights are based on to be the count of the df$total_users. Within the hc_yAxis_multiples function, there are two lists given. I thought that the first list gives the left y-axis, and the second gives the right. The closest answer to my question that I could find was given by this stackoverflow response
If anyone has any insight, it would be very much appreciated!
Your use of the yAxis statement in hc_add_series seems to be off. First, it should not be inside hcaes and second, it's a number specifying which axis (in order of appearance in hy_yAxis_multiple call) the series belongs to. So hc_add_series(..., yAxis = 1) should be used to assign a series to the second (right) axis.
Below is a (fully self-explaining, independent, minimal) example that shows how it should work.
library(highcharter)
df <- data.frame(
total_inbox = c(2, 3, 4, 5, 6),
total_volume = c(30, 30, 30, 30, 30),
total_users = c(300, 400, 20, 340, 330),
received_dt = c("20180202", "20180204", "20180206", "20180210", "20180212"),
isp = "ProviderXY"
)
df$inbox_rate <- df$total_inbox / df$total_volume
df$inbox_rate <- round((df$inbox_rate*100),0)
df$received_dt <- as.character(df$received_dt)
df$received_dt <- as.Date(df$received_dt, "%Y%m%d")
df <- df[order(df$received_dt),]
hc <- highchart()%>%
hc_xAxis(type = "datetime", labels = list(format = '{value:%m/%d}')) %>%
hc_yAxis_multiples(list(title = list(text = "IPR"),labels=list(format = '{value}%'),min=0,
max=100,showFirstLabel = TRUE,showLastLabel=TRUE,opposite = FALSE),
list(title = list(text = "Total Subscribers"),min=0,max = max(df$total_users),
labels = list(format = "{value}"),showLastLabel = FALSE, opposite = TRUE)) %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_add_series(df,type="column",hcaes(x=received_dt,y=total_users,group=isp),yAxis=1) %>%
hc_add_series(df,type="line",hcaes(x=received_dt,y=inbox_rate,group=isp))
hc
Maybe take this as an example how code in questions should be like. Copy-Paste-Runnable, no outside variables and minus all the things that dont matter here (like the theme and legend for example).

Rcharts: plot only shows first character of label

I recently switched from ggplot to Rcharts and have a fairly simple question about the labels.
Sample data
data_1 <- data.table(Filter = c('Filter 1', 'Filter 2'),
Amount = c(100, 50))
data_2 <- data.table(Filter = c('Filter 1'),
Amount = c(100))
Plots
hPlot(Amount ~ Filter, data = data_1, type = 'bar', group.na = 'NA\'s')
hPlot(Amount ~ Filter, data = data_2, type = 'bar', group.na = 'NA\'s')
Question:
Why do we see the correct label in the first plot, but only the first letter of the label in the second plot? This issue always occurs when the number of rows = 1 (as it is in data_2).
Does anyone has a quick fix / workaround?

Resources