Bubblecloud Plots in ggplot2
How to make a Bubblecloud Plots using ggplotly with Plotly.
New to Plotly?
Plotly is a free and open-source graphing library for R. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.
Basic Text Graph
Sources: International IDEA for national turnout and European Parliament for European turnout, while regional classifications are based on EuroVoc.
recent_turnout <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/european_turnout.csv",stringsAsFactors = FALSE)
recent_turnout$region <- factor(recent_turnout$region, levels=c("British","Northern","Western","Mediterranean","Central/Eastern"))
library(plotly)
p <- recent_turnout %>%
ggplot(aes(x=nat_turnout,y=euro_turnout)) +
geom_text(aes(size=population/3.5, label=abbreviation, colour=region), alpha=1) +
labs(title = "Recent turnout in European Union countries",
x = "Latest legislative or presidential election (whichever had higher turnout)",
y = "May 2019 European Parliament election")
fig <- ggplotly(p)
fig
Overlaid Points
Colour-coding the text itself might present readability issues. Another possible use of geom_text is to keep the text grey, but overlay it on a coloured point graph.
Adding the text option within aes() allows us to control the text that appears when hovering over a point.
recent_turnout <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/european_turnout.csv",stringsAsFactors = FALSE)
recent_turnout$region <- factor(recent_turnout$region, levels=c("British","Northern","Western","Mediterranean","Central/Eastern"))
library(plotly)
p <- recent_turnout %>%
ggplot(aes(x=nat_turnout,y=euro_turnout)) +
geom_point(aes(size=population, colour=region, text=paste("country:", country)), alpha=0.4) +
geom_text(aes(size=population/3.5, label=abbreviation), colour="gray20", alpha=1) +
labs(title = "Recent turnout in European Union countries",
x = "Latest legislative or presidential election (whichever had higher turnout)",
y = "May 2019 European Parliament election")
fig <- ggplotly(p)
fig
Customed Colour and Size Scale
Let's use the LaCroixColoR package to spruce up the colour scheme. In addition, by using scale_size_continuous, we can make sure that none of the text is too small.
recent_turnout <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/european_turnout.csv",stringsAsFactors = FALSE)
recent_turnout$region <- factor(recent_turnout$region, levels=c("British","Northern","Western","Mediterranean","Central/Eastern"))
library(plotly)
library(LaCroixColoR)
p <- recent_turnout %>%
ggplot(aes(x=nat_turnout,y=euro_turnout)) +
geom_point(aes(size=population, colour=region, text=paste("country:", country)), alpha=0.4) +
geom_text(aes(size=population/3.5, label=abbreviation), colour="gray20", alpha=1) +
scale_colour_manual(values=lacroix_palette(n=6, name="PeachPear")) +
scale_size_continuous(range = c(3, 8)) +
labs(title = "Recent turnout in European Union countries",
x = "Latest legislative or presidential election (whichever had higher turnout)",
y = "May 2019 European Parliament election")
fig <- ggplotly(p)
fig
Adding a regression
Adding a regression line as well as a label. geom_smooth does not allow for adjusting the transparency of the line (using alpha), which is why stat_smooth is used here. annotate is used to include a single text label (geom_text would create one label for every data point, all overlapped with each other).
recent_turnout <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/european_turnout.csv",stringsAsFactors = FALSE)
recent_turnout$region <- factor(recent_turnout$region, levels=c("British","Northern","Western","Mediterranean","Central/Eastern"))
m <- lm(euro_turnout ~ nat_turnout, data = recent_turnout)
library(plotly)
library(LaCroixColoR)
p <- recent_turnout %>%
ggplot(aes(x=nat_turnout,y=euro_turnout)) +
stat_smooth(geom="line", method="lm", alpha=0.3, se=FALSE) +
geom_point(aes(size=population, colour=region, text=paste("country:", country)), alpha=0.4) +
geom_text(aes(size=population/3.5, label=abbreviation), colour="gray20", alpha=1) +
scale_colour_manual(values=lacroix_palette(n=6, name="PeachPear")) +
scale_size_continuous(range = c(3, 8)) +
labs(title = "Recent turnout in European Union countries",
x = "Latest legislative or presidential election (whichever had higher turnout)",
y = "May 2019 European Parliament election") +
annotate(geom="text", x=60, y=80, label = paste("European turnout = \n",
round(unname(coef(m)[2]),2),
"x national turnout",
round(unname(coef(m)[1]),1)))
fig <- ggplotly(p)
fig
Customized Formatting
Changed the font of the geom_text and of the graph (these must be done separately!), corrected the size label, centre-aligned the title.
recent_turnout <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/european_turnout.csv",stringsAsFactors = FALSE)
recent_turnout$region <- factor(recent_turnout$region, levels=c("British","Northern","Western","Mediterranean","Central/Eastern"))
m <- lm(euro_turnout ~ nat_turnout, data = recent_turnout)
library(plotly)
library(LaCroixColoR)
p <- recent_turnout %>%
ggplot(aes(x=nat_turnout,y=euro_turnout)) +
stat_smooth(geom="line", method="lm", alpha=0.3, se=FALSE) +
geom_point(aes(size=population, colour=region, text=paste("country:", country)), alpha=0.4) +
geom_text(aes(size=population/3.5, label=abbreviation), colour="gray20", alpha=1, family="Fira Sans") +
scale_colour_manual(values=lacroix_palette(n=6, name="PeachPear")) +
scale_size_continuous(range = c(3, 8)) +
labs(title = "Recent turnout in European Union countries",
x = "Latest legislative or presidential election (whichever had higher turnout)",
y = "May 2019 European Parliament election",
size = "") +
annotate(geom="text", x=60, y=80, label = paste("European turnout = \n",
round(unname(coef(m)[2]),2),
"x national turnout",
round(unname(coef(m)[1]),1))) +
theme(plot.title = element_text(hjust = 0.5)) +
guides(size=guide_legend(""), fill = FALSE) +
theme(text = element_text(family = 'Fira Sans'))
fig <- ggplotly(p)
fig
What About Dash?
Dash for R is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.
Learn about how to install Dash for R at https://dashr.plot.ly/installation.
Everywhere in this page that you see fig
, you can display the same figure in a Dash for R application by passing it to the figure
argument of the Graph
component from the built-in dashCoreComponents
package like this:
library(plotly)
fig <- plot_ly()
# fig <- fig %>% add_trace( ... )
# fig <- fig %>% layout( ... )
library(dash)
library(dashCoreComponents)
library(dashHtmlComponents)
app <- Dash$new()
app$layout(
htmlDiv(
list(
dccGraph(figure=fig)
)
)
)
app$run_server(debug=TRUE, dev_tools_hot_reload=FALSE)