Highcharter bar colors issue - r

I have the following function:
library(highcharter)
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal,
color = color
)
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
)
The function takes a dataframe such as the following:
newdata <- data.frame(
Gender = c(rep("Female", 2), rep("Male", 2)),
is_churner = c("Active", "Churner", "Active", "Churner"),
Nominal = c(7267L, 933L, 9767L, 1313L),
Percent = c(42.7, 41.5, 57.3, 58.5),
color = c("green", "red", "green", "red")
) %>%
dplyr::group_by(is_churner)
One of the columns - color is supposed to be mapped to the color argument of the hchart function. As far as I recall, this is something that used to work.
Now, however, I get a really ugly graph.
Neither the colors of the bars correspond to the colors column, nor the legend below (which is what the colors represent) are colored accordingly.
What am I doing wrong?

I believe the color has to be called separately outside hcaes, but your approach seems more intuitive/sensible, so shame it's not working. The following works:
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal
), color = c("green", "red")
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
)
The following also works:
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal
)
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
) %>%
hc_colors(c("green", "red"))
I've deleted color from hcaes and added it instead to hc_colors.

I have had the same issue, in my case it turned out that my css files overruled the colors I specified in the hchart color.
When I removed te relevant lines in the css files the color command did work in the way you originally specified. You do not need to call it separately outside hcaes.

Related

R Plotly - Cannot Order or Organize by a Variable

I am trying to create a Plotly plot in R, and I cannot seem to get it to break the data down by the "class" variable.
This data is built into R, so it should be easy for anyone to look at.
First, here is the code (I added quotation marks around "class" in a few spots, because the code will not run otherwise):
library(plotly)
library(tidyverse)
mpg %>%
group_by(model) %>%
summarise(c = mean(cty), h = mean(hwy), class = class) %>%
mutate(model = forcats::fct_reorder(model, c), class = forcats::fct_reorder(class, c)) %>%
plot_ly() %>%
add_segments(
x = ~c, y = ~forcats::fct_reorder(model, c),
xend = ~h, yend = ~model,
color = "class", showlegend = TRUE
) %>%
add_markers(
x = ~c, y = ~model,
marker = list(symbol = "square",
color = "class"),
name = "",
showlegend = FALSE
) %>%
add_markers(
x = ~h, y = ~model,
marker = list(symbol = "diamond",
color = "class"),
name = "",
showlegend = FALSE
) %>%
layout(xaxis = list(title = "Miles per gallon"))
I am trying to get the data to be ordered by the new "c" variable overall, but I want to be able to break the data down by the "class" (the type of vehicle). However, as you can see from the code, every car is the same color, so that isn't happening?
I appreciate any help I can get here. I am pretty new to Plotly, so I could definitely be overlooking something simple.
Thank you!
Instead of mapping the string constant "class" on color, map the class column on the color attribute:
library(plotly)
library(tidyverse)
mpg %>%
group_by(model) %>%
summarise(c = mean(cty), h = mean(hwy), class = class) %>%
mutate(model = forcats::fct_reorder(model, c), class = forcats::fct_reorder(class, c)) %>%
plot_ly() %>%
add_segments(
x = ~c, y = ~forcats::fct_reorder(model, c),
xend = ~h, yend = ~model,
color = ~class, showlegend = TRUE
) %>%
add_markers(
x = ~c, y = ~model, color = ~class,
marker = list(symbol = "square"),
name = "",
showlegend = FALSE
) %>%
add_markers(
x = ~h, y = ~model, color = ~class,
marker = list(symbol = "diamond"),
name = "",
showlegend = FALSE
) %>%
layout(xaxis = list(title = "Miles per gallon"))
#> `summarise()` has grouped output by 'model'. You can override using the
#> `.groups` argument.

Adjust the yAxis fontSize in highchart in R

