pie chart highcharter R - r

I am plotting a pie chart using highcharter. when the mouse hover on each slice< it only shows just one value, but I want to add another value so that it shows two!
here is a sample code:
in my code you see that it is ploting the data using just A column and B column, but I want it to show C column as additional information as the mouse hover on slices.
library(highcharter)
A <- c("a", "b", "c", "d")
B <- c(4, 6, 9, 2)
C <- c(23, 26, 13, 15)
df <- data.frame(A, B, C)
highchart() %>%
hc_chart(type = "pie") %>%
hc_add_series_labels_values(labels = df$A, values = df$B)%>%
hc_tooltip(crosshairs = TRUE, borderWidth = 5, sort = TRUE, shared = TRUE, table = TRUE,
pointFormat = paste('<b>{point.percentage:.1f}%</b>')
) %>%
hc_title(text = "ABC",
margin = 20,
style = list(color = "#144746", useHTML = TRUE))

To my knowledge, the solution proposed by #ewolden does not work in highcharter.
A simple and flexible solution for setting additional information to the tooltip of a highcharter pie is the following:
library(highcharter)
A <- c("a", "b", "c", "d")
B <- c(4, 6, 9, 2)
C <- c(23, 26, 13, 15)
df <- data.frame(A, B, C)
# A modified version of the "hc_add_series_labels_values" function
# The "text" input is now available
myhc_add_series_labels_values <- function (hc, labels, values, text, colors = NULL, ...)
{
assertthat::assert_that(is.highchart(hc), is.numeric(values),
length(labels) == length(values))
df <- dplyr::data_frame(name = labels, y = values, text=text)
if (!is.null(colors)) {
assert_that(length(labels) == length(colors))
df <- mutate(df, color = colors)
}
ds <- list_parse(df)
hc <- hc %>% hc_add_series(data = ds, ...)
hc
}
# Set the "text" input in myhc_add_series_labels_values
# point.text is now available inside pointFormat of hc_tooltip
highchart() %>%
hc_chart(type = "pie", data=df) %>%
myhc_add_series_labels_values(labels=A, values=B, text=C) %>%
hc_tooltip(crosshairs=TRUE, borderWidth=5, sort=TRUE, shared=TRUE, table=TRUE,
pointFormat=paste('<br><b>A: {point.percentage:.1f}%</b><br>C: {point.text}')) %>%
hc_title(text="ABC", margin=20, style=list(color="#144746", useHTML=TRUE))
With this solution we can print the content of two or more variables inside the tooltip. Below we add a variable D to the df dataset and visualize it in the tooltip:
D <- c("Mars", "Jupiter", "Venus", "Saturn")
df <- data.frame(A, B, C, D)
txt <- paste("C:",C," <br>D:", D)
highchart() %>%
hc_chart(type="pie", data=df) %>%
myhc_add_series_labels_values(labels=A, values=B, text=txt) %>%
hc_tooltip(crosshairs=TRUE, borderWidth=5, sort=TRUE, shared=TRUE, table=TRUE,
pointFormat=paste('<br><b>A: {point.percentage:.1f}%</b><br>{point.text}')) %>%
hc_title(text = "ABC", margin = 20, style = list(color = "#144746", useHTML = TRUE))

You can make a chart with custom names in highcharts like so:
http://jsfiddle.net/zh65suhm/.
That is, changing your tooltip to the following:
'<b>{point.percentage:.1f}%</b><br>Custom point: <b>{point.customData}</b>'
Where each point has its own customData value.
I have not used highcharter, but looking at the API it might be possible to some work with this:
hc_add_series(favorite_bars, "pie", hcaes(name = bar, y = percent), name = "Bars") %>%
Potentially this could work:
hc_add_series(favorite_bars, "pie", hcaes(name = bar, y = percent, customData = variable_with_customdata), name = "My pie") %>%
Hopefully this will help you out.

Related

Use RGB Customers Colors by Group in R Plotly

