Как использовать условие в geom_text / nudge_y

#r #ggplot2

#r #ggplot2

Вопрос:

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

пример

Вот мой код:

 library(tidyr)
library(ggplot2)
library(dplyr)
library(stringr)
library(purrr)

numa.nodes <- tibble (
  numa_name = c("numa_01","numa_01","numa_01","numa_01","numa_01","numa_01","numa_02","numa_02","numa_02","numa_02"),
  counter_name =c("cpu01","cpu02","cpu03","cpu04","memory_used","memory_total","cpu01","cpu02","memory_used","memory_total"),
  value = c(sample(0:100,4), sample(0:32,1), 32, sample(0:100,1), sample(0:100,1), sample(0:128,1), 128)
)

 numa.nodes <- numa.nodes %>% add_row(
   numa_name = c("numa_03","numa_03","numa_03","numa_03","numa_03","numa_03","numa_04","numa_04","numa_04","numa_04"),
   counter_name =c("cpu01","cpu02","cpu03","cpu04","memory_used","memory_total","cpu01","cpu02","memory_used","memory_total"),
   value = c(sample(0:100,4), sample(0:32,1), 32, sample(0:100,1), sample(0:100,1), sample(0:128,1), 128)
 )

 
 numa.nodes <- numa.nodes %>% add_row(
   numa_name = c("numa_05","numa_05","numa_05","numa_05","numa_05","numa_05","numa_05"),
   counter_name =c("cpu01","cpu02","cpu03","cpu04","cpu05","memory_used","memory_total"),
   value = c(sample(1:100,5), sample(1:64,1), 64)
 )
 
 
numa.nodes <- numa.nodes %>% mutate(counter_name=factor(counter_name,levels = unique(counter_name),ordered = T))

memory_columns <-  numa.nodes %>% filter(counter_name=='memory_total')
memory_y_scale <- max(memory_columns$value, na.rm = TRUE)   6




plot_numa = function(num){
  
  df = numa.nodes %>% filter(str_detect(numa_name, num))
  
  cpu_plot = df %>%
    filter(str_detect(counter_name, "cpu")) %>%
    ggplot(aes(x = counter_name))  
    geom_col(aes(y = 100), fill = "white", color = "black")  
    geom_col(aes(y = value), fill = "#00AFBB", color = "black")  
    geom_text(aes(y = value, label = paste0(value,"%")), nudge_y = 5, color = "black")  
    theme_bw()  
    labs(x = "CPU", y = "")
  
  memory_plot = df %>%
    filter(str_detect(counter_name, "memory")) %>%
    pivot_wider(names_from = counter_name, values_from = value) %>%
    ggplot(aes(x = "") )  
    geom_col(aes(y = memory_total), fill = "white", color = "black")  
    geom_col(aes(y = memory_used), fill = "#FC4E07", color = "black")  
    geom_text(aes(label = paste(memory_total, "GB"), y = memory_total), nudge_y = 5, color = "black")  
    geom_text(aes(label = paste(memory_used, "GB"), y = memory_used), nudge_y = -3, color = "black")  
    theme_bw()  
    ylim(0, memory_y_scale)  
    labs(x = "Memory", y = "")
  
  ggpubr::ggarrange(cpu_plot, memory_plot, ncol = 2) %>% ggpubr::annotate_figure(top = paste("NUMA",num))
  
}

numa_numbers <- unique(numa.nodes$numa_name) %>% str_remove ("numa_")

ggpubr::ggarrange(plotlist = map(.x = numa_numbers, .f = ~plot_numa(num = .x)))

  

Я попытался изменить эту строку:

  geom_text(aes(label = paste(memory_used, "GB"), y = memory_used), nudge_y = -3, color = "black")
  

для чего-то подобного:

      geom_text(aes(label = paste(memory_used, "GB"), y = memory_used),nudge_y =  ifelse( (memory_total-memory_used) > 10, 5, -3)
                                                                                , color = "black")
  

Но у меня ошибка:

 Error in ifelse((memory_total - memory_used) > 10, 5, -3) : 
  object 'memory_total' not found
  
  1. Есть ли лучший способ оптимальной печати меток?
  2. Что я делаю не так?
  3. Как изменить цвет метки на более контрастный, т.Е. Черный на белом, белый на красном?

Ответ №1:

Подумайте об этом так: значение подталкивания будет отличаться (потенциально) для каждого наблюдения в вашем фрейме данных. Это означает, что это то, что должно обрабатываться внутри aes() , где материал предназначен для изменения ваших данных, а не nudge_y для того, чтобы быть константой (и жалуется, если используется иначе).

Итак, решение состоит в том, чтобы полностью отказаться от nudge_y вашего ifelse() утверждения и встроить его непосредственно в aes(y=...) него.

В этом случае вот замена для этой конкретной geom_text() строки:

 # to see the same plot posted here, put this at the top of your code
set.seed(7331)
...
# plot code...
...   

geom_text(aes(
      label = paste(memory_used, "GB"),
      y = ifelse((memory_total-memory_used > 10), memory_used   5, memory_used - 3)),
      color = "black")  
  

введите описание изображения здесь