在r中的x轴上创建两个类别级别的二维聚集柱形图,而不使用ggplot

juud5qan  于 2023-11-14  发布在  其他
关注(0)|答案(2)|浏览(128)

我有一个数据表,我可以把它放入Excel中的聚类柱形图中。我想做同样的事情,但在R中创建图表。如何才能做到这一点?Table of DataChart in Excel
我尝试了下面的方法,结果得到了所附的图表。数据的顺序和标签不正确。ggplot在我的机器上不起作用,所以不是一个选项。

# Create a data frame with the given data
data <- data.frame(
  City = c("Minneapolis", "Minneapolis", "Minneapolis", "Orlando", "Orlando", "Orlando", 
           "Phoenix", "Phoenix", "Phoenix", "Sacramento", "Sacramento", "Sacramento"),
  Tree_Type = c("No Tree", "Medium Tree", "Large Tree", "No Tree", "Medium Tree", "Large Tree", 
                "No Tree", "Medium Tree", "Large Tree", "No Tree", "Medium Tree", "Large Tree"),
  E_Plus = c(158, 133, 123, 879, 863, 827, 2858, 2812, 2779, 421, 363, 351),
  iTE = c(1354, 1337, 1331, 6057, 6043, 6041, 4356, 4336, 4328, 2125, 2099, 2078)
)

# Set up the positions for bars
bar_width <- 0.35
barplot(
  height = c(data$E_Plus, data$iTE), 
  beside = TRUE, 
  names.arg = paste(data$City, data$Tree_Type), 
  col = c("red", "blue"),
  main = "Energy Consumption by City and Tree Type", 
  ylab = "Energy Consumption", 
  xlab = "City / Tree Type", 
  ylim = c(0, max(data$E_Plus, data$iTE) + 500)  # Adjust the y-axis limits if necessary
)

# Adding legend
legend("topright", legend = c("EnergyPlus", "i-Tree Energy"), fill = c("red", "blue"))

# Adding data labels under the bars
text(
  x = 1:(nrow(data) * 2), 
  y = -50,  # Adjust the vertical position of the labels
  labels = paste(data$City, data$Tree_Type), 
  xpd = TRUE, 
  srt = 45, 
  adj = c(1.2, 1.2), 
  cex = 0.8
)

字符串
Incorrect chart from R

f87krz0w

f87krz0w1#

您可以使用barplotmatrix形式(即,为height提供矩阵而不是向量-每列表示一个条形图,每行表示堆叠条形图或旁边的隐藏条形图(beside = TRUE))。然后每个组已经很好地放在一起,组之间有一些间隙。
然后你需要一些摆弄标签,你可以得到非常接近Excel正在做的事情:

with(data, {
  op <- par(mar = c(7, 4, 4, 2) + .1) ## make some space for the labels below
  barplot(rbind(E_Plus, iTE), ## use matrix form
          col = c("steelblue", "orange"),
          beside = TRUE
  )
  ## Tree_Type below each group
  text(seq(2, by = 3, length.out = 12), par("usr")[3] - .25, 
       srt = 90, adj = 1, xpd = TRUE,
       labels = Tree_Type) ## xpd = TRUE to put labels outside the plotting area
  ## City centered below each group of three Tree_Types
  text(seq(5, by = 9, length.out = 4), par("usr")[3] - 1500, 
       xpd = TRUE, labels = unique(City))
  x <- seq(.5, by = 9, length.out = 5)
  ## lines as in the Excel variant
  segments(x, 0, x, par("usr")[3] - 1700, col = "lightgray", xpd = TRUE)
  par(op)
})

字符串
x1c 0d1x的数据

eblbsuwk

eblbsuwk2#

我们可以reshape数据,并使用一些算法来避免硬编码(尽可能多地)。

r <- reshape(data, idvar='Tree_Type', timevar='City', v.names=c('E_Plus', 'iTE'),
             direction='w') |>
  {\(.) `rownames<-`(.[, -1], .[, 1])}() |> as.matrix()

sq <- seq_len(ncol(r)); .clr <- c('#2297e6', '#ffa500')

par(mar=c(10, 4, 4, 2))

plot.new()
plot.window(c(2.5, prod(dim(r))*2.15), c(range(r)))
lapply(seq(0, max(r), 1e3), \(i) abline(h=i, col='gray80'))
b <- barplot(unlist(lapply(unique(data$City), \(x) t(r[, grep(x, colnames(r))]))), 
             space=c(2, .25), col=.clr, legend.text=c('E+', 'iTE'), las=1, add=T)
mtext(rownames(r), 1, 0.5, at=colMeans(matrix(b, 2)), las=2)
mtext(unique(data$City), 1, 6, at=colMeans(matrix(b, 6)), las=1, col=8)
b2 <- matrix(b[-1, ], 2) |> suppressWarnings()
n <- nrow(r)
pos <- colMeans(b2[, seq_len(ncol(b2)) %% n == 0][, 1:n])
.d <- diff(tail(pos, 2))
pos <- c(pos[1] - .d, pos, pos[length(pos)] + .d)
segments(pos, 0, pos, -.26e4, xpd=TRUE, col='gray80')

字符串
x1c 0d1x的数据
很遗憾barplot还没有panel.first=参数!

  • 数据:*
data <- structure(list(City = c("Minneapolis", "Minneapolis", "Minneapolis", 
"Orlando", "Orlando", "Orlando", "Phoenix", "Phoenix", "Phoenix", 
"Sacramento", "Sacramento", "Sacramento"), Tree_Type = c("No Tree", 
"Medium Tree", "Large Tree", "No Tree", "Medium Tree", "Large Tree", 
"No Tree", "Medium Tree", "Large Tree", "No Tree", "Medium Tree", 
"Large Tree"), E_Plus = c(158, 133, 123, 879, 863, 827, 2858, 
2812, 2779, 421, 363, 351), iTE = c(1354, 1337, 1331, 6057, 6043, 
6041, 4356, 4336, 4328, 2125, 2099, 2078)), class = "data.frame", row.names = c(NA, 
-12L))

相关问题