如何在通过 ggarrange 创建的图表周围添加边框并在组合图表之间增加 space

How to add a border around a chart created via ggarrange and increase space between combined charts

我正在尝试绘制 Numa 节点 CPU 和内存使用情况。

我的示例中有 4 个 numa 节点,每个节点有 CPU 和内存使用图表。

问题是 - 在每个节点中可能有许多 CPU 值(每个核心 1 条,在我的示例中为 20 个核心)并且只有一个内存值,所以我不得不使用不同宽度的图表(CPU 图表比内存更宽)。由于该注释文本 (NUMA XX) 现在看起来不像是图表的中间。我真的不能说是哪个节点的内存条。

我想我需要使用边框或背景颜色将 numa 节点彼此分开,以便 CPU 和每个 Numa 节点的内存在一起。另外我认为我需要减少 CPU 和 numa 节点内的内存之间的 space 并增加 numa 节点之间的 space 。怎么做?

我的代码:

library(dplyr)

library(ggplot2)

library(ggpubr)

library(tidyr)

memory_df <- structure(list(NumaNode = c("00", "00", "01", "01", "02", "02", "03", "03"),
                         CounterName = c("TotalMemory", "UsedMemory", "TotalMemory", 
                                      "UsedMemory", "TotalMemory", "UsedMemory", "TotalMemory", "UsedMemory"),
                    Value = c(48, 45.55, 48, 46.38, 48, 46.54, 48, 47.39)),
                    row.names = c(NA, -8L),
                    class = c("tbl_df", "tbl", "data.frame"))

memory_y_scale <-  memory_df %>% filter(CounterName=='TotalMemory') %>% select (Value) %>% max() + 6

cpu_df <- structure(list(NumaNode = c("00", "00", "00", "00", "00", "00", 
                                      "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", 
                                      "00", "00", "00", "01", "01", "01", "01", "01", "01", "01", "01", 
                                      "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", 
                                      "01"), Counter = c("00", "01", "10", "11", "12", "13", "14", 
                                                         "15", "16", "17", "18", "19", "02", "03", "04", "05", "06", "07", 
                                                         "08", "09", "00", "01", "10", "11", "12", "13", "14", "15", "16", 
                                                         "17", "18", "19", "02", "03", "04", "05", "06", "07", "08", "09"
                                      ), Value = c(10.79, 5.85, 9.55, 9.71, 9.77, 4.73, 4.62, 10.92, 
                                                   3.55, 10.3, 1.38, 6.28, 5.42, 4.45, 10.09, 3.42, 10.14, 4.34, 
                                                   9.48, 4.17, 5.2, 3.85, 10.17, 8.49, 10.36, 8.06, 10.01, 8.42, 
                                                   9.12, 7.6, 1.98, 2.41, 4.72, 3.19, 4.74, 3.66, 4.28, 9.83, 5.78, 
                                                   10.18)), row.names = c(NA, -40L), class = c("tbl_df", "tbl", 
                                                                                               "data.frame"))



# plot function =======================================================================

plot_numa = function(num){
  
  # memory plot =====================
  
  memory_filtered_df = memory_df %>% filter(str_detect(NumaNode, num))
  
  memory_plot  <-  memory_filtered_df %>%
    filter(str_detect(CounterName, "Memory")) %>%
    pivot_wider(names_from = CounterName, values_from = Value) %>%
    ggplot(aes(x = "") ) +
    geom_col(aes(y = TotalMemory), fill = "white", color = "black") +
    geom_col(aes(y = UsedMemory), fill = "#00FF66FF", color = "black") +
    geom_text(aes(label = paste(TotalMemory, "GB"), y = TotalMemory + 5 ), color = "black") +
    geom_text(aes(
      label = paste(UsedMemory, "GB"),
      y = ifelse((TotalMemory-UsedMemory > 10), UsedMemory + 5, UsedMemory - 4)),
      color = "black") +
    theme_bw() +
    ylim(0, memory_y_scale) +
    labs(x = "Memory", y = "")
  
  # cpu plot =====================
  
  cpu_filtered_df <-  cpu_df %>% filter(str_detect(NumaNode, num))
  
  if (nrow (cpu_filtered_df) == 0 )    {
    cpu_filtered_df <- cpu_df %>% filter(str_detect(NumaNode, "00"))
  }
  
  cpu_plot <-  cpu_filtered_df %>%
    ggplot(aes(x = Counter)) +
    geom_col(aes(y = 100), fill = "white", color = "white", alpha = 0) +
    geom_col(aes(y = Value), fill = "#00AFBB", color = "black") +
    theme_bw() +
    labs(x = "CPU, % Processor Time", y = "") 
  
  
  ggpubr::ggarrange(cpu_plot, memory_plot, ncol = 2, widths = c(4,1)) %>% 
    ggpubr::annotate_figure(top = paste("        NUMA",num))
  
}

