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

ggplot2多stat_function图例不显示及Y轴改频数问题求助

问题1:修复图例不显示的问题

你的图例不显示核心原因是stat_function中同时指定了外层固定颜色和aes(colour)映射,固定颜色会覆盖映射规则,导致ggplot无法识别图例生成逻辑。另外如果需要将直方图样式也纳入图例,需把fill参数移入aes中统一管理。

仅保留分布曲线图例的修改代码

data <- runif(100, 15, 45)
df <- data.frame(data)

graph_parameter_product <- function(data_set, column_value, bin_width, title_value) {
    # 提前提取列值,避免函数内变量作用域问题
    col_val <- data_set[[deparse(substitute(column_value))]]
    graph <- ggplot(data_set, aes(x= column_value )) +
      geom_histogram(binwidth = bin_width, fill= "lightblue", colour= "black", aes(y=..density..)) + 
      xlab("Measurement") +
      ylab("Density") +
      labs(title = title_value ) +
      theme(plot.title = element_text(hjust = 0.5))+
      # 移除外层固定colour参数,仅保留aes内的映射定义
      stat_function(fun = dnorm,
                    args = list(mean = mean(col_val), sd = sd(col_val)),
                    aes(colour = "Normal")) +
      stat_function(fun = dlnorm,
                    args = list(meanlog = mean(log(col_val)), sdlog = sd(log(col_val))),
                    linetype="dotted", size=1.2,
                    aes(colour = "LogNormal")) +
      scale_colour_manual("Distribution", values = c("Normal"="red", "LogNormal"="black"))
    
    graph 
  }
  
graph_parameter_product(df, data, 1, "Test Data")

含直方图样式图例的修改代码

如果需要把直方图也加入图例,可调整geom_histogram的fill参数到aes中,并添加填充色的图例配置:

graph_parameter_product <- function(data_set, column_value, bin_width, title_value) {
    col_val <- data_set[[deparse(substitute(column_value))]]
    graph <- ggplot(data_set, aes(x= column_value )) +
      # 将fill移入aes,指定图例标签
      geom_histogram(binwidth = bin_width, colour= "black", aes(y=..density.., fill= "Histogram")) + 
      xlab("Measurement") +
      ylab("Density") +
      labs(title = title_value ) +
      theme(plot.title = element_text(hjust = 0.5))+
      stat_function(fun = dnorm,
                    args = list(mean = mean(col_val), sd = sd(col_val)),
                    aes(colour = "Normal")) +
      stat_function(fun = dlnorm,
                    args = list(meanlog = mean(log(col_val)), sdlog = sd(log(col_val))),
                    linetype="dotted", size=1.2,
                    aes(colour = "LogNormal")) +
      scale_colour_manual("Distribution", values = c("Normal"="red", "LogNormal"="black")) +
      scale_fill_manual("Histogram", values = c("Histogram"="lightblue")) +
      # 可选:调整图例顺序
      guides(fill=guide_legend(order=1), colour=guide_legend(order=2))
    
    graph 
  }
附加问题:Y轴显示实际频数

要让Y轴显示频数,需要做两处关键修改:

  1. 移除geom_histogram中的y=..density..,默认Y轴就是频数(对应..count..)。
  2. 将stat_function返回的密度值转换为频数:频数 = 密度 × 样本量 × 组距,因为密度是频数除以(样本量×组距)的结果。

完整修改代码

data <- runif(100, 15, 45)
df <- data.frame(data)

graph_parameter_product <- function(data_set, column_value, bin_width, title_value) {
    col_val <- data_set[[deparse(substitute(column_value))]]
    sample_size <- nrow(data_set)
    graph <- ggplot(data_set, aes(x= column_value )) +
      # 移除y=..density..,默认显示频数
      geom_histogram(binwidth = bin_width, fill= "lightblue", colour= "black") + 
      xlab("Measurement") +
      ylab("Frequency") +
      labs(title = title_value ) +
      theme(plot.title = element_text(hjust = 0.5))+
      # 将密度值转换为频数
      stat_function(fun = function(x) dnorm(x, mean=mean(col_val), sd=sd(col_val)) * sample_size * bin_width,
                    aes(colour = "Normal")) +
      stat_function(fun = function(x) dlnorm(x, meanlog=mean(log(col_val)), sdlog=sd(log(col_val))) * sample_size * bin_width,
                    linetype="dotted", size=1.2,
                    aes(colour = "LogNormal")) +
      scale_colour_manual("Distribution", values = c("Normal"="red", "LogNormal"="black"))
    
    graph 
  }
  
graph_parameter_product(df, data, 1, "Test Data")

内容的提问来源于stack exchange,提问作者Joe the Second

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:36:32