How can I create a highcharts graph like this using the R highcharter package?
It is a simple count of sectors (instances) above or bellow 0 and coloured to reflect the value.
This may sometime be termed a dot plot (https://ggplot2.tidyverse.org/reference/geom_dotplot.html)?
image from (https://graphics.wsj.com/job-market-tracker/)
Some sample data:
data = data.table(
CJ(date = seq(as.IDate("2019-01-01"), as.IDate("2019-01-10"), by = "day"),
group = seq(1,20))
)
data[, value := runif(n=200, -5,5)]
This is as far as I got:
library(highcharter)
library(data.table)
data = data.table(
CJ(date = seq(as.Date("2019-01-01"), as.Date("2019-02-10"), by = "day"),
group = seq(1,20))
)
# generate random value
data[, value := round(runif(n=dim(data)[1], -5,5),4)]
# categorize it from 1 to 10
data[, cat:=cut(value, breaks=quantile(data[value!=0]$value, seq(0,1,0.1)), labels=seq(1,10))]
# assign colour based on value
colf = colorRampPalette(colors = c("red","yellow", "green"))
cols = colf(10)
data[, color := as.factor(cols[cat])]
# generate x and y
data[, x := datetime_to_timestamp(date)]
data[, y := order(order(value))-sum(value<0), date]
data[, name := group]
highchart() %>%
hc_chart(type = "scatter") %>%
hc_xAxis(type = "datetime", dateTimeLabelFormats = list(day = '%d of %b')) %>%
hc_tooltip(pointFormat = "Performance = <b>{point.value}</b> <br> Group = <b>{point.name}</b>") %>%
hc_add_theme(hc_theme_flat(chart = list(backgroundColor = "#FFF"))) %>%
hc_add_series(data, groupPadding=0)
It also works with more points:
Related
I'm trying to create a scatter plot using highchart, but the color in the graph and in the labels are different. The color should be defined by the column named "Check_color" beacuse i'm using into Rshiny app, and sometimes i don't have all the options in the graph and the color should be align with the column "Rank". I mean, if only "Yes" is selected all points should be green, if only "No", should be red, etc...
Ando Righ now in the graph "Yes" in green, but in the labels are blue, and the same for the rest. How can i math the colors in the labels? Thanks !!
This is my current code
data = data.table(
CJ(x = seq(as.Date("2019-01-01"), as.Date("2019-01-10"), by = "day"),
group = seq(1,20))
)
data[, value := round(runif(n=200, 0,5),4)]
data = data.table(data %>% mutate(cat=cut(value, breaks=quantile(data[value!=0]$value, seq(0,1,0.1)), labels=seq(1,10))))
colf = colorRampPalette(colors = c("red","yellow", "green"))
cols = colf(10)
data[, color := as.factor(cols[cat])]
data$x = datetime_to_timestamp(data$x)
data = data.table(data %>% group_by(x) %>% mutate(y = (order(order(value))-sum(value<0,na.rm=T))))
data[, name := group]
data$x <- runif(200, 100, 1000) / 10
data$y <- runif(200, 100, 1000) / 10
data$gp_ <- round(runif(200,1,5), digits = 0)
data$Index <- seq(1,200,1)
data$Rank <- ifelse(data$gp_ == 1 , "Yes", ifelse(data$gp_ == 2 , "No",ifelse(data$gp_ == 3 , "Minor Deficiency",ifelse(data$gp_ == 4 , "Major Deficiency",ifelse(data$gp_ == 5 , "Not Applicable","")))))
data <- data[1:71,]
data$Check_color <- ifelse(data$Rank == "Yes" , "#14E632", ifelse(data$Rank == "No" , "#FA0101",ifelse(data$Rank == "Minor Deficiency" , "#FF99FF",ifelse(data$Rank == "Major Deficiency" , "#FF9933",ifelse(data$Rank == "Not Applicable" , "#CACECE","")))))
hc_1 <- data %>%
hchart('scatter', hcaes(x = x, y = y , group = Rank, color = Check_color )) %>%
hc_title(text = "<b>PUBLIC COMPANY D&O COVERAGE HEAT MAP </b>") %>%
hc_chart(
borderColor = "#999999",
borderRadius = 20,
borderWidth = 3) %>%
hc_tooltip(pointFormat = 'Provision ID: {point.Index} <br/>
Provision: {point.Check_color} <br/>
Severity: {point.y:.2f} <br/>
Frequency: {point.x:.2f} ')
hc_1
The problem with the two color scales came from using group = Rank and color = Check_color in the hcaes. Remove color = Check_color, and you get matching color. However, I do not know how to specify the color from there... I tried hc_color() which didn't work. Maybe someone else can complete this answer!
hc_1 <- data %>%
hchart('scatter', hcaes(x = x, y = y , group = Rank )) %>%
hc_title(text = "<b>PUBLIC COMPANY D&O COVERAGE HEAT MAP </b>") %>%
hc_chart(
borderColor = "#999999",
borderRadius = 20,
borderWidth = 3) %>%
hc_tooltip(pointFormat = 'Provision ID: {point.Index} <br/>
Provision: {point.Check_color} <br/>
Severity: {point.y:.2f} <br/>
Frequency: {point.x:.2f} ')
hc_1
I have the following dataset:
xdata <- seq(as.Date("2020-01-01"),as.Date("2020-12-31"), "days")
ydata <- c(1:366)
datamipo <- data.frame(xdata,ydata)
And I want to plot the data by month and plot using highcharter:
datamipo %>%
mutate(month = format(xdata,"%b")) %>%
group_by(month) %>%
summarise(total = sum(ydata)) %>%
hchart(type = "line",
hcaes(x=month, y=total))
But the x axis doesn't recognize the data as dates and put them in alphabetical order. Please, do you know how can I group the date to show the totals by month? Thank you.
I would think about saving this data differently and operate on the actual values. Here you can see an example of such a setting:
df <- data_frame(
time = seq(as.Date("2020-01-01"), as.Date("2020-02-01"), by = 1),
value = sample(1000:2000, size = 32),
dt = datetime_to_timestamp(time)
)
hchart(df, "line", hcaes(dt, value)) %>%
hc_xAxis(type = "datetime", dateTimeLabelFormats = list(day = '%d dayview', week = '%d weekview'))
hchart(df, "line", hcaes(dt, value)) %>%
hc_xAxis(type = "datetime", dateTimeLabelFormats = list(day = '%d of %b', week = '%d of %b'))
R Code:
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
options(stringsAsFactors = FALSE)
rm(list = ls())
if (!require("pacman")) install.packages("pacman")
pacman::p_load("dplyr","tidyr","highcharter")
raw_data <- read.csv("results.csv")
DT <- data.table(raw_data)
cols <- c('Person','ABC_Capability','ABC_Sub.capability','Leadership.Facet','Facet.Score')
DT <- DT[, cols, with = FALSE]
names(DT) <- c('Person','Capability','Sub_Capability','SVL','Facet_Score')
DT <- dcast(DT, Capability + Sub_Capability + SVL ~ Person,
value.var = c('Facet_Score'))
DT1 <- DT %>%
group_by(name = Sub_Capability) %>%
do(categories = .$SVL) %>%
list_parse()
highchart() %>%
hc_chart(type = "bar") %>%
hc_title(text = "Some Title") %>%
hc_add_series(name="A", data = DT$Joan) %>%
hc_add_series(name="B", data = DT$Shane) %>%
hc_add_series(name="C", data = DT$Simon) %>%
hc_xAxis(categories = DT1)
Output:
I tried using a smaller dataset and realized every time there is a single value in a group. The label gets truncated. For example: Develops people > Empowering
Any help would be appreciated.
Like Kamil Kulig mentioned, you can try making the categories an array instead of vector and it worked for me. Using the sample code you provided, it would be:
DT1 <- DT %>%
group_by(name = Sub_Capability) %>%
# store SVL as array
do(categories = array(.$SVL)) %>%
list_parse()
New Update:
The vector needs to be converted to an array using the array() function even if you are not using grouped categories but simply wanted to rename the tick labels i.e.
highcharter::hchart(mtcars[1, ],
"column", name = "MPG",
highcharter::hcaes(x = 0, y = mpg),
showInLegend = F) %>%
# x axis format
highcharter::hc_xAxis(title = list(text ="Car Name"),
# relabel x axis tick to the name of the cars
categories = array(rownames(mtcars)[1]))
then the axis tick label will display the name of the car.
If you use simply categories = rownames(mtcars)[1]) instead of converting it into an array the x axis label won't display properly:
Here the tick label is just M instead of Mazada RX4.
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!"
)
)
)
I am trying to create an interactive Version of this plot:
So far I have the following code that creates an interactive plot but is not exactly what I am looking for:
#Create Data
library(ggvis)
set.seed(123)
tdat <- data.frame(group = rep(LETTERS[1:2], each = 50),
time = rep(seq(from = as.Date("2010-01-01"), length.out = 50, by = "day"), 2),
val = c(cumsum(rnorm(50)) + 100,
cumsum(rnorm(50)) + 100))
# ggvis Code
# Function for the tooltip
getData <- function(dat){
paste(paste("Time:", as.character(dat$time)),
paste("Group:", as.character(dat$group)),
paste("Value:", dat$val),
sep = "<br />")
}
# Visualisation
tdat %>% ggvis(~time, ~val, stroke = ~group) %>% layer_lines(strokeWidth := 1) %>%
layer_points(size = 1, fill = ~group) %>% add_tooltip(getData)
This results in the following plot:
There are however some issues:
1) I don't want to have points, just lines. Without the layer_points, there are no tooltips...
2) The variable time is a date but shows up as an integer. How can I fix the ugly number?
Thank you very much.
Edit
The field of the tooltip can be formated to date if it is coerced to a char before calling the ggvis function but it introduces other issues. For example, the x-axis does not shown properly.
I found a solution for both:
#Create Data
library(ggvis)
set.seed(123)
tdat <- data.frame(group = rep(LETTERS[1:2], each = 50),
time = rep(seq(from = as.Date("2010-01-01"), length.out = 50, by = "day"), 2),
val = c(cumsum(rnorm(50)) + 100,
cumsum(rnorm(50)) + 100))
For the getData function a bit of reverse engineering made me find the solution. Apparently if you divide the numeric date by 86400000 and add the origin of 1970-01-01 makes it work.
# ggvis Code
# Function for the tooltip
getData <- function(dat){
paste(paste("Time:", as.Date(dat$time/86400000, origin='1970-01-01') ),
paste("Group:", as.character(dat$group)),
paste("Value:", dat$val),
sep = "<br />")
}
As for the points, just setting the opacity to zero makes it work:
# Visualisation
tdat %>% ggvis(~time, ~val, stroke = ~group) %>% layer_lines(strokeWidth := 1) %>%
layer_points(size = 1, fill = ~group, opacity := 0) %>% add_tooltip(getData)
Ouput:
Sorry for the bad output but this was the best I could get via a print screen.