How can I do a dual axis using highcharter library? - r

someone could tell what command I should add to get a dual axis in one graphic.
library(highcharter)
library(tidyr)
base1=gather(base1,"serie","valor",2:4)
p1<-base1 %>% hchart("line",hcaes(x = Año,y=valor, group=serie)) %>% hc_add_theme(hc_theme_economist())
p1
# Gráfica 2
dir(pattern="*.xlsx")
library(readxl)
base1=read_xlsx("DatosColombia.xlsx", sheet = "Hoja3")
attach(base1)
library(highcharter)
library(tidyr)
base1=gather(base1,"serie","valor",2:3)
p2<-base1 %>% hchart("line",hcaes(x = Año,y=valor, group=serie)) %>% hc_add_theme(hc_theme_economist())
p2

Use hc_yAxis_multiples
Basic example:
highchart() %>%
hc_yAxis_multiples(
list(lineWidth = 3),
list(showLastLabel = FALSE, opposite = TRUE)
) %>%
hc_add_series(data = rnorm(10)) %>%
hc_add_series(data = rexp(10), type = "spline", yAxis = 1)

Related

Adding traces to plotly animations in R

I am trying to develop a Business Cycle Clock similar to https://kosis.kr/visual/bcc/index/index.do?language=eng.
I've already achieved most of the things I wanted to replicate, but I can't figure it out how to add these traces (for example, in the link above set speed to 10 and trace length to 5 and then click on 'Apply' to understand what I mean).
Does anyone have any idea how to implement it? It would make the "clock" much easier to read. Thanks in advance.
Reprocible example:
library(plotly)
library(dplyr)
library(magrittr)
variable <- rep('A',10)
above_trend <- rnorm(10)
mom_increase <- rnorm(10)
ref_date <- seq.Date('2010-01-01' %>% as.Date,
length.out = 10,by='m')
full_clock_db <- cbind.data.frame(variable, above_trend, mom_increase, ref_date)
freq_aux = 'm'
ct = 'Brazil'
main_title = paste0('Business Cycle Clock para: ', ct)
m <- list(l=60, r=170, b=50, t=70, pad=4)
y_max_abs = 2
x_max_abs = 5
fig = plot_ly(
data = full_clock_db,
x = ~mom_increase,
y = ~above_trend,
color = ~variable,
frame = ~ref_date,
text = ~variable,
hoverinfo = "text",
type = 'scatter',
mode = 'markers'
) %>%
animation_opts( frame = 800,
transition = 500,
easing = "circle",
redraw = TRUE,
mode = "immediate") %>%
animation_slider(
currentvalue = list(prefix = "Período", font = list(color="red"))
)
fig
Another more elegant solution would be to rely on ggplot2 + gganimate:
library(ggplot2)
library(gganimate)
ggplot(full_clock_db, aes(x = mom_increase, y = above_trend)) +
geom_point(aes(group = 1L)) +
transition_time(ref_date) +
shadow_wake(wake_length = 0.1, alpha = .6)
You cna play with different shadow_* functions to find the one to your liking.
One way would be to use a line plot and repeat points as necessary. Here's an example as POC:
library(dplyr)
library(plotly)
e <- tibble(x = seq(-3, 3, 0.01)) %>%
mutate(y = dnorm(x)) %>%
mutate(iter = 1:n())
accumulate <- function(data, by, trace_length = 5L) {
data_traf <- data %>%
arrange({{ by }}) %>%
mutate(pos_end = 1:n(),
pos_start = pmax(pos_end - trace_length + 1L, 1L))
data_traf %>%
rowwise() %>%
group_map(~ data_traf %>% slice(seq(.x$pos_start, .x$pos_end, 1L)) %>%
mutate("..{{by}}.new" := .x %>% pull({{by}}))) %>%
bind_rows()
}
enew <- e %>%
accumulate(iter, 100)
plot_ly(x = ~ x, y = ~ y) %>%
add_trace(data = e, type = "scatter", mode = "lines",
line = list(color = "lightgray", width = 10)) %>%
add_trace(data = enew, frame = ~ ..iter.new,
type = "scatter", mode = "lines") %>%
animation_opts(frame = 20, 10)
The idea is that for each step, you keep the trace_length previous steps and assign them to the same frame counter (here ..iter.new). Then you plot lines instead of points and you have a sort of trace..

Highcharter - Having one or more of the grouping elements pre-selected

