You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RStudio中统一直方图坐标轴刻度的技术问询

问题

在RStudio中绘制了对应type为x、y、z、-x、-y、-z的6个直方图,按3列2行排列。当前每个图的坐标轴刻度独立适配,部分图最大柱高为30,部分仅为5,无法直观对比。

需求:

  • 将type为x、y、-x、-y的直方图的y轴(count)和x轴(load)刻度统一
  • 将z和-z的刻度也统一
  • 也可接受6个图刻度全部统一

思路:先获取每种type的最大柱高,取最大值设置y轴;x轴取每种type的value最大值的全局最大值设置。

当前可用代码:

library(tidyverse)
library(dplyr)
library(ggplot2)

#Sample data set
max_values <- data.frame(
  type = c("x","x","x","x","y","y","y","y","z","z","z","z","z","-x","-x","-x","-x","-y","-y","-y","-y","-z","-z","-z","-z","-z"),
  values = c(0.5,1,2,0.3,1,2,3,4,0.5,0.4,0.3,0.2,2,5,5.1,6,4.9,3,10,9.5,9.1,9,9.7,8)
)

# create a list of type values
type_list <- c("x", "y", "z", "-x", "-y", "-z")

# create an empty list to store the plots
plot_list <- list()

# loop through the type values and create a plot for each type
for (i in type_list) {
  plot_data <- max_values %>% filter(type == i)  # 原代码中scenario列不存在,此处移除该过滤条件
  if(nrow(plot_data) > 0) {  
    plot <- ggplot(plot_data, aes(values)) +     # 修正数据列名为values
      geom_histogram(colour= 1, fill = "white", binwidth=0.5) +
      ggtitle(paste("Histogram |", toupper(i), "Max values | Scenario 1")) +
      xlab("Load (N) [Bin top 0.5]") +
      ylab("Count (@500 samples per sec)")
    
    # add the plot to the plot_list
    plot_list[[i]] <- plot
  }
}

# display the plots
gridExtra::grid.arrange(
  plot_list[["x"]],
  plot_list[["y"]],
  plot_list[["z"]],
  plot_list[["-x"]],
  plot_list[["-y"]],
  plot_list[["-z"]],
  ncol = 3
)

尝试过的近似代码:

# loop through the type values and create a plot for each type
for (i in type_list) {
  plot_data <- max_values %>% 
    filter(type == i)  # 移除不存在的scenario过滤条件
  
  if(nrow(plot_data) > 0 && !all(is.na(plot_data$values))) { # 修正列名
    # create bins of width 0.5 based on the values in the `value` column
    plot_data$binwidth <- cut(plot_data$values, breaks = seq(0, max(plot_data$values), by = 0.5), include.lowest = TRUE)
    
    # add a group column based on the bin width
    plot_data$group <- as.factor(match(plot_data$binwidth, unique(plot_data$binwidth)))
    
    # get the max bin width
    max_binwidth <- max(as.numeric(plot_data$binwidth))
    
    # create the plot
    plot <- ggplot(plot_data, aes(values)) +     # 修正列名
      geom_histogram(colour=1, fill="white", binwidth=0.5) +
      ggtitle(paste("Histogram |", toupper(i), "Max values | Scenario 1")) +
      xlab("Load (N) [Bin top 0.5]") +
      ylab("Count (@500 samples per sec)") +
      facet_wrap(~ group, scales = "free_y") +  # group the histograms by the bin width
      scale_x_continuous(limits = c(0, max_binwidth), expand = c(0,0)) +  # set the x axis limits
      scale_y_continuous(limits = c(0, NA), expand = c(0,0))  # set the y axis limits
    
    # add the plot to the plot_list
    plot_list[[i]] <- plot
  }
}
解决方案

方案1:分组统一刻度(x/y/-x/-y一组,z/-z一组)

提前计算两组的x轴最大值和y轴最大计数,绘图时按组统一设置坐标轴范围:

library(tidyverse)
library(ggplot2)
library(gridExtra)

# 修正后的样本数据
max_values <- data.frame(
  type = c("x","x","x","x","y","y","y","y","z","z","z","z","z","-x","-x","-x","-x","-y","-y","-y","-y","-z","-z","-z","-z","-z"),
  values = c(0.5,1,2,0.3,1,2,3,4,0.5,0.4,0.3,0.2,2,5,5.1,6,4.9,3,10,9.5,9.1,9,9.7,8)
)

# 定义分组
group1 <- c("x", "y", "-x", "-y")
group2 <- c("z", "-z")

