Использование geom_tile для карты тепла - PullRequest
0 голосов
/ 06 сентября 2018

Я работал над проблемой в течение двух полных дней и, похоже, не могу решить ее правильно. Я хочу создать график, который показывает использование классной комнаты в моем колледже для каждого часа дня и каждого дня недели, чтобы нашим преподавателям было легко увидеть, какие классы используются недостаточно.

Данные, с которыми мне приходится работать, выглядят примерно так:

room strTime endTime days pctFill
1101 1345    1500    MW   91.67
1102 1345    1630    MW   95.83
1102 1730    2015    MW   66.67
1104 0915    1200    MW   62.50
1104 1345    1630    MW   45.83

Каждая строка в df представляет отдельный класс, который встречается в одной комнате. «комната» - это номер комнаты. «strTime» и «endTime» - начальное и конечное время для класса в этой комнате. Это текстовые поля, но их можно легко преобразовать во времена или в любой другой формат. «дни» - это дни недели, в которые встречается класс. Я знаю, что мне придется разделить данные «дней» и считаю, что проще всего создать новую строку для каждого дня, поэтому первая строка будет разделена на две строки: одну для понедельника и одну для среды. «pctFill» - это процент заполнения для этой комнаты (комната вместимостью 20 студентов, но содержит 15 студентов, будет 75.00 pctFill).

Я бы хотел создать график типа Heatmap, используя geom_tile (или geom_raster или geom_rect). Я предполагаю, что график будет иметь дни недели вдоль оси x и время дня вдоль оси y, где каждый пересекающийся блок будет заполнен цветом, который представляет процент заполнения классной комнаты. Я закончил несколько уроков и понял концепцию geom_tile и могу создать чертовски сюжет для mtcars. К сожалению, данные, которые я использую, по-видимому, не работают так же, поскольку это время, а не простая категориальная переменная, я думаю. Я пытался создать сюжет, используя все три геометрии, но без особого успеха. Я могу заставить geom_tile почти работать, но каждая плитка центрируется по времени начала, а не по нижнему краю окна во время начала. Кроме того, все поля имеют одинаковую высоту, что, вероятно, связано с масштабом оси Y. Я попытался использовать geom_raster и создать сетку с осью Y, разделенной на 15-минутные интервалы, а затем залить каждый блок сетки соответствующим цветом. К сожалению, что бы я не делал с этим сюжетом, я получал только пустую сетку. Geom_rect сработал бы, но я не мог найти способ сделать прямоугольники широкими, не создав псевдопеременную со значением между каждым из значений комнаты.

Вот мой самый близкий подход к тому, что работает:

ggplot() +
  geom_tile(
    data = df
    ,mapping = aes(x = room
                   ,y = strTime
                   ,fill = pctFill
                   )
    ,color = 'white'
    ,alpha = 0.5
    ) +
  scale_fill_gradient(low = 'white', high = 'steelblue')

Если у кого-то есть пример графика, похожего на то, что я делаю, и он не против поделиться кодом для этого графика, я буду очень признателен. Или просто указатель в правильном направлении может быть достаточно. Спасибо за любую помощь, которую вы можете предложить.

Best geom_tile effort

1 Ответ

0 голосов
/ 06 сентября 2018

Как насчет этого?

Во-первых, ваши данные образца:

library(tidyverse)
txt <- 'room strTime endTime days pctFill
1101 1345    1500    MW   91.67
1102 1345    1630    MW   95.83
1102 1730    2015    MW   66.67
1104 0915    1200    MW   62.50
1104 1345    1630    MW   45.83'

df <- read.table(text = txt, header = T)

Затем мы преобразуем данные таким образом, чтобы каждый день недели находился в отдельной строке:

df <- read.table(text = txt, header = T) %>% 
  mutate(days = str_split(days, '')) %>% 
  unnest(days)

   room strTime endTime pctFill days
1  1101    1345    1500   91.67    M
2  1101    1345    1500   91.67    W
3  1102    1345    1630   95.83    M
4  1102    1345    1630   95.83    W
5  1102    1730    2015   66.67    M
6  1102    1730    2015   66.67    W
7  1104     915    1200   62.50    M
8  1104     915    1200   62.50    W
9  1104    1345    1630   45.83    M
10 1104    1345    1630   45.83    W

И, наконец, сюжет с использованием geom_rect():

plot.rooms <- ggplot(data = df, aes(xmin = room - 0.33, xmax = room + 0.33,  ymin = strTime, ymax = endTime)) +
  geom_rect(aes(alpha = pctFill)) +
  facet_grid(facets = ~days) +
  scale_x_continuous(breaks = sort(unique(df$room))) +
  scale_alpha_continuous(range = c(0.3, 1))
print(plot.rooms)

enter image description here

...