I'm producing a set of charts using highcharter. I have items, which each have variants, and units sold by variant. I'm looking for a method by which I can choose which variants are pre-selected to appear on the chart.
Below is an example of the chart I produced:
library(tidyverse)
library(highcharter)
library(viridis)
df <- tibble(item_name = c('beer','beer','soft drink','soft_drink'),
units = c(15,50,25,10),
variant_name = c('blonde','white','coke','lemonade'))
cols = as.vector(scales::viridis_pal(option = "turbo", direction = 1)(length(unique(df$variant_name))))
df %>%
group_by(item_name) %>%
arrange(desc(units)) %>%
ungroup() %>%
hchart(
"column", hcaes(x = item_name, y = units, group = variant_name),
stacking = "normal"
) %>%
hc_colors(c(cols))
I would like to be able to pre-select, let's say 'blonde' and 'coke'. Other variants would have to be selected by clicking on the variant name in the chart:
I haven't been able to find a way to do that so far, the documentation for highcharts only points to doing so when you have multiple series.
You could write your own JS function to load the elements. Where you can specify the chart.series.load, check this link for extra info. Here is a reproducible example:
library(tidyverse)
library(highcharter)
library(viridis)
df <- tibble(item_name = c('beer','beer','soft drink','soft_drink'),
units = c(15,50,25,10),
variant_name = c('blonde','white','coke','lemonade'))
cols = as.vector(scales::viridis_pal(option = "turbo", direction = 1)(length(unique(df$variant_name))))
df %>%
group_by(item_name) %>%
arrange(desc(units)) %>%
ungroup() %>%
hchart(
"column", hcaes(x = item_name, y = units, group = variant_name),
stacking = "normal"
) %>%
hc_chart(events = list(load = JS("function() {
var chart = this;
chart.series[1].setVisible(true)
chart.series[2].setVisible(false)
chart.series[3].setVisible(false)
chart.series[4].setVisible(false)
}"))) %>%
hc_colors(c(cols))
Output:

Argument is not named in hc_add_series

I use the package highcharter to create the plot below with:
library(highcharter)
library(dplyr)
hc <- highchart() %>%
hc_chart(type="column") %>%
hc_xAxis(type="category") %>%
hc_add_series(
name = "Things",
data = list(
list(
name = "Animals",
y = 10,
drilldown = "animals"
),
list(
name = "People",
y = 10,
drilldown = "people"
)
)
)
hc
When I try to create the similar plot fot the sum of Num for every US State I get:
argument is not named in hc_add_series
data
State <- c("ALABAMA", "ALABAMA", "ALASKA", "ALASKA")
Num <- c(5, 6, 7, 8)
d <- data.frame(State, Num)
code
library(highcharter)
library(dplyr)
hc <- highchart() %>%
hc_chart(type="column") %>%
hc_xAxis(type="category") %>%
hc_add_series(
name = "States",
output2 <- d %>% group_by(State) %>%
summarise(Num = sum(Num)) %>%
mutate(drilldown = tolower(State)) %>%
transpose
)
Why does this happen since in both cases Im using a list
I think you can benefit from using hcaes which works like aes in ggplot:
highchart() %>%
hc_chart(type="column") %>%
hc_xAxis(type="category") %>%
hc_add_series(
data = d,
name = "States",
type = "column",
hcaes(x = State, y = Num)
)

Plot_ly Scatterplot connecting lines how do most elegant?

I'm asking myself how to solve the following problem the most elegant. My data encompasses of some actual values and some proposed values. Right now I have data that looks like the reproducible example below:
library(plotly)
library(dplyr)
test_dt <- data.frame(Age=1:5, Key=c("Actuals", "Actuals", "Actuals", "Other", "Other") , Value=rnorm(5))
plot_ly(data = (test_dt %>% group_by(., Key) %>% arrange(desc(Age))),
x = ~Age,
y = ~Value,
type = 'scatter',
mode = 'lines',
color = ~Key,
linetype = ~Key
) %>% layout(
yaxis = list(
title = "SD"),
margin = list(top=100, b=50)
)
The output of this code looks like this:
how plot a dashed line where i drew the red arrow?
My solution so far is that I access the last value of my actuals and insert this value as a new row for my "other" line. But I don't think that's very elegant and sometimes, if no other values exist which can happen in my data depending on the inputs then I have a legend plotted for my "other" line without actually having one.
act_age_max <- filter(test_dt, Key=="Actuals") %>% .[["Age"]] %>% max
propval_names <- filter(test_dt, Key!="Actuals") %>% .[["Key"]]
last_actual <- filter(test_dt, Age==act_age_max, Key=="Actuals") %>% .[["Value"]]
acts_year <- filter(test_dt, Age==act_age_max, Key=="Actuals") %>% .[["Year"]]
append_dt <- data.frame(Age=act_age_max, Key=propval_names, Value=last_actual)
plot_data <- rbind(test_dt, append_dt)
plot_ly(data = (plot_data %>% group_by(., Key) %>% arrange(desc(Age))),
x = ~Age,
y = ~Value,
type = 'scatter',
mode = 'lines',
color = ~Key,
linetype = ~Key
) %>% layout(
yaxis = list(
title = "SD"),
margin = list(top=100, b=50)
)

Add mouseover to outliers but not other points?

I'd like to plot a large scatterplot using the highcharter package, but only allow mouse over on a few outliers. Is there a way to enable mouseTracking on one series but not the other?
df <- data.frame( x = rnorm(1000), y = rnorm(1000) )
df$sig <- ifelse( abs(df$x) > 2, "signif", "not")
library(highcharter)
hc <- highchart() %>%
hc_add_series_df(df, type = "scatter", group=sig)
Right now I can only disable mouse over on all points, but the hc_plotOptions says something about using a series array?
hc_plotOptions(hc, scatter = list( enableMouseTracking= FALSE ))
There are a lot of way to do what you want.
I think the simplest is use:
hchart(df, "scatter", hcaes(x, y, group = sig), enableMouseTracking = c(FALSE, TRUE))
(Note this is the development version of highcharter.)
Which is same as:
highchart() %>%
hc_add_series(data = df %>% filter(sig == "not"), type = "scatter", enableMouseTracking = FALSE) %>%
hc_add_series(data = df %>% filter(sig == "signif"), type = "scatter", enableMouseTracking = TRUE)
Or
highchart() %>%
hc_add_series(data = list_parse(df %>% filter(sig == "not")), type = "scatter", enableMouseTracking = FALSE) %>%
hc_add_series(data = list_parse(df %>% filter(sig == "signif")), type = "scatter", enableMouseTracking = TRUE)

Resources