Highcharter Examples

Bar chart

Create a bar chart of Meta (Facebook) profits by fiscal year

d1 |> 
  filter(tic == "META") |> 
  group_by(fyearq) |> 
  summarize(oiadpq = sum(oiadpq, na.rm = TRUE), .groups = "drop") |> 
  hchart(type = "column", hcaes(x = as.factor(fyearq), y = oiadpq)) |> 
  hc_add_theme(hc_theme_economist())

Play around with a few themes and then finalize one theme that you like: https://jkunst.com/highcharter/articles/themes.html#themes-1 https://jkunst.com/highcharter/reference/index.html#section-themes

When you hover mouse over the bars, you will notice the tooltip shows “Series 1” rather than the variable name oibdp. Admittedly, both “Series 1” and oibdp are equally obtuse but we can do better. Let’s label the series “Operating Profits”

plot1 = d1 |> 
  filter(tic == "META") |> 
  group_by(fyearq) |> 
  summarize(oiadpq = sum(oiadpq, na.rm = TRUE), .groups = "drop") |> 
  hchart(type = "column", hcaes(x = as.factor(fyearq), y = oiadpq)) |> 
  hc_add_theme(hc_theme_monokai())

plot1

When you hover mouse over the bars, you will notice the tooltip shows “Series 1” rather than the variable name oiadpq. Admittedly, both “Series 1” and oiadpq are equally obtuse but we can do better. Let’s label the series “Operating Profits”

The changes in the plot below are as follows:

  1. The header of the tooltip clarifies that it is a fiscal year. Next, it also adds a hyperlink to the filings on the Securities and Exchange Commission’s (SEC’s) EDGAR system.

  2. Changed the content of the tooltip and added more description replacing the default “Series 1” label

plot2 = plot1 |> 
  hc_tooltip(
    headerFormat = "<b>Fiscal Year: {point.x} </b><a href='https://www.sec.gov/edgar/browse/?CIK=0001326801'>SEC </a><br>",
    pointFormat = "<span style='color:#f82267'>\U25CF </span><b>Operating Profit: {point.y}</b>",
    hideDelay = 1500,
    useHTML = TRUE,
    style = list(pointerEvents = 'auto')
  )

plot2

Change the axes titles

Note that I also changed the theme and rotated the X axis text by 270 degrees.

plot3 = plot2 |> 
  #hc_add_theme(hc_theme_ft()) |>
  hc_xAxis(title = list(text = "Fiscal Year",
                        style = list(color = "#FFFFFF", fontWeight = "bold")),
           labels = list(rotation = 270,
                         style=list(color="#FFFFFF"))) |> 
  hc_yAxis(title = list(text = "Operating Income in Million USD",
                        style = list(color = "#FFFFFF", fontWeight = "bold")),
labels=list(style=list(color="#FFFFFF")))

plot3

Add title and subtitle

I will switch back to the original theme. But recall that in the previous plot I changed the axis titles color to black. This will not generate enough contrast when we use a dark theme. Therefore, I will make the font color white.

plot4 = plot3 |> 
    hc_xAxis(title = list(text = "Fiscal Year",
                        style = list(color = "white", fontWeight = "bold")),
           labels = list(rotation = 270)) |> 
  hc_yAxis(title = list(text = "Operating Income in Million USD",
                        style = list(color = "white", fontWeight = "bold"))) |> 
  hc_title(text = "Evil = Profitable??", align = "center") |>
  hc_subtitle(text = "Despite all the scandals, Facebook's operating income is consistently growing",
              align = "center") |> 
  hc_add_theme(hc_theme_monokai())

plot4

Next, add an emoji to the title. This requires useHTML set to TRUE inside hc_title(). You can get a relevant decimal code for any emoji online. For example, check this out: https://www.w3schools.com/charsets/ref_emoji.asp

plot5 = plot4 |> 
  hc_title(text = '<span style="font-family: helvetica, inter, sans-serif;"><strong><span style="color: #3598db;">Evil = Profitable??</span></strong></span> <span>&#129297;</span>',
           useHTML = TRUE, align = "center")

plot5

Line graph

Plot a line graph of Apple’s leverage ratio over the years.

The leverage ratio is given by (dlttq + dlcq) / atq where dlttq is long-term debt and dlcq is short-term debt. If any of these variables is missing, we should assume they are 0.

d1 |> 
  filter(tic == "AAPL") |> 
  mutate(leverage = (replace_na(dlttq, 0) + replace_na(dlcq, 0))/ atq,
         leverage = round(leverage, 2)) |> 
  hchart("line", hcaes(x = datadate, y = leverage), name = "Leverage") |> 
  # Change these titles
  #hc_xAxis() |> 
 # hc_yAxis() |> 
  hc_add_theme(hc_theme_538())

Scatterplot

Create a scatterplot of profit by sales

d1 |> 
  hchart("scatter", hcaes(x = saleq, y = oibdpq, group = conm)) |> 
  hc_add_theme(hc_theme_538())

Here, the colors are repeating because the color palette doesn’t have 7 unique colors. We can pass our own colors using hc_colors(). I will use viridis color palettes because it has 256 colors.

Notice that cols color vector in the code below has 8 characters instead of 6 as expected in a typical hex code. The two extra characters are for alpha. We have to remove them before we can use them here. Read more about it here: https://www.quackit.com/css/color/values/css_hex_color_notation_8_digits.cfm

cols = viridisLite::viridis(10, option = "H")

cols = substr(cols, 0, 7) # This will retain first 7 characters including the # sign.

d1 |> 
  hchart("scatter", hcaes(x = saleq, y = oibdpq, group = conm)) |> 
  hc_add_theme(hc_theme_538()) |> 
  hc_colors(cols)

Use pals package for more discrete colors: https://rdrr.io/cran/pals/man/discrete.html

cols = pals::alphabet() |> unname()
# unname will remove the names from the vector. Highcharter throws an error if you pass a named vector with colors.

d1 |> 
  hchart("scatter", hcaes(x = saleq, y = oibdpq, group = conm)) |> 
  hc_add_theme(hc_theme_538()) |> 
  hc_colors(cols)

Adding a regression line to the scatterplot

We will use a regression plugin to get a regression line. The plugins are available in the following folder on your computer:

Run this code in the console dir(system.file(“htmlwidgets/lib/highcharts/plugins”, package = “highcharter”))

Here is the vignette for regression plugin: https://jkunst.com/highcharter/reference/hc_add_dependency.html

d1 |> 
  filter(tic == "AAPL") |> 
  hchart("scatter", hcaes(x = saleq, y = oibdpq), regression = TRUE) |>
  hc_add_dependency("plugins/highcharts-regression.js") |>
  hc_add_theme(hc_theme_538())

Heatmap

We did not see static heatmaps with ggplot2 so let’s learn how to get them using highcharter

To create a heatmap, highcharter needs a data frame or a matrix. A matrix is a data object similar to a data frame as it is 2D. However, a matrix must have ALL its elements of the same class. This is different from a data frame where every column must have elements of the same class but two columns may have different classes.

The most common heatmap is a correlation plot. cor() function from base R outputs a matrix of correlations. Here we visualize correlations between multiple variables in the data set.

cor_dt = d1 |>
  select(saleq, oibdpq, cogsq, atq, xrdq, mkvaltq, cheq, capxy) |> 
  drop_na() |> 
  cor()
class(cor_dt)
[1] "matrix" "array" 
 cor_dt |> 
  hchart() |> 
    hc_colorAxis(
    stops = color_stops(colors = rev(c("#000004FF", 
                                   "#56106EFF", 
                                   "#BB3754FF", 
                                   "#F98C0AFF", 
                                   "#FCFFA4FF")))
    )

Why are all the correlations positive? For example, why is the correlation between profits (oibdpg) and the costs (cogsg) positive? Shouldn’t that be negative?

d1 |>
  select(saleq, oibdpq, cogsq, atq, xrdq, mkvaltq, cheq, capxy) |> 
  drop_na() |> 
  mutate(across(everything(), ~.x/saleq)) |> 
  select(-saleq) |> 
  cor() |>
  hchart()

Pie chart

Let’s create a pie chart for all the profits in the fiscal year 2021. This will be an ugly pie chart because there are 10 companies in the data. But interactive pie charts make life a little bit easier!

d1 |> 
  filter(fyearq == 2023) |>
  group_by(conm) |> 
  summarize(oiadpq = sum(oiadpq, na.rm = TRUE), .groups = "drop") |> 
  arrange(oiadpq) |> 
  mutate(conm = str_to_title(conm)) |> # Convert company names to title case
  hchart("pie", hcaes(x = conm, y = oiadpq))

Change the tooltip to show the series name using name argument in hchart()

d1 |> 
  filter(fyearq == 2023) |>
  group_by(conm) |> 
  summarize(oiadpq = sum(oiadpq, na.rm = TRUE), .groups = "drop") |> 
  arrange(oiadpq) |> 
  mutate(conm = str_to_title(conm)) |> # Convert company names to title case
  hchart("pie", hcaes(x = conm, y = oiadpq), name = "Operating Profit")

Wordcloud

Highcharter has a module that allows us to create wordclouds with minimal effort.

To create the wordcloud, we need words and their frequencies from text. For this example, I will use a few random tweets collected in November 2021.

tweets = readRDS(here::here("data", "file001.rds"))

We will use tidytext package for getting the words from the tweets.

tweet_text = tibble(text = tweets$text) |> 
  mutate(text = gsub(x = text, pattern = "[0-9]+|[[:punct:]]|\\(.*\\)", replacement = "")) |> 
  tidytext::unnest_tokens(word, text)

Next, let’s delete common words that don’t add much to the analysis. These are words such as “the”, “and”, etc. and called stopwords.

data(stop_words)

tweet_text = tweet_text |> anti_join(stop_words)
Joining with `by = join_by(word)`
tweet_text |> 
  count(word, sort = TRUE)
# A tibble: 40,543 × 2
   word       n
   <chr>  <int>
 1 im      1177
 2 dont     802
 3 time     539
 4 people   536
 5 love     524
 6 amp      444
 7 game     392
 8 lol      370
 9 day      308
10 play     276
# ℹ 40,533 more rows

We can remove other commonly occurring useless words as follows:

tweet_text = tweet_text |> 
  filter(!word %in% c("im", "dont", "amp", "youre", "ive", "hes", "didnt", "isnt"))

Now we are ready for the wordcloud

word_freq = tweet_text |> 
  count(word, sort = T)
word_freq |> 
  filter(n > 100) |> 
  hchart("wordcloud", hcaes(name = word, weight = n), name = "Count")

Aside: Wordcloud using wordcloud2 package. Note this is not part of highcharter

word_freq |> 
  filter(n > 100) |> 
  wordcloud2(color = "random-light", backgroundColor = "black",
             minRotation = 0, maxRotation = 0)

Visualizing stock market data

We will compare the stock price movement of Apple and Microsoft

aapl = getSymbols("AAPL", auto.assign = FALSE)
msft = getSymbols("MSFT", auto.assign = FALSE)
highchart(type = "stock") |> 
  hc_add_series(aapl) |> 
  hc_add_series(msft)