|>
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())
Highcharter Examples
Bar chart
Create a bar chart of Meta (Facebook) profits by fiscal year
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”
= d1 |>
plot1 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:
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.
Changed the content of the tooltip and added more description replacing the default “Series 1” label
= plot1 |>
plot2 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.
= plot2 |>
plot3 #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.
= plot3 |>
plot4 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
= plot4 |>
plot5 hc_title(text = '<span style="font-family: helvetica, inter, sans-serif;"><strong><span style="color: #3598db;">Evil = Profitable??</span></strong></span> <span>🤑</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
= viridisLite::viridis(10, option = "H")
cols
= substr(cols, 0, 7) # This will retain first 7 characters including the # sign.
cols
|>
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
= pals::alphabet() |> unname()
cols # 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.
= d1 |>
cor_dt 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.
= readRDS(here::here("data", "file001.rds")) tweets
We will use tidytext package for getting the words from the tweets.
= tibble(text = tweets$text) |>
tweet_text mutate(text = gsub(x = text, pattern = "[0-9]+|[[:punct:]]|\\(.*\\)", replacement = "")) |>
::unnest_tokens(word, text) tidytext
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 |> anti_join(stop_words) tweet_text
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
= tweet_text |>
word_freq 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
= getSymbols("AAPL", auto.assign = FALSE)
aapl = getSymbols("MSFT", auto.assign = FALSE) msft
highchart(type = "stock") |>
hc_add_series(aapl) |>
hc_add_series(msft)