# 计算group1的x轴最大值和y轴最大计数
group1_x_max <- max(max_values$values[max_values$type %in% group1])
group1_y_max <- max(
  max_values %>% 
    filter(type %in% group1) %>% 
    group_by(type) %>% 
    summarise(count_max = table(cut(values, breaks = seq(0, group1_x_max, by = 0.5), include.lowest = TRUE)) %>% max()) %>% 
    pull(count_max)
)

# 计算group2的x轴最大值和y轴最大计数
group2_x_max <- max(max_values$values[max_values$type %in% group2])
group2_y_max <- max(
  max_values %>% 
    filter(type %in% group2) %>% 
    group_by(type) %>% 
    summarise(count_max = table(cut(values, breaks = seq(0, group2_x_max, by = 0.5), include.lowest = TRUE)) %>% max()) %>% 
    pull(count_max)
)

type_list <- c("x", "y", "z", "-x", "-y", "-z")
plot_list <- list()

for (i in type_list) {
  plot_data <- max_values %>% filter(type == i)
  if(nrow(plot_data) > 0) {
    # 根据所属分组设置坐标轴范围
    if(i %in% group1) {
      x_limits <- c(0, group1_x_max)
      y_limits <- c(0, group1_y_max)
    } else {
      x_limits <- c(0, group2_x_max)
      y_limits <- c(0, group2_y_max)
    }
    
    plot <- ggplot(plot_data, aes(values)) +     
      geom_histogram(colour= 1, fill = "white", binwidth=0.5) +
      ggtitle(paste("Histogram |", toupper(i), "Max values | Scenario 1")) +
      xlab("Load (N) [Bin top 0.5]") +
      ylab("Count (@500 samples per sec)") +
      scale_x_continuous(limits = x_limits, expand = c(0, 0)) +
      scale_y_continuous(limits = y_limits, expand = c(0, 0))
    
    plot_list[[i]] <- plot
  }
}

# 排列展示
grid.arrange(
  plot_list[["x"]], plot_list[["y"]], plot_list[["z"]],
  plot_list[["-x"]], plot_list[["-y"]], plot_list[["-z"]],
  ncol = 3
)

方案2:全部6个图统一刻度

计算全局x轴最大值和全局y轴最大计数,所有图共用同一坐标轴范围:

library(tidyverse)
library(ggplot2)
library(gridExtra)

max_values <- data.frame(
  type = c("x","x","x","x","y","y","y","y","z","z","z","z","z","-x","-x","-x","-x","-y","-y","-y","-y","-z","-z","-z","-z","-z"),
  values = c(0.5,1,2,0.3,1,2,3,4,0.5,0.4,0.3,0.2,2,5,5.1,6,4.9,3,10,9.5,9.1,9,9.7,8)
)

# 计算全局x轴最大值
global_x_max <- max(max_values$values)
# 计算每个type的直方图计数最大值,再取全局最大
global_y_max <- max(
  max_values %>% 
    group_by(type) %>% 
    summarise(count_max = table(cut(values, breaks = seq(0, global_x_max, by = 0.5), include.lowest = TRUE)) %>% max()) %>% 
    pull(count_max)
)

type_list <- c("x", "y", "z", "-x", "-y", "-z")
plot_list <- list()

for (i in type_list) {
  plot_data <- max_values %>% filter(type == i)
  if(nrow(plot_data) > 0) {
    plot <- ggplot(plot_data, aes(values)) +     
      geom_histogram(colour= 1, fill = "white", binwidth=0.5) +
      ggtitle(paste("Histogram |", toupper(i), "Max values | Scenario 1")) +
      xlab("Load (N) [Bin top 0.5]") +
      ylab("Count (@500 samples per sec)") +
      scale_x_continuous(limits = c(0, global_x_max), expand = c(0, 0)) +
      scale_y_continuous(limits = c(0, global_y_max), expand = c(0, 0))
    
    plot_list[[i]] <- plot
  }
}

grid.arrange(
  plot_list[["x"]], plot_list[["y"]], plot_list[["z"]],
  plot_list[["-x"]], plot_list[["-y"]], plot_list[["-z"]],
  ncol = 3
)

关键说明

  1. 修正了原代码中的两个问题:数据列名应为values而非value,移除了不存在的scenario过滤条件。
  2. 计算直方图最大计数时,采用和绘图一致的0.5宽度分箱逻辑,确保统计结果与实际绘图的柱高匹配。
  3. 使用expand = c(0,0)去除坐标轴两端的空白,让图表布局更紧凑。

内容的提问来源于stack exchange,提问作者Chris Topher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 00:15:12