Как создать тепловую карту с ggplot2?
Я пытаюсь создать тепловую карту, используя ggplot2. Я нашел этот пример, который я по существу пытаюсь воспроизвести с помощью моих данных, но у меня возникают трудности. Мои данные - это простой CSV файл, который выглядит так:
people,apple,orange,peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0
Я хотел бы создать простую карту тепла, где имя плода находится на оси х, а человек находится на оси у. Граф должен изображать квадраты, где цвет каждого квадрата представляет собой количество потребляемых фруктов. Квадрат, соответствующий mike:peach
, должен быть самым темным.
Вот код, который я использую, чтобы попытаться создать тепловую карту:
data <- read.csv("/Users/bunsen/Desktop/fruit.txt", head=TRUE, sep=",")
fruit <- c(apple,orange,peach)
people <- data[,1]
(p <- ggplot(data, aes(fruit, people)) + geom_tile(aes(fill = rescale), colour = "white") + scale_fill_gradient(low = "white", high = "steelblue"))
Когда я рисую эти данные, я получаю количество фруктов на оси x и людей по оси y. Я также не получаю цветовые градиенты, представляющие количество фруктов. Как я могу получить имена фруктов на оси х с количеством фруктов, съеденных человеком, отображаемым в виде карты тепла?
Текущий вывод, который я получаю в R, выглядит следующим образом:
![enter image description here]()
Ответы
Ответ 1
Честно говоря, dr.bunsen - ваш пример выше был плохо воспроизводимым, и вы не прочитали первую часть учебника, в которой вы связаны. Вот, вероятно, вы ищете:
library(reshape)
library(ggplot2)
library(scales)
data <- structure(list(people = structure(c(2L, 3L, 1L, 4L),
.Label = c("bill", "mike", "sue", "ted"),
class = "factor"),
apple = c(1L, 0L, 3L, 1L),
orange = c(0L, 0L, 3L, 1L),
peach = c(6L, 1L, 1L, 0L)),
.Names = c("people", "apple", "orange", "peach"),
class = "data.frame",
row.names = c(NA, -4L))
data.m <- melt(data)
data.m <- ddply(data.m, .(variable), transform, rescale = rescale(value))
p <- ggplot(data.m, aes(variable, people)) +
geom_tile(aes(fill = rescale), colour = "white")
p + scale_fill_gradient(low = "white", high = "steelblue")
![enter image description here]()
Ответ 2
Семь (!) Лет спустя, лучший способ правильно форматировать ваши данные - использовать tidyr
а не reshape
Использование gather
из tidyr
, очень легко переформатировать свои данные, чтобы получить ожидаемые 3 колонки (person
для оси у, fruit
для оси х и count
для значений):
library("dplyr")
library("tidyr")
hm <- readr::read_csv("people,apple,orange,peach
mike,1,0,6
sue,0,0,1
bill,3,3,1
ted,1,1,0")
hm <- hm %>%
gather(fruit, count, apple:peach)
#syntax: key column (to create), value column (to create), columns to gather (will become (key, value) pairs)
Теперь данные выглядят так:
# A tibble: 12 x 3
people fruit count
<chr> <chr> <dbl>
1 mike apple 1
2 sue apple 0
3 bill apple 3
4 ted apple 1
5 mike orange 0
6 sue orange 0
7 bill orange 3
8 ted orange 1
9 mike peach 6
10 sue peach 1
11 bill peach 1
12 ted peach 0
Отлично! Пусть получится заговор. Основной геометрией для создания тепловой geom_tile
с ggplot2 является geom_tile
к которой мы будем предоставлять эстетические x
, y
и fill
.
library("ggplot2")
ggplot(hm, aes(x=x, y=y, fill=value)) + geom_tile()
![first attempt]()
Хорошо, не так уж плохо, но мы можем сделать намного лучше.
- Для тепловых карт мне нравится черно-белая тема
theme_bw()
которая избавляется от серого фона. -
Мне также нравится использовать палитру из RColorBrewer
(с direction = 1
чтобы получить более темные цвета для более высоких значений, или -1 в противном случае). Существует много доступных палитр: красные, синие, спектральные, RdYlBu (красно-желто-синие), RdBu (красно-синие) и т.д. Ниже я использую "Зеленые". Запустите RColorBrewer::display.brewer.all()
чтобы увидеть, как выглядят палитры.
-
Если вы хотите, чтобы плитки были в квадрате, просто используйте coord_equal()
.
-
Вы можете распечатать значения поверх плиток с помощью geom_text
(или geom_label
). Он принимает эстетику x
, y
и label
но в нашем случае x
и y
наследуются. Вы также можете печатать более высокие значения больше, пропуская size=count
как эстетический - в этом случае вам также нужно передать size=F
в guides
чтобы скрыть легенду размера.
-
Вы можете рисовать линии вокруг плиток, передавая color
geom_tile
.
Объединяя все это:
ggplot(hm, aes(x=fruit, y=people, fill=count)) +
# tile with black contour
geom_tile(color="black") +
# B&W theme, no grey background
theme_bw() +
# square tiles
coord_equal() +
# Green color theme for 'fill'
scale_fill_distiller(palette="Greens", direction=1) +
# printing values in black
geom_text(aes(label=count), color="black") +
# removing legend for 'fill' since we're already printing values
guides(fill=F) +
# since there is no legend, adding a title
labs(title = "Count of fruits per person")
![Final heatmap]()
Чтобы удалить что-либо, просто удалите соответствующую строку.