Добавление предельных итогов к карте тепла ggplot в R - PullRequest
0 голосов
/ 22 апреля 2019

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

Проблема с вышеуказанным постом заключается в том, что я не понимаю код, в котором создаются итоги (строка, столбец).Хотя он помечен как «# create итоговая строка и столбец», я не понимаю.

Так что было бы здорово, если бы ... 1. ... кто-нибудь мог бы помочь мне и показать мне (простой) способ добраться туда со ссылкой на мой опубликованный код (ниже), а также 2. ... если итоги строк и столбцов могут иметь разные цветовые шкалы.

Я пробовал это ...

# create sample
scen <- 1:32
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]

# create heatmap
library(ggplot2)
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
  geom_tile(aes(fill = SoP)) +
  geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
  scale_fill_gradient2(low = "gold", #colors
                       mid = "white",
                       high = "grey",
                       midpoint = 0) +
  theme(panel.grid.major.x=element_blank(), #no gridlines
        panel.grid.minor.x=element_blank(), 
        panel.grid.major.y=element_blank(), 
        panel.grid.minor.y=element_blank(),
        panel.background=element_rect(fill="white"),
        axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
        axis.text.y = element_text(size = 8,face = NULL),
        plot.title = element_text(size=10,face="bold")) +
  ggtitle("Treatment efficiency") + 
  theme(legend.title=element_text(face="bold", size=8)) + 
  scale_x_discrete(name="Landscape", position = "top") +
  scale_y_discrete(name="Scenario") +
  labs(fill="SoP")
print(df.diff)

Большое спасибо за вашу помощь!

1 Ответ

3 голосов
/ 24 апреля 2019

Давайте посмотрим, смогу ли я объяснить ответ в посте, на который вы ссылались, т. Е. ggplot2: Независимая непрерывная заливка для итоговой строки и столбца

Сначала пара замечаний:

  • На оси y вы строите вектор чисел, который считается непрерывной шкалой, поэтому метки осей исчезают при запуске scale_y_discrete, пока график работает нормально, как только мыпринять решение о добавлении нового значения к оси (т. е. Total), это вызовет проблемы, поэтому я считаю, что Scenario должен быть символьным вектором.
  • Превращение столбца Scenario в строку с использованиемas.character испортит сортировку значений, попробуйте, например, запустить sort(as.character(1:20)), этого можно избежать, используя 2-значные числа (01, 02, 03, .....), и это то, что я сделал там
  • В вышеупомянутом ответе итоги были связаны с исходным df, однако я буду использовать их в качестве внешних данных, чтобы их было легче понять (или, по крайней мере, я думаю, что так проще)

Так вотмы идем:

library(ggplot2)
library(dplyr)

# pad numbers with zeros to get 2 digit numbers, this will be a string
scen <- sprintf('%02d', 1:32)
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]

# create the main plot, and take a look at it
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
  geom_tile(aes(fill = SoP)) +
  geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
  scale_fill_gradient2(low = "gold", #colors
                       mid = "white",
                       high = "grey",
                       midpoint = 0) 

df.diff

Теперь нам нужны данные, которые позволят нам добавить дополнительную категорию к Landscape_Name и дополнительную категорию к Scenario, например:

  • Категория, добавленная к Landscape_Name (горизонтальные суммы), является суммой всех SoP для каждого Scenario, а
  • Категория, добавленная к Scenario (вертикальные суммы), является суммой всехSoP для каждого Landscape_Name

В основном нам нужны group_by и sum

h_total <- df %>% 
  group_by(Scenario) %>% 
  summarise(SoP = sum(SoP)) %>% 
  mutate(Landscape_Name = 'Total')


v_total <- df %>% 
  group_by(Landscape_Name) %>% 
  summarise(SoP = sum(SoP)) %>% 
  mutate(Scenario = 'Total')

Теперь мы можем добавить сгруппированные данные к исходному графику с помощью geom_point, поскольку мы использовали те же имена столбцов в новых данных, эстетика x и y будет унаследована от исходного графика, и для того, чтобы иметь другую цветовую схему в качестве исходного графика, мы используем color (неfill), которая отлично работает с выбранной формой.

Если вы хотите, чтобы значения ячеек также использовались для итогов, вам нужно добавить слои для них тоже

p <- df.diff + 
  geom_point(data = h_total, 
             aes(color = SoP), 
             size = 10, 
             shape = 19) +
  geom_point(data = v_total, 
             aes(color = SoP), 
             size = 10, 
             shape = 19) +
  scale_color_gradient2(low = "red", #colors
                        mid = "white",
                        high = "grey",
                        midpoint = 0) +
  geom_text(data = h_total, size = 3, aes(label = round(SoP,2))) +
  geom_text(data = v_total, size = 3, aes(label = round(SoP,2)))

p

Наконец добавьтенастройки темы, заголовок, метки оси и легенды

p  +
  theme(panel.grid.major.x=element_blank(), #no gridlines
        panel.grid.minor.x=element_blank(), 
        panel.grid.major.y=element_blank(), 
        panel.grid.minor.y=element_blank(),
        panel.background=element_rect(fill="white"),
        axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
        axis.text.y = element_text(size = 8,face = NULL),
        plot.title = element_text(size=10,face="bold"),
        legend.title=element_text(face="bold", size=8))  + 
  scale_x_discrete(name="Landscape", position = "top") +
  scale_y_discrete(name="Scenario", 
                  # if you want the total to be at the bottom instead of at the top, 
                  # you can set the limits of y  with the reversed order of the categories 
                  limits = rev(c(unique(as.character(df$Scenario)), 'Total'))) + 
  # you can here change the y/x ratio 
  coord_fixed(ratio = 0.4) +
  labs(fill="SoP", color ="SoP Total") +
  ggtitle("Treatment efficiency")

Я наконец сохранил сюжет сggsave(' PATH/TO/plot.jpeg', width =20, height = 40, units = 'cm')

и это был вывод

enter image description here

...