Is there a way to increase the yAxis labels in highcharts in R?
highchart() %>%
hc_title(text = "some plot name") %>%
hc_add_series(subset1_melted_nona,type = "scatter", hcaes(x = variable, y = value), value= 10, color="darkblue", name="freq", marker = list(radius = 2)) %>%
hc_add_series(subset1_melted_nona, type = "arearange", hcaes(x=variable, low =errmin, high=errmax), yAxis=1, name="cov", color="red") %>%
hc_add_series(subset1_melted_nona, type= "line", hcaes(x = variable, y = enb), yAxis=2, name="comp", color="#CC6600") %>%
hc_yAxis_multiples(
list(lineWidth = 3, lineColor="darkblue",title=list(text="freq")),
list(lineWidth = 3, opposite = TRUE, lineColor="red", title=list(text="cov")),
list(lineWidth = 3, opposite = TRUE, lineColor="#CC6600", title=list(text="comp")))
You can use JS to edit labels from the available Highcharts JS API:
https://api.highcharts.com/highcharts/xAxis.labels.style.fontSize
You can find an article on how to do this here:
https://www.highcharts.com/blog/tutorials/working-with-highcharts-javascript-syntax-in-r/

plotly bar graph - adding percentages to labels

I'm trying to create a simple bar chart using the plotly package in R. I want to add labels above each bar, but I've only be able to successfully add in the counts. Is it all possible to add in percentages next to each count? This is what I have:
fig_valve <- plot_ly(valve_df,
x = ~vlvsz_c,
y = ~count,
type = "bar",
hoverinfo = "x+y")
fig_valve <- fig_valve %>%
add_text(text = ~count,
textposition = "top",
textfont = list(size = 11, color = "black"),
showlegend = FALSE) %>%
layout(title = "",
xaxis = list(title = "Valve Size", showgrid = FALSE),
yaxis = list(title = "Count", showgrid = FALSE),
showlegend = FALSE,
font = t)
The output:
I'm wondering if I can add in the percentages for each category. Greatly appreciate any suggestions!
You can add the percentages next to the counts via text = ~paste0(count, " (", scales::percent(count / sum(count)), ")") where I use scales::percent for nice formatting. Using mtcars as example data, try this:
library(plotly)
library(dplyr)
library(scales)
fig_valve <- mtcars %>%
count(cyl, name = "count") %>%
plot_ly(
x = ~cyl,
y = ~count,
type = "bar",
hoverinfo = "x+y")
fig_valve <- fig_valve %>%
add_text(text = ~paste0(count, " (", scales::percent(count/sum(count)), ")"),
textposition = "top",
textfont = list(size = 11, color = "black"),
showlegend = FALSE) %>%
layout(title = "",
xaxis = list(title = "Valve Size", showgrid = FALSE),
yaxis = list(title = "Count", showgrid = FALSE),
showlegend = FALSE,
font = t)
fig_valve

Change order of subplots

Is there a way to change the order of subplots in plotly for R? Is there a way to manually change the levels of a factor in this code?
I want a plot with Weight in the first plot followed by a,b,c in order above it. But what I get as output is Weight, c, a and b as shown in the image graph
Here is my code
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", id)
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
One way to do this is re-ordering factor levels as below:
# set.seed to keep the exact same results
set.seed(123)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
DF <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable)))
DF$variable <- factor(DF$variable, levels = c("Weight", "a", "b", "c")) #re-order
q <- DF %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", sort(id, decreasing =F))) %>% #sort the order
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
q
You will need sort(id, decreasing =F) to get exact same order of what you set in factor(DF$variable, levels = c("Weight", "a", "b", "c")).
Exchange the data, the name, and the line features of the top and bottom subplots as following code,
#assign q$x$data to one template variable p
p = q$x$data
#exchange the data, name, and line features of q$x$data[[1]] and q$x$data[[4]]
q$x$data[[1]]$x = p[[4]]$x
q$x$data[[1]]$y = p[[4]]$y
q$x$data[[1]]$name = p[[4]]$name
q$x$data[[1]]$line = p[[4]]$line
q$x$data[[4]]$x = p[[1]]$x
q$x$data[[4]]$y = p[[1]]$y
q$x$data[[4]]$name = p[[1]]$name
q$x$data[[4]]$line = p[[1]]$line
#show
q
The problem might have been caused by yaxis = ~paste0("y", id). I replaced it with yaxis = ~paste0(id, "y") to get the correct order. You may need to change some code to get the right format.
library(plotly)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0(id, "y")
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df), shareX = TRUE)
q

