This week at work I started using
rbokeh, the R interface to Bokeh. The package allows to create web-based interactive plots. I was mostly excited about the zooming tools that a local R-Lady mentioned to me. They made data exploration so much easier, thanks a bunch Elena!
When checking out the doc, I saw an example called “Periodic table of the elements with additional info on hover”. While this was useless at work where I only made time series plots, I could set aside this application for my leisure time. I made an interactive CV for my husband, Damien, who is a chemist!
You’ll find the original periodic table example in
rbokeh's preview. My code is very similar to the one there!
One gets the elements data from the package itself.
library("rbokeh") library("dplyr") data(elements) knitr::kable(head(elements))
|1||2||He||Helium||4.002602||#D9FFFF||1s2||NA||32||140||2372||0||gas||atomic||NA||4||0.00e+00||noble gas||1868||18||1||#bbbb88||noble gas||18:0.1||1:0.8||1:0.15||1:0.3|
|2||3||Li||Lithium||6.941||#CC80FF||[He] 2s1||0.98||134||76 (+1)||182||520||-60||solid||metallic||454||1615||5.40e-01||alkali metal||1817||1||2||#a6cee3||alkali metal||1:0.1||2:0.8||2:0.15||2:0.3|
|3||4||Be||Beryllium||9.012182||#C2FF00||[He] 2s2||1.57||90||45 (+2)||NA||900||0||solid||metallic||1560||2743||1.85e+00||alkaline earth metal||1798||2||2||#1f78b4||alkaline earth metal||2:0.1||2:0.8||2:0.15||2:0.3|
|4||5||B||Boron||10.811||#FFB5B5||[He] 2s2 2p1||2.04||82||27 (+3)||NA||801||-27||solid||covalent network||2348||4273||2.46e+00||metalloid||1807||13||2||#33a02c||metalloid||13:0.1||2:0.8||2:0.15||2:0.3|
|5||6||C||Carbon||12.0107||#909090||[He] 2s2 2p2||2.55||77||16 (+4)||170||1087||-154||solid||covalent network||3823||4300||2.26e+00||nonmetal||Ancient||14||2||#baa2a6||nonmetal||14:0.1||2:0.8||2:0.15||2:0.3|
It looks fine but some elements recently got new names. I wouldn’t know about it from my own readings, but well my husband did, and he can recommend a radio show in French about it because one of his favourite tweeps is the interviewee. He obviously thinks I can drive traffic to any website I want with this blog. I couldn’t find how to update the table of the package so opened an issue at
rbokeh and will selfishly solve the issue for myself here.
The ones that got new names compared to the table of the package are 113, 114, 115, 116, 117, and 118. Actually 118 wasn’t even in the
rbokeh table so we’ll add it. I’m adding the atomic masses too but I was told that an atomic mass superior to 82 doesn’t have much interest anyway because of the unstability of the elements.
elements <- filter(elements, !atomic.number %in% c(113, 114, 115, 116, 117)) renamed_elements <- data.frame(atomic.number = c(113, 114, 115, 116, 117, 118), symbol = c("Nh", "Fl", "Mc", "Lv", "Ts", "Og"), name = c("Nihonium", "Flerovium", "Moscovium", "Livermorium", "Tennessine", "Oganesson"), atomic.mass = c("", "", "", "", "", ""), group = c("13", "14", "15", "16", "17", "18"), period = rep("7", 6)) elements <- bind_rows(elements, renamed_elements) knitr::kable(tail(elements))
Okay now the table looks like a 2017 table of elements.
I didn’t want to have additional information about the elements but rather pieces of experience of my husband who was actually thrilled to fill a table with stuff he’s done with elements. Here is what he sent me.
damien <- readr::read_csv2("data/2017-02-03-chemist_Elements.csv")
## Parsed with column specification: ## cols( ## Element = col_character(), ## `Why did I use it?` = col_character(), ## Place = col_character() ## )
|Element||Why did I use it?||Place|
|H||I am currently working on the hydrogenation of alkenes. And, well, H is everywhere!||Hangzhou, Paris, Berlin, Tarragona|
|He||It is not possible to cool large superconducting coils without liquid He.||Berlin|
|Li||Butyl lithium is a very powerful base!||Hangzhou|
|C||I am currently working on the vibrations between carbon monoxide and metallic surfaces. And, well, C is everywhere!||Hangzhou, Paris, Berlin, Tarragona|
|N||Infrared spectrometer works much better in liquid nitrogen||Paris, Berlin, Tarragona|
|O||I am currently working on the vibrations between carbon monoxide and metallic surfaces. And, well, O is everywhere!||Hangzhou, Paris, Berlin, Tarragona|
I think it’s funny to print Damien’s head. I was less amused by the second column name because of the spaces, so I renamed it before joining it to the original elements table. I also replaced the missing values of the elements table, corresponding to elements my husband had nothing to say about, with empty strings.
names(damien) <- "desc" elements <- left_join(elements, damien, by = c("symbol" = "Element")) elements <- mutate(elements, Place = ifelse(is.na(Place), "", Place)) elements <- mutate(elements, desc = ifelse(is.na(desc), "", desc))
Drawing the table
Preparing the colours and coordinates
Nothing new here, I’m pretty much doing the same as in the doc,
places <- unique(elements$Place) colors <- c("#a6cee3", "#1f78b4", "#fdbf6f", "white", "#b2df8a", "#33a02c", "#bbbb88", "#baa2a6", "#e08e79") colors <- data.frame(Place = places, color = colors) elements <- select(elements, - color) elements <- left_join(elements, colors, by = "Place")
This is the part where the tutorial indicates how to create coordinates for putting every text in its place.
elements <- mutate(elements, symx = paste0(group, ":0.1")) elements <- mutate(elements, numbery = paste(period, ":0.8", sep = "")) elements <- mutate(elements, massy = paste(period, ":0.15", sep = "")) elements <- mutate(elements, namey = paste(period, ":0.3", sep = ""))
I haven’t got a ton of experience with
rbokeh, the main syntax differences I noted compared to
ggplot2 was the piping and the fact that you need to specify data for each layer. You’ll find a better comparison on Bob Rudis’ blog.
But in the case of the period table I only really needed to copy paste code, thanks a lot to Ryan Hafen for his awesome package and for the cool example. The part of the code I changed is
hover = list(name, desc, place) which is the part where I choose to show the experience my husband associates with each element. In the original example the hover tool showed more info about elements. Note that Damien doesn’t even associates something really interesting with gold like, you know, a wedding ring. Bummer.
# See you create a table like this and add a serious title p <- figure(title = "Periodic Table of Damien Cornu's experience", tools = c("resize", "hover"), ylim = as.character(c(7:1)), xlim = as.character(1:18), xgrid = FALSE, ygrid = FALSE, xlab = "", ylab = "", height = 445, width = 800) %>% # Here the rectangles are created, # without experience rectangles get a while fill ly_crect(group, period, data = elements, 0.9, 0.9, fill_color = color, line_color = "grey", fill_alpha = 0.6, hover = list(name, desc, Place)) %>% # add symbol text ly_text(symx, period, text = symbol, data = elements, font_style = "bold", font_size = "10pt", align = "left", baseline = "middle") %>% # add atomic number text ly_text(symx, numbery, text = atomic.number, data = elements, font_size = "6pt", align = "left", baseline = "middle") %>% # add name text ly_text(symx, namey, text = name, data = elements, font_size = "4pt", align = "left", baseline = "middle") %>% # add atomic mass text ly_text(symx, massy, text = atomic.mass, data = elements, font_size = "4pt", align = "left", baseline = "middle")
Displaying the CV
Maybe the way I display the
rbokeh plot on this page is a dirty hack. Using the
htmlwidget package I saved the widget,
htmlwidgets::saveWidget(p, file = "damien.html")
And then I simply included the html file thus created. If you knit a html, not a html via a .md as is the case with a Jekyll website, you don’t need these two steps to display a widget. At work I made a flexdashboard with
rbokeh and it couldn’t have been easier.