如何绘制基于幅度的堆叠条形图(在R图或ggplot中)?

fkvaft9z  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(87)

为了清楚地解释我想画什么,我给出了一个示例R代码。这是我的数据矩阵。

mat.all=matrix(c(1,rep(2,4),rep(3,6),rep(4,4),5,139.17365,136.27613,139.01464,135.47032,98.02343,136.28064,132.31289,135.26496,96.62991, 97.49587,90.17913,132.25711,96.01838,88.87682,89.06218,87.65776),16,2,byrow=F)

字符串
这给

[,1]      [,2]
 [1,]    1 139.17365
 [2,]    2 136.27613
 [3,]    2 139.01464
 [4,]    2 135.47032
 [5,]    2  98.02343
 [6,]    3 136.28064
 [7,]    3 132.31289
 [8,]    3 135.26496
 [9,]    3  96.62991
[10,]    3  97.49587
[11,]    3  90.17913
[12,]    4 132.25711
[13,]    4  96.01838
[14,]    4  88.87682
[15,]    4  89.06218
[16,]    5  87.65776


在这里,我需要画4个竖条,每个竖条的高度为mat.all[1,2] = 139.17365。然后对于第一个竖条,我需要标记一条对应于mat.all行中所有2的线。即mat.all[2:5,2]
类似地,对于第二个小节,我需要对所有的3进行这样的处理,对于第三个小节,我需要对所有的4进行这样的处理,对于第四个小节,我需要对5(最后一个)进行这样的处理。
最后,我需要在每个条形中放置一个文本,以显示以下基于第一个值大小的百分比减少,即mat.all[1,2] = 139.17365。

perc.all=round(((mat.all[1,2]-mat.all[1:16,2])*100/mat.all[1,2]),1)
> perc.all
 [1]  0.0  2.1  0.1  2.7 29.6  2.1  4.9  2.8 30.6 29.9 35.2  5.0 31.0 36.1
[15] 36.0 37.0


我在下面添加了一个png文件来显示我想要的堆叠条形图。我试图粗略地显示第一个条形图。


的数据
我真的很感激任何帮助,有我的愿望输出。谢谢。

monwx1rj

monwx1rj1#

为了返回您概述的情节,还有很多事情要做。此外,您还没有提供所需输出的详细示例,但基于您给出的示例,希望这接近您想要的。
在这个方法中,其中一个标签的位置有问题,我无法解决这个问题,所以我最终手动纠正了它。如果有人能看到错误,请在下面评论。

library(dplyr)
library(ggplot2)

# A dataframe of your matrix
df <- data.frame(matrix(c(1,rep(2,4),rep(3,6),rep(4,4),5,
                          139.17365,136.27613,139.01464,
                          135.47032,98.02343,136.28064,
                          132.31289,135.26496,96.62991,
                          97.49587,90.17913,132.25711,
                          96.01838,88.87682,89.06218,87.65776),16,2,
                        byrow=F))

colnames(df) <- c("id", "value")

# Get max value of value column
max_value <- max(df[,2])

# Prepare data for plotting
df1 <- df %>%
  # Your "percentage decrease based on magnitude" formula
  mutate(perc_all = round((max(value) - value) * 100 / max(value), 1)) %>%
  group_by(id) %>%
  # Assign value for original order (and for barplot labels)
  mutate(ord = paste0("x", 1:n())) %>%
  # Sort data in descending order
  arrange(id, desc(perc_all)) %>%
  # Create vector of barplot labels
  mutate(label_text =  paste0(ord,"=", round(perc_all, 1), "%")) %>%
  # Add one row to each group for absent data
  group_modify(~ add_row(.x,.before = 0)) %>%
  # Add value to new rows so each column adds up to max_value
  mutate(perc_all = ifelse(is.na(perc_all),
                           max_value - sum(perc_all, na.rm = TRUE), perc_all),
         # Add "x" value to new rows
         ord = ifelse(is.na(ord),
                      paste0("x", n()), ord),
         # Calculate label locations for barplot labels
         label_loc = cumsum(lag(perc_all, default = 0))) %>% 
  # Return only the plot data
  filter(id %in% 2:5) %>%
  ungroup()

# Label placement of x3 for id group 3 is incorrect, could not work out why,
# so have to manually edit it
df1[11,6] <- df1[11,6] - 2

# Running this will return a warning, which you can ignore, it just means
# there are NA values in the label_text column
ggplot() +
  geom_bar(data = df1,
           aes(x = id, 
               y = perc_all,
               fill = ord,
               group = ord),
           stat = "identity",
           show.legend = FALSE) +
  geom_text(data = df1,
            aes(x = id,
                y = label_loc,
                label = label_text),
            vjust = -0.1,
            colour = "black",
            size = 2)

字符串


的数据

zzzyeukh

zzzyeukh2#

这就是你想要的吗

mat.all=matrix(c(1,rep(2,4),rep(3,6),rep(4,4),5,139.17365,136.27613,139.01464,135.47032,98.02343,136.28064,132.31289,135.26496,96.62991, 97.49587,90.17913,132.25711,96.01838,88.87682,89.06218,87.65776),16,2,byrow=F)

library(ggplot2)

# Convert the matrix to a data frame
df <- data.frame(mat.all)
perc.all=round(((mat.all[1,2]-mat.all[1:16,2])*100/mat.all[1,2]),1)
# Add a column for percentage decrease
df$perc.decrease <- perc.all

# Plot the stacked bar chart
ggplot(df, aes(x = factor(X1), y = X2, fill = factor(X1))) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = paste0(perc.decrease, "%")),
            position = position_stack(vjust = 0.5), size = 3) +
  #scale_y_continuous(labels = scales::comma) +  # Optional, format y-axis labels
  labs(title = "Stacked Bar Chart with Percentage Decrease",
       x = "Category",
       y = "Magnitude") +
  theme_minimal()

字符串

相关问题