Sharing axes and legends between subplots in plotly in R (faceting in ggplot2 and using ggplotly doesn't work)

I have the following data:
df <- data.frame(numbers = rep(1:3, 30),
letter = sample(c("A", "B", "C", "D"), 90, replace = TRUE),
status = sample(c("good", "bad", "ugly"), 90, replace = TRUE))
I am trying to replicate this ggplot2 plot, but make it interactive:
ggplot(df, aes(letter, fill = status)) + geom_bar() + facet_wrap(.~numbers)
If I use ggplotly, then I can select and deselect variables, but the bars do not readjust so I get something that looks like this:
So my idea was to cast the data, then create individual plotly plots and use subplot:
df_group <- df %>% group_by(numbers, letter, status) %>% tally()
df_group_cast <- dcast(df_group, numbers + letter ~ status)
p1 <- df_group_cast %>%
filter(numbers == 1) %>%
plot_ly(x = ~letter, y = ~good, type = 'bar', name = 'good') %>%
add_trace(y = ~bad, name = 'bad') %>%
add_trace(y = ~ugly, name = 'ugly') %>%
layout(yaxis = list(title = 'Count'), barmode = 'stack')
p2 <- df_group_cast %>%
filter(numbers == 2) %>%
plot_ly(x = ~letter, y = ~good, type = 'bar', name = 'good') %>%
add_trace(y = ~bad, name = 'bad') %>%
add_trace(y = ~ugly, name = 'ugly') %>%
layout(yaxis = list(title = 'Count'), barmode = 'stack')
p3 <- df_group_cast %>%
filter(numbers == 3) %>%
plot_ly(x = ~letter, y = ~good, type = 'bar', name = 'good') %>%
add_trace(y = ~bad, name = 'bad') %>%
add_trace(y = ~ugly, name = 'ugly') %>%
layout(yaxis = list(title = 'Count'), barmode = 'stack')
subplot(p1, p2, p3)
This is interactive, but also looks bad. I would like them to share a scale, have one legend, and have titles for each number group.
Is this possible?
(I am trying to embed an interactive graph like this into slidify, if there are better libraries I am open to using them. So far rCharts has failed me, so I'm trying plotly)
I figured it out! Didn't need to cast my data in the end. I have even added a step for adding subgroup titles.
df_group <- df %>% group_by(numbers, letter, status) %>% tally()
Put together annotation texts to add to the plots:
a <- list(
text = sprintf("<b>1</b>"),
xref = "paper",
yref = "paper",
yanchor = "bottom",
xanchor = "center",
align = "center",
x = 0.5,
y = 1,
showarrow = FALSE)
b <- list(
text = sprintf("<b>2</b>"),
xref = "paper",
yref = "paper",
yanchor = "bottom",
xanchor = "center",
align = "center",
x = 0.5,
y = 1,
showarrow = FALSE)
c <- list(
text = sprintf("<b>3</b>"),
xref = "paper",
yref = "paper",
yanchor = "bottom",
xanchor = "center",
align = "center",
x = 0.5,
y = 1,
showarrow = FALSE)
Put together the actual plots, note the "annotations" option under layout. I also didn't need to add all that trace nonsense, coloring by status did the work for me.
p1 <- df_group %>%
filter(numbers == 1) %>%
group_by(letter) %>%
plot_ly(x = ~letter, y= ~n, color = ~status, type = 'bar', legendgroup = ~status) %>%
layout(barmode = 'stack', annotations = a)
p2 <- df_group %>%
filter(numbers == 2) %>%
group_by(letter) %>%
plot_ly(x = ~letter, y= ~n, color = ~status, type = 'bar', legendgroup = ~status, showlegend = FALSE) %>%
layout(barmode = 'stack', annotations = b)
p3 <- df_group %>%
filter(numbers == 3) %>%
group_by(letter) %>%
plot_ly(x = ~letter, y= ~n, color = ~status, type = 'bar', legendgroup = ~status, showlegend = FALSE) %>%
layout(barmode = 'stack', annotations = c)
Plotting:
subplot(p1, p2, p3, shareY = TRUE)
Imgur can't show interactivity, so you will just have to trust that this is interactive and you can select the categories in all plots by clicking on their labels.

Resources