Heatmaps in ggplot2
How to make Heatmaps plots in ggplot2 with Plotly.
Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Sign up for early access now.
Basic 2d Heatmap
See also geom_hex for a similar geom with hexagonal bins. Note: facetting is supported in geom_bin2d but not geom_hex.
Source: Department of Canadian Heritage
library(plotly)
english_french <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/english_french.csv",stringsAsFactors = FALSE)
p <- ggplot(english_french, aes(x=engperc,y=frenperc)) +
geom_bin2d() +
labs(title = "Distribution of Canadian areas by English and French fluency",
x = "% fluent in English",
y = "% fluent in French",
fill = "# of census \nsubdivisions")
ggplotly(p)
geom_raster
creates a coloured heatmap, with two variables acting as the x- and y-coordinates and a third variable mapping onto a colour. (It is coded similarly to geom_tile and is generated more quickly.) This uses the volcano dataset that comes pre-loaded with R.
library(reshape2)
library(plotly)
df <- melt(volcano)
p <- ggplot(df, aes(Var1, Var2)) +
geom_raster(aes(fill=value)) +
labs(x="West to East",
y="North to South",
title = "Elevation map of Maunga Whau")
ggplotly(p)
Customized Colours
This uses the Spectral palette from ColorBrewer; a full list of palettes is here.
library(reshape2)
library(plotly)
df <- melt(volcano)
p <- ggplot(df, aes(Var1, Var2)) +
geom_raster(aes(fill=value)) +
scale_fill_distiller(palette = "Spectral", direction = -1) +
labs(x="West to East",
y="North to South",
title = "Elevation map of Maunga Whau",
fill = "Elevation") +
theme(text = element_text(family = 'Fira Sans'),
plot.title = element_text(hjust = 0.5))
ggplotly(p)
Let's flip the colour scheme so that lighter colours denote larger numbers than darker colours. We should also move to a logarithmic scale, since as it is, the very large value in the bottom right overshadows all other values.
library(plotly)
p <- ggplot(english_french, aes(x=engperc,y=frenperc)) +
geom_bin2d() +
scale_fill_gradient(low="lightblue1",high="darkblue",trans="log10") +
labs(title = "Distribution of Canadian towns by English and French fluency",
x = "% fluent in English",
y = "% fluent in French",
fill = "# of census \nsubdivisions")
ggplotly(p)
Weighted Data
In the previous graphs, each observation represented a single census subdivision - this counted small towns of 500 people equally with cities like Montreal and Toronto. We can weight the data by the "total" column (i.e. total population) to make this a graph of population.
library(plotly)
p <- ggplot(english_french, aes(x=engperc, y=frenperc, weight=total)) +
geom_bin2d() +
scale_fill_gradient(low="lightblue1",high="darkblue",trans="log10") +
labs(title = "Distribution of the Canadian population by English and French fluency",
x = "% fluent in English",
y = "% fluent in French",
fill = "population")
fig <- ggplotly(p)
fig
With Facets
We can facet the graphic with the "region" column, and set "bins" to 20, so that the graph is 20 x 20 sides.
library(plotly)
p <- ggplot(english_french, aes(x=engperc,y=frenperc, weight=total)) +
geom_bin2d(bins = 20) +
facet_wrap(~factor(region, levels = c("Atlantic","Québec","Ontario","Prairies","British Columbia"))) +
scale_fill_gradient(low="lightblue1",high="darkblue",trans="log10") +
labs(title = "Distribution of Canadian towns by English and French fluency",
x = "% fluent in English",
y = "% fluent in French",
fill = "population")
fig <- ggplotly(p)
fig
Customized Appearance
We can modify the graph's appearance - for example, if the grey background makes it difficult to make out the paler shades of blue, we can change the theme to one with a white background. Included also is a way to change the font.
library(plotly)
p <- ggplot(english_french, aes(x=engperc,y=frenperc, weight=total)) +
geom_bin2d(bins = 20) +
facet_wrap(~factor(region, levels = c("Atlantic","Québec","Ontario","Prairies","British Columbia"))) +
scale_fill_gradient(low="lightblue1",high="darkblue",trans="log10") +
labs(title = "Distribution of Canadian towns by English and French fluency",
x = "% fluent in English",
y = "% fluent in French",
fill = "population") +
theme_bw() +
theme(text = element_text(family = 'Fira Sans'))
fig <- ggplotly(p)
fig
Basic geom_tile graph
This graph, compiled by Jeff Zimmerman, shows how often hitters swing and miss at fastballs, based on their velocity and spin rate. Colour schemes are from ColorBrewer; a complete list of palettes is available here.
library(plotly)
spinrates <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/spinrates.csv",
stringsAsFactors = FALSE)
p <- ggplot(spinrates, aes(x=velocity, y=spinrate)) +
geom_tile(aes(fill = swing_miss)) +
scale_fill_distiller(palette = "YlGnBu") +
labs(title = "Likelihood of swinging and missing on a fastball",
y = "spin rate (rpm)")
ggplotly(p)
Adjusting appearance
The direction option sets which side of the colour scheme maps onto the low values and which side maps onto the high; it defaults to -1 but could be adjusted to 1.
Also adjusted the theme.
library(plotly)
spinrates <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/spinrates.csv",
stringsAsFactors = FALSE)
p <- ggplot(spinrates, aes(x=velocity, y=spinrate)) +
geom_tile(aes(fill = swing_miss)) +
scale_fill_distiller(palette = "YlGnBu", direction = 1) +
theme_light() +
labs(title = "Likelihood of swinging and missing on a fastball",
y = "spin rate (rpm)")
ggplotly(p)
geom_tile with viridis colour scheme
Viridis colour schemes are uniform in both colour and black-and-white, as well as for those with colour-blindness. There are five colour schemes: "magma" (or "A"), "inferno" (or "B"), "plasma" (or "C"), "viridis" (or "D", the default option) and "cividis" (or "E").
library(plotly)
spinrates <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/spinrates.csv",
stringsAsFactors = FALSE)
p <- ggplot(spinrates, aes(x=velocity, y=spinrate)) +
geom_tile(aes(fill = swing_miss)) +
scale_fill_viridis_c(option = "B", direction = -1) +
labs(title = "Likelihood of swinging and missing on a fastball",
y = "spin rate (rpm)") +
theme_light()
ggplotly(p)
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)