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

R绘图添加图例问题:含核密度、正态密度与直方图

Fixing Legend Display for Iris Histograms with Density Curves

Hey there! The reason your legends aren't showing up is that you're using coordinates (1, 95) that fall way outside the bounds of your plots. Since you set freq=FALSE in hist(), the y-axis represents density values (not raw counts), which for the iris sepal length data only go up to around 1.0—so 95 is way off the chart!

Quick Fix for Your Existing Code

Simply replace the hardcoded coordinates in legend() with a keyword position that automatically fits within the plot, like "topright", "topleft", or "bottomright". Here's your adjusted code:

# Setosa plot
setosa_length <- iris$Sepal.Length[iris$Species == "setosa"]
hist(setosa_length, freq=FALSE, main="Setosa Sepal Length")
x <- seq(4, 8, length.out=100)
y <- dnorm(x, mean(setosa_length), sd(setosa_length))
lines(x, y, col="red")
lines(density(setosa_length), col="blue")
# Use keyword position instead of hardcoded coordinates
legend("topright", legend=c("Normal Density", "Kernel Density"), 
       col=c("red", "blue"), lty=1, cex=0.8)

# Versicolor plot
versicolor_length <- iris$Sepal.Length[iris$Species == "versicolor"]
hist(versicolor_length, freq=FALSE, main="Versicolor Sepal Length")
x <- seq(4, 8, length.out=100)
y <- dnorm(x, mean(versicolor_length), sd(versicolor_length))
lines(x, y, col="red")
lines(density(versicolor_length), col="blue")
legend("topright", legend=c("Normal Density", "Kernel Density"), 
       col=c("red", "blue"), lty=1, cex=0.8)

# Virginica plot
virginica_length <- iris$Sepal.Length[iris$Species == "virginica"]
hist(virginica_length, freq=FALSE, main="Virginica Sepal Length")
x <- seq(4, 8, length.out=100)
y <- dnorm(x, mean(virginica_length), sd(virginica_length))
lines(x, y, col="red")
lines(density(virginica_length), col="blue")
legend("topright", legend=c("Normal Density", "Kernel Density"), 
       col=c("red", "blue"), lty=1, cex=0.8)

Bonus: Clean Up Your Code with a Loop

Since you're repeating the same code three times, using a loop will make your script shorter and easier to maintain:

# Get unique species names
species_list <- unique(iris$Species)

# Loop through each species
for(species in species_list) {
  # Extract sepal length data
  length_data <- iris$Sepal.Length[iris$Species == species]
  # Create histogram with density
  hist(length_data, freq=FALSE, main=paste(species, "Sepal Length"),
       xlab="Sepal Length", ylab="Density")
  # Generate x values for normal curve
  x <- seq(min(iris$Sepal.Length), max(iris$Sepal.Length), length.out=100)
  # Calculate normal density
  y_norm <- dnorm(x, mean(length_data), sd(length_data))
  # Add normal curve
  lines(x, y_norm, col="red")
  # Add kernel density curve
  lines(density(length_data), col="blue")
  # Add legend in top-right corner
  legend("topright", legend=c("Normal Density", "Kernel Density"),
         col=c("red", "blue"), lty=1, cex=0.8)
}

Key Notes:

  • Using keyword positions like "topright" ensures the legend stays within the plot area automatically, no need to guess coordinates.
  • I removed the with(iris, ...) since you're already working with a subset of the data—it's not necessary here.
  • The loop version uses unique(iris$Species) to dynamically get all species, so if you add more data later, it will still work.

内容的提问来源于stack exchange,提问作者Shilpa Kancharla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:40:40