numa_numbers <- unique(memory_df$NumaNode)

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

这是我想要的边框示例。我对此不满意,因为 4 个图块彼此太靠近并且边框被覆盖。

请在下面找到一些代码,对于间距部分,在 theme() 中使用 plot.margin。我还更改了第 76 行,widths: ggpubr::ggarrange(cpu_plot, memory_plot, ncol = 2, widths = c(2,1)) %>% .

library(ggpubr)
library(tidyverse)

memory_df <- structure(list(NumaNode = c("00", "00", "01", "01", "02", "02", "03", "03"),
                            CounterName = c("TotalMemory", "UsedMemory", "TotalMemory", 
                                            "UsedMemory", "TotalMemory", "UsedMemory", "TotalMemory", "UsedMemory"),
                            Value = c(48, 45.55, 48, 46.38, 48, 46.54, 48, 47.39)),
                       row.names = c(NA, -8L),
                       class = c("tbl_df", "tbl", "data.frame"))

memory_y_scale <-  memory_df %>% filter(CounterName=='TotalMemory') %>% select (Value) %>% max() + 6

cpu_df <- structure(list(NumaNode = c("00", "00", "00", "00", "00", "00", 
                                      "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", 
                                      "00", "00", "00", "01", "01", "01", "01", "01", "01", "01", "01", 
                                      "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", 
                                      "01"), Counter = c("00", "01", "10", "11", "12", "13", "14", 
                                                         "15", "16", "17", "18", "19", "02", "03", "04", "05", "06", "07", 
                                                         "08", "09", "00", "01", "10", "11", "12", "13", "14", "15", "16", 
                                                         "17", "18", "19", "02", "03", "04", "05", "06", "07", "08", "09"
                                      ), Value = c(10.79, 5.85, 9.55, 9.71, 9.77, 4.73, 4.62, 10.92, 
                                                   3.55, 10.3, 1.38, 6.28, 5.42, 4.45, 10.09, 3.42, 10.14, 4.34, 
                                                   9.48, 4.17, 5.2, 3.85, 10.17, 8.49, 10.36, 8.06, 10.01, 8.42, 
                                                   9.12, 7.6, 1.98, 2.41, 4.72, 3.19, 4.74, 3.66, 4.28, 9.83, 5.78, 
                                                   10.18)), row.names = c(NA, -40L), class = c("tbl_df", "tbl", 
                                                                                               "data.frame"))



# plot function =======================================================================

plot_numa = function(num){
  
  # memory plot =====================
  
  memory_filtered_df = memory_df %>% filter(str_detect(NumaNode, num))
  
  memory_plot  <-  memory_filtered_df %>%
    filter(str_detect(CounterName, "Memory")) %>%
    pivot_wider(names_from = CounterName, values_from = Value) %>%
    ggplot(aes(x = "") ) +
    geom_col(aes(y = TotalMemory), fill = "white", color = "black") +
    geom_col(aes(y = UsedMemory), fill = "#00FF66FF", color = "black") +
    geom_text(aes(label = paste(TotalMemory, "GB"), y = TotalMemory + 5 ), color = "black") +
    geom_text(aes(
      label = paste(UsedMemory, "GB"),
      y = ifelse((TotalMemory-UsedMemory > 10), UsedMemory + 5, UsedMemory - 4)),
      color = "black") +
    theme_bw() +
    ylim(0, memory_y_scale) +
    labs(x = "Memory", y = "") +
    theme(plot.margin = unit(c(0.01,2,2,0.01), "cm"))
  
  # cpu plot =====================
  
  cpu_filtered_df <-  cpu_df %>% filter(str_detect(NumaNode, num))
  
  if (nrow (cpu_filtered_df) == 0 )    {
    cpu_filtered_df <- cpu_df %>% filter(str_detect(NumaNode, "00"))
  }
  
  cpu_plot <-  cpu_filtered_df %>%
    ggplot(aes(x = Counter)) +
    geom_col(aes(y = 100), fill = "white", color = "white", alpha = 0) +
    geom_col(aes(y = Value), fill = "#00AFBB", color = "black") +
    theme_bw() +
    labs(x = "CPU, % Processor Time", y = "") +
    theme(plot.margin = unit(c(0.01,0.01,2,0), "cm"))
  
  
  ggpubr::ggarrange(cpu_plot, memory_plot, ncol = 2, widths = c(2,1)) %>% 
    ggpubr::annotate_figure(top = paste("        NUMA",num))
  
}

numa_numbers <- unique(memory_df$NumaNode)

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

以及输出: