In my previous post about {highcharter}, I considered changing some of the defaults for a scatter graph to make it look more appealing and be more accessible. This post will focus on plotting the following different types of graphs:
Bar charts, including grouped bar charts
Icon plots
Line graphs
Stream graphs
First, we will load the packages we require in this post. The {highcharter} (Kunst 2022) and {tidyverse} (Wickham et al. 2019) packages are used throughout. The {medicaldata} package (Higgins 2021) is used to create the bar charts and (some of) the line graphs. The icon plots use data obtained via the {clmnis} package (Dempsey 2025).
Wickham, Hadley, Mara Averick, Jennifer Bryan, Winston Chang, Lucy D’Agostino McGowan, Romain François, Garrett Grolemund, et al. 2019. “Welcome to the tidyverse.”Journal of Open Source Software 4 (43): 1686. https://doi.org/10.21105/joss.01686.
library(highcharter)library(paletteer) # colour paletteslibrary(tidyverse)library(gapminder)# medical data package# use 'remotes::install_github("higgi13425/medicaldata")' to access the 'thiomon' datasetlibrary(medicaldata)# obtaining MP information# remotes::install_github("houseofcommonslibrary/clmnis")library(clmnis)library(fontawesome)
Bar charts
For the bar charts, I’m using data obtained from the {medicaldata} package. Loading the Covid data1, and ensuring factors are coded correctly.
covid <-tibble(medicaldata::covid_testing)covid <- covid |>mutate(across(c(gender, test_id, demo_group, drive_thru_ind, result, payor_group, patient_class), as_factor))# look at levels of the factors#sapply(covid[, c("gender", "test_id", "demo_group", "drive_thru_ind", "result", "payor_group", "patient_class")], levels)covid
Let’s start with a simple bar chart, showing the frequency of negative and positive Covid results.
First we create counts of positive, negative and invalid results.
Code
result_counts <- covid |>count(result) |># capitalise first lettermutate(result =str_to_title(as.character(result))) |>arrange(desc(n))
Code
# Create the bar charthchart( result_counts,type ="bar",hcaes(x = result, y = n),name ="Results" ) |>hc_title(text ="Results of Covid Tests") |>hc_xAxis(title =list(text ="Result")) |>hc_yAxis(title =list(text ="Count")) |>hc_colors("#003087") |># a sourcehc_credits(text ="Data obtained from the {medicaldata} package",href ="https://higgi13425.github.io/medicaldata/",enabled =TRUE ) |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="covid_bar" ) |>hc_plotOptions(accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Grouped bar chart
Group results by gender.
Code
result_counts_gender <- covid |>group_by(gender) |>count(result) |># capitalise first lettermutate(result =str_to_title(as.character(result)))
The hover box issues
The hard part here seems to be getting the hover box to output the correct things. Specifically, I don’t know how to get the names of the y-axis titles (“Positive”, etc.), without doing nested if statements. It must involve the formatter but I’m not sure how.
FIXED: use this.key to get the names.
Code
hchart( result_counts_gender,type ="bar",hcaes(x = result, y = n, group = gender) ) |>hc_colors(c("#003087", "#006747")) |>hc_title(text ="Lots of people don't have Covid",align ="left") |>hc_subtitle(text ="A bar chart showing Covid test results, split by gender.",align ="left") |>hc_xAxis(title =list(text ="Result")) |>hc_yAxis(title =list(text ="Count")) |># a sourcehc_credits(text ="Data obtained from the {medicaldata} package",href ="https://higgi13425.github.io/medicaldata/",enabled =TRUE ) |>hc_tooltip(formatter =JS("function () { if (this.series.name == 'male') { return `<b>Male</b></br>${this.y} ${this.key} results` } else if (this.series.name == 'female') { return `<b>Female</b></br> ${this.y} ${this.key} results` }}") ) |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="covid_bar" ) |>hc_plotOptions(accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Icons plot
Let’s look at the gender split in parliament as of 31st December 2024. We can extract the data using {clmnis}(Dempsey 2025), which is an R package for downloading data from the UK Parliament’s Members Names Information Service (MNIS).
hchart( mps_gender,"item",hcaes(name = gender,y = n,color = col ),name ="Number of MPs",showInLegend =TRUE,size ="100%",center =list("50%", "75%"),startAngle =-100,endAngle =100) %>%hc_title(text ="Male MPs make up a significant majority of the House of Commons",align ="left" ) %>%hc_subtitle(text ="An item chart showing the proportion of male and femal MPs in the House of Commons, on 31st December 2024.",align ="left" ) |>hc_legend(labelFormat ='{name} <span style="opacity: 0.4">{y}</span>') |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="mp_icon_plot" ) |>hc_plotOptions(accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
To change the plot to a circular layout, set startAngle = -180 and endAngle = 180 and change the center argument.
Code
hchart( mps_gender,"item",hcaes(name = gender,y = n,color = col ),name ="Number of MPs",showInLegend =TRUE,size ="100%",center =list("50%", "50%"),startAngle =-180,endAngle =180) %>%hc_title(text ="Male MPs make up a significant majority of the House of Commons",align ="left" ) %>%hc_subtitle(text ="An item chart showing the proportion of male and femal MPs in the House of Commons, on 31st December 2024.",align ="left" ) |>hc_legend(labelFormat ='{name} <span style="opacity: 0.4">{y}</span>') |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="mp_icon_plot" ) |>hc_plotOptions(accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Adding symbols to the icon chart
What if we want female and male symbols instead of circles, and the icons arranges in a rectangle?
hchart( mps_gender_icon,"item",hcaes(name = gender,y = n,color = col ),name ="Number of MPs",showInLegend =TRUE,size ="100%") |>hc_title(text ="Male MPs make up a significant majority of the House of Commons",align ="left" ) |>hc_subtitle(text ="An item chart showing the proportion of male and femal MPs in the House of Commons, on 31st December 2024.",align ="left" ) |>hc_legend(labelFormat ='{name} <span style="opacity: 0.4">{y}</span>') |>hc_plotOptions(item =list(layout ="vertical",rows =18# Specify the number of rows here ) ) |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="mp_icon_plot" ) |>hc_plotOptions(accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Line graphs
Using data obtained from the {gapminder} package (Bryan 2023), we will produce a line graph. A few new things here:
gapminder_line <- gapminder |>filter(country %in%c("United Kingdom","France","Germany","Italy","Netherlands"))hchart(gapminder_line, "line",hcaes(x = year, y = pop, group = country)) |>hc_title(text ="The Netherlands has a much smaller population than Germany.",align ="left" ) |>hc_subtitle(text ="A line chart showing changes in population between 1952 and 2007.",align ="left" ) |>hc_xAxis(title =list(text ="Year")) |>hc_yAxis(title =list(text ="Population")) |># a sourcehc_credits(text ="Data obtained from the {gapminder} package",href ="https://www.gapminder.org/",enabled =TRUE ) |>hc_colors(colors =as.character(paletteer::paletteer_d("lisa::FridaKahlo"))) |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="population_line" ) |>hc_plotOptions(series =list(label =list(enabled =TRUE, # add labels to linesstyle =list(fontWeight ="bold",color ="#333" ),connectorAllowed =FALSE# include line connecting label to series? ),lineWidth =2,marker =list(enabled =FALSE, # remove markerssymbol ="circle",states =list(hover =list(enabled =TRUE# enable markers if hovered over ) ) )),accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Stream graphs
Copying the line graph we produced above.
Code
hchart(gapminder_line, "streamgraph", zoomType ="x",hcaes(x = year, y = pop, group = country)) |>hc_title(text ="The populations in these countries are relatively steady over time.",align ="left" ) |>hc_subtitle(text ="A line chart showing changes in population between 1952 and 2007.",align ="left" ) |>hc_xAxis(title =list(text ="Year")) |>hc_yAxis(visible =FALSE, startOnTick =FALSE, endOnTick =FALSE, title =list(text ="Population")) |># a sourcehc_credits(text ="Data obtained from the {gapminder} package",href ="https://www.gapminder.org/",enabled =TRUE ) |>hc_colors(colors =as.character(paletteer::paletteer_d("lisa::FridaKahlo"))) |>hc_exporting(accessibility =list(enabled =TRUE# default value is TRUE ),enabled =TRUE,filename ="population_line" ) |>hc_plotOptions(series =list(label =list(enabled =TRUE, # add labels to linesstyle =list(fontWeight ="bold",color ="#555555" ),connectorAllowed =FALSE# include line connecting label to series? ),lineWidth =2,marker =list(enabled =FALSE, # remove markerssymbol ="circle",states =list(hover =list(enabled =FALSE# enable markers if hovered over ) ) )),accessibility =list(enabled =TRUE,keyboardNavigation =list(enabled =TRUE) ) )
Copying the example given in the Highchart demos. First, we will create a list of data – medals won by countries in the Winter Olympics, which is taken from Olympedia.
I have shamelessly stolen this next chart from Joshua Kunst who created it in a {highcharter} article, and in turn stole the idea from the Wall Street Journal. But, it is such a nice chart that I can’t not reproduce it here.