I have several series which I would like to animate with plotly R. After following the example here (https://plot.ly/r/cumulative-animations/), I have the animation working. I figured out how to change the colors for the groups, however, I need specific colors for the groups (RGB custom colors).
I have two questions:
How do I assign RGB colors to groups in R Plotly...what am I missing here?
Is there an easier way to do this? I have several more "cities" than just two, and want to be able to dynamically assign the specific color. I was able to pull the colors in as a column in the data frame, and would like to be able to assign them that way...got it working for the regular colors, but need to get it for the RGB...
library(plotly)
# Helper function to create frames
accumulate_by <- function(dat, var) {
var <- lazyeval::f_eval(var, dat)
lvls <- plotly:::getLevels(var)
dats <- lapply(seq_along(lvls), function(x) {
cbind(dat[var %in% lvls[seq(1, x)], ], frame = lvls[[x]])
})
dplyr::bind_rows(dats)
}
# Pull in data and also create color columns
d <-
txhousing %>%
filter(year > 2005, city %in% c("Abilene", "Bay Area")) %>%
accumulate_by(~date) %>%
mutate(regular_color = if_else(city == "Abilene", 'red', 'black'),
RGB_color = if_else(city == "Abilene", 'rgb(229,18,18)', 'rgb(13,9,9)'))
# color vectors
reg_color_vector <-
d %>%
arrange(city) %>%
select(regular_color) %>%
distinct() %>%
pull()
RGB_color_vector <-
d %>%
arrange(city) %>%
select(RGB_color) %>%
distinct() %>%
pull()
p <- d %>%
plot_ly(
x = ~date,
y = ~median,
split = ~city,
frame = ~frame,
type = 'scatter',
mode = 'lines',
line = list(simplyfy = F),
color = ~city,
# colors = c('red', 'black')
colors = c('rgb(229, 18, 18)', 'rgb(13, 9, 9)')
# colors = reg_color_vector
# colors = RGB_color_vector
) %>%
layout(
xaxis = list(
title = "Date",
zeroline = F
),
yaxis = list(
title = "Median",
zeroline = F
)
) %>%
animation_opts(
frame = 100,
transition = 0,
redraw = FALSE
) %>%
animation_slider(
hide = T
) %>%
animation_button(
x = 1, xanchor = "right", y = 0, yanchor = "bottom"
)
p
rgb() is a function which outputs a hexadecimal value of the color you want. That is what you need to store. Remove the ' and it should be fine. And you need to add maxColorValue = 255 to the rgb() function.
d <-
txhousing %>%
filter(year > 2005, city %in% c("Abilene", "Bay Area")) %>%
accumulate_by(~date) %>%
mutate(regular_color = if_else(city == "Abilene", 'red', 'black'),
RGB_color = if_else(city == "Abilene",
rgb(229, 18, 18, maxColorValue = 255),
rgb(13, 9, 9, maxColorValue = 255)))
You can use in plot_ly than the RGB_color_vector to define the colors.
plot_ly(
x = ~date,
y = ~median,
split = ~city,
frame = ~frame,
type = 'scatter',
mode = 'lines',
line = list(simplyfy = F),
color = ~city,
colors = RGB_color_vector
)

Interactively select a grouping variable in plotly

How can I create a grouped bar chart in plotly that has a dropdown (or something else), so a viewer can select the grouping variable?
Working example:
library(dplyr)
library(plotly)
library(reshape2)
iris$Sepal.L <- iris$Sepal.Length %>%
cut(breaks = c(4,5,7,8),
labels = c("Length.a","Length.b","Length.c"))
iris$Sepal.W <- iris$Sepal.Width %>%
cut(breaks = c(1,3,5),
labels = c("Width.a","Width.b"))
# Get percentages
data1 <- table(iris$Species, iris$Sepal.L) %>%
prop.table(margin = 1)
data2 <- table(iris$Species, iris$Sepal.W) %>%
prop.table(margin = 1)
# Convert to df
data1 <- data.frame(Var1=row.names(data1), cbind(data1))
row.names(data1) <- NULL
data2 <- data.frame(Var1=row.names(data2), cbind(data2))
row.names(data2) <- NULL
plot_ly(
data = data1,
name = "Length.a",
x = ~Var1, y = ~Length.a,
type = "bar") %>%
add_trace(y=~Length.b, name = "Length.b") %>%
add_trace(y=~Length.c, name = "Length.c")
plot_ly(
data = data2,
name = "Width.a",
x = ~Var1, y = ~Width.a,
type = "bar") %>%
add_trace(y=~Width.b, name = "Width.b")
For example if I would like to select between viewing a plot with table(iris$Species, iris$Sepal.Length) and a plot with table(iris$Species, iris$Sepal.Width)
Bonus:
If it's easy; being able to interactively select the x variable as well would be cool, but not necessary.
You can find a solution here.
The idea is to plot your bar charts (with data1 and data2) all together and to make visible only one at a time.
items <- list(
list(label="Var1",
args=list(list(visible=c(T,T,T,F,F)))),
list(label="Var2",
args=list(list(visible=c(F,F,F,T,T))))
)
plot_ly(data=data1) %>%
add_bars(name = "Length.a",
x = ~Var1, y = ~Length.a, visible=T) %>%
add_bars(name = "Length.b",
x = ~Var1, y = ~Length.b, visible=T) %>%
add_bars(name = "Length.c",
x = ~Var1, y = ~Length.c, visible=T) %>%
add_bars(name = "Width.a",
x = ~Var1, y = ~Width.a, visible=F, data=data2, marker=list(color="#377EB8")) %>%
add_bars(name = "Width.b",
x = ~Var1, y = ~Width.b, visible=F, data=data2, marker=list(color="#FF7F00")) %>%
layout(
title = "Bar chart with drop down menu",
xaxis = list(title="x"),
yaxis = list(title = "y"),
showlegend = T,
updatemenus = list(
list(y = 0.9,
buttons = items)
))

annotation in highchart doesn't work as expected

I was using Highchart to plot some time series and wanted to add some annotation to the plot to highlight some key points. I knew putting the cursor on the graph can pop up the context, however, some automatic graph generation is needed and hence annotating is the best approach.
And I did that, with the last line in the code below. However, the effect is not what I expected. The text was located at the bottom left corner, not located at the right horizontal position yet the vertical position is right. The time series are created using xts library, which means the horizontal axis is simply the date data structure, nothing fancy. xValue is specified as the 900th element of all the time points which have a total length of 1018, so the 900th time point must be in the second half of the graph.
Anyone knows how I can put the annotation at the right location? Many thanks.
hc <- highchart(type = "stock") %>%
hc_title(text = "Some time series") %>%
hc_add_series(x, color='green', name="x", showInLegend = TRUE) %>%
hc_add_series(y, color='red', name="y", showInLegend = TRUE) %>%
hc_add_series(z, color='blue', name="z", showInLegend = TRUE) %>%
hc_navigator(enabled=FALSE) %>%
hc_scrollbar(enabled=FALSE) %>%
hc_legend(enabled=TRUE, layout="horizontal") %>%
hc_annotations(list(enabledButtons=FALSE, xValue = index(x)[900], yValue = -5, title =list(text = "Hello world! How can I make this work!")))
hc
The data can be roughly generated using the following script:
dt <- seq(as.Date("2014/1/30"), as.Date("2018/2/6"), "days")
dt <- dt[!weekdays(dt) %in% c("Saturday", "Sunday")]
n <- length(dt)
x <- xts(rnorm(n), order.by=dt)
y <- xts(rnorm(n), order.by=dt)
z <- xts(rnorm(n), order.by=dt)
Let's star with the #kamil-kulig example, this will be a little out of R world but I want to give some justification if you don't mind.
If we see annotations options is not a object but a list of object(s), so in highcharter is implemented the hc_add_annotation function.
Now, you are using a old version of highcharter. Highcharter devlopment version is using v6 of highchartsJS which made some changes: before the annotations.js was a pluging now is included as a module with some changes in the names of arguments.
Example I: Simple
The example by Kamil Kulig is replicated doing:
highchart(type = "stock") %>%
hc_add_annotation(
labelOptions = list(
backgroundColor = 'rgba(255,255,255,0.5)',
verticalAlign = 'top',
y = 15
),
labels = list(
list(
point = list(
xAxis = 0,
yAxis = 0,
x = datetime_to_timestamp(as.Date("2017/01/02")),
y = 1.5
),
text = "Some annotation"
)
)
) %>%
hc_xAxis(
minRange = 1
) %>%
hc_add_series(
pointStart = start,
pointInterval = day,
data = c(3, 4, 1)
)
Example II: With your data
Be careful in the way you add the x position. Highcharter include a datetime_to_timestamp function to convert a date into a epoch/timestap which is required for highcharts.
library(xts)
dt <- seq(as.Date("2014/1/30"), as.Date("2018/2/6"), "days")
dt <- dt[!weekdays(dt) %in% c("Saturday", "Sunday")]
n <- length(dt)
x <- xts(rnorm(n), order.by=dt)
y <- xts(rnorm(n), order.by=dt)
z <- xts(rnorm(n), order.by=dt)
highchart(type = "stock") %>%
hc_title(text = "Some time series") %>%
hc_add_series(x, color='green', name="x", showInLegend = TRUE) %>%
hc_add_series(y, color='red', name="y", showInLegend = TRUE) %>%
hc_add_series(z, color='blue', name="z", showInLegend = TRUE) %>%
hc_navigator(enabled=FALSE) %>%
hc_scrollbar(enabled=FALSE) %>%
hc_legend(enabled=TRUE, layout="horizontal") %>%
hc_add_annotation(
labels = list(
list(
point = list(
xAxis = 0,
yAxis = 0,
x = datetime_to_timestamp(as.Date(index(x)[900])),
y = 1
),
text = "Hello world! How can I make this work!"
)
)
)

R Plotly set custom colors for bar chart

I've got a plotly bar chart in my Shiny app, and I'd like to set specific colors each column in the resulting bar chart.
#Here's some reproducible data
df=data.frame(Month=c("Jan","Feb","Mar","Apr","May","Jun"),Criteria1=c(10,15,20,15,7,6),Criteria2=c(3,8,5,7,9,10),Criteria3=c(11,18,14,9,3,1))
#Plot
colNames <- names(df)[-1] #Month is the first column
# Here is where I set the colors for each `Criteria`, assuming that the order of colors follows the same order as the factor levels of the `Criteria`.
p <- plotly::plot_ly(marker=list(colors=c('#CC1480', '#FF9673', '#E1C8B4')))
for(trace in colNames){
p <- p %>% plotly::add_trace(data = df, x = ~Month, y = as.formula(paste0("~`", trace, "`")), name = trace, type = "bar")
}
p %>%
layout(title = "Trend Over Time",showlegend = FALSE,
xaxis = list(title = ""),
yaxis = list (title = "Monthly Count of QoL Tweets"))
However the resulting plot does not show any of the colors I specify.
What am I doing incorrectly? Any pointers would be very appreciated.
I don't think loop is neccessary here, the following provides as well more control over choosing the color for specific levels when df is melted, the individual levels Criteria1, Criteria2, Criteria3
library(plotly)
library(reshape2)
#Yout data.frame
df <- data.frame(Month = c("Jan","Feb","Mar","Apr","May","Jun"),
Criteria1 = c(10,15,20,15,7,6),
Criteria2 = c(3,8,5,7,9,10),
Criteria3 = c(11,18,14,9,3,1))
melt(df, id.vars = 'Month') %>% plot_ly(x = ~Month, y = ~value, type = 'bar',
color = ~variable,
colors = c(Criteria1 = '#CC1480', Criteria2 = '#FF9673', Criteria3 = '#E1C8B4'))
You could assign your colors to a vector:
colors <- c('#CC1480', '#FF9673', '#E1C8B4')
and then add the traces in a slightly modified loop.
p <- plotly::add_trace(p,
x = df$Month,
y = df[,trace],
marker = list(color = colors[[match(trace, colNames)]]),
name = trace,
type = "bar")
}
which will give you the following graph
Complete code
library("plotly")
df=data.frame(Month=c("Jan", "Feb","Mar", "Apr", "May", "Jun"),
Criteria1 = c(10, 15,20,15,7,6),
Criteria2 = c(3, 8, 5, 7, 9, 10),
Criteria3 = c(11, 18, 14, 9, 3, 1))
colNames <- names(df)[-1] #Month is the first column
colors <- c('#CC1480', '#FF9673', '#E1C8B4')
p <- plotly::plot_ly()
#colNames = c('Criteria1')
for(trace in colNames){
p <- plotly::add_trace(p,
x = df$Month,
y = df[,trace],
marker = list(color = colors[[match(trace, colNames)]]),
name = trace,
type = "bar")
}
p

Highchart shiny R scatter plot - how to define individual point colors

I'm trying to create a scatter plot in highcharts shiny R but I need to give a different color to points, individually. Consider for instance the following example:
library("MASS")
dscars <- round(mvrnorm(n = 20, mu = c(1, 1), Sigma = matrix(c(1,0,0,1),2)), 2)
highchart() %>%
hc_chart(type = "scatter", zoomType = "xy") %>%
hc_tooltip(
useHTML = TRUE,
pointFormat = paste0("<span style=\"color:{series.color};\">{series.options.icon}</span>",
"{series.name}: <b>[{point.x}, {point.y}]</b><br/>")
) %>%
hc_add_series(data = list.parse2(as.data.frame(dscars)),
marker = list(symbol = fa_icon_mark("car")),
icon = fa_icon("car"), name = "car")
My objective is to give to this 20 points, an unique color.
I tried to set the "fillColor" inside marker list as also as to define the color of the series, both with a vector of 20 colors but I had no success.
Can any one give me a hint?
Thank you
In highcharts (the highcharter) the point can be given as other parameter, same as x and y. So first
library("MASS")
dscars <- round(mvrnorm(n = 20, mu = c(1, 1), Sigma = matrix(c(1,0,0,1),2)), 2)
dscars <- as.data.frame(dscars)
names(dscars) <- c("x", "y") # it's better give a named list IMHO
dscars$color <- colorize(1:nrow(dscars))
colorizeis a function to create a color vector given other vector. In this case the input vector is a sequence (no repeated) so the output will be differents colors. But if you want yo can use your own colors.
highchart() %>%
hc_chart(type = "scatter", zoomType = "xy") %>%
hc_tooltip(
useHTML = TRUE,
pointFormat = paste0("<span style=\"color:{point.color};\">{series.options.icon}</span>",
"{series.name}: <b>[{point.x}, {point.y}]</b><br/>")
) %>%
hc_add_series(data = list_parse(dscars),
marker = list(symbol = fa_icon_mark("car")),
icon = fa_icon("car"), name = "car")
Note we used:
color:{point.color}; in the poinFormat, beacuse every point has its own color in the color accesor.
I used list_parse which parse the data frame in a named list instead of unnamed list so highcharts understand how to use the data. list_parse is the same list.parse3 for old version of highcharts.
Hope it helps.
Is this what you want?
rm(list = ls())
library(highcharter)
library(MASS)
dscars <- data.frame(round(mvrnorm(n = 20, mu = c(1, 1), Sigma = matrix(c(1,0,0,1),2)), 2))
highchart() %>%
hc_chart(type = "scatter", zoomType = "xy") %>%
hc_tooltip(
useHTML = TRUE,
pointFormat = paste0("<span style=\"color:{colorByPoint:true};\">{series.options.icon}</span>",
"{series.name}: <b>[{point.x}, {point.y}]</b><br/>")
) %>%
hc_add_series(data = list.parse2(as.data.frame(dscars)),colorByPoint = TRUE,
marker = list(symbol = fa_icon_mark("car")),
icon = fa_icon("car"), name = "car")

Resources