簡體   English   中英

R- Bar plot 具有連續的 x 和 y

[英]R- Bar plot with continuous x and y

如果這個問題已經得到回答,請鏈接,因為我無法找到類似的問題。 I have referred to R bar plot with 3 variables , Bar plot with multiple variables in R , ggplot with 2 y axes on each side and different scales , Bar Plot with 2 y axes and same x axis in R language [duplicate] , Bar Plot具有 2 個 Y 軸和相同的 X 軸

我有一個數據集,其中包括物種、觀察值、預期值以及觀察值和預期值的標准化值。

data <- structure(list(Species = c("BABO_BW", "BABO_BW", "BABO_BW", "BABO_RC", 
"BABO_RC", "BABO_RC", "BABO_SKS", "BABO_SKS", "BABO_SKS", "BABO_MANG", 
"BABO_MANG", "BABO_MANG", "BW_RC", "BW_RC", "BW_RC", "BW_SKS", 
"BW_SKS", "BW_SKS", "BW_MANG", "BW_MANG", "BW_MANG", "RC_SKS", 
"RC_SKS", "RC_SKS", "RC_MANG", "RC_MANG", "RC_MANG", "SKS_MANG", 
"SKS_MANG", "SKS_MANG"), variable = c("obs.C-score", "exp.C-score", 
"SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", 
"exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", 
"obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", 
"SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", "obs.C-score", 
"exp.C-score", "SES_Cscore", "obs.C-score", "exp.C-score", "SES_Cscore", 
"obs.C-score", "exp.C-score", "SES_Cscore"), value = c(328680, 
276507, 6.73358774036271, 408360, 345488, 5.31345024375997, 285090, 
254670, 4.35376633657727, 12474, 12190, 1.24624427424057, 1450800, 
1809738, -11.0195450589776, 1507488, 1361088, 6.15672144449049, 
62706, 65780, -0.495728742814285, 1790156, 1700165, 2.70409191051284, 
45701, 86301, -4.71151949799025, 42240, 62745, -4.52203636797869
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-30L))

樣品 Output

    Species    Variable       Value
1   BABO_BW    obs.C-score    328680.0000000
2   BABO_BW    exp.C-score    276507.0000000
3   BABO_BW    SES_Cscore     6.7335877
4   BABO_MANG  obs.C-score    12474.0000000
5   BABO_MANG  exp.C-score    12190.0000000
6   BABO_MANG  SES_Cscore     1.2462443
7   BABO_RC    obs.C-score    408360.0000000
8   BABO_RC    exp.C-score    345488.0000000
9   BABO_RC    SES_Cscore     5.3134502
10  BABO_SKS   obs.C-score    285090.0000000

我試圖將 SES_Cscore 放在 x 軸上,並將 obs.C-score 和 exp.C-score 作為條形。 物種列對 C 分數進行了分組,因此我也想將它們包括在 x 軸中。

我已經能夠將 plot 處的物種和其他變量作為條形圖。

ggplot(data,aes(x = Species,y = value)) + 
    geom_bar(aes(fill = variable),stat = "identity",position = "dodge")

圖表不正確

我想在 x 軸上也有 SES_Cscore 的連續變量。 有沒有辦法做到這一點?

提前謝謝你,祝你有美好的一天!

這可以通過稍微重塑數據來完成,以便 SES_Score 被記錄為每個物種一個值的變量,而不是作為每個觀察映射到條形高度的變量。 我在這里通過重塑寬(以便三個變量每個都有自己的列)來做到這一點,然后再次重塑長但僅限於我們想要 map 到 y 的變量。

library(tidyverse)
data %>%
  pivot_wider(names_from = variable, values_from = value) %>%
  pivot_longer(2:3) %>%
  mutate(Species2 = paste(Species, round(SES_Cscore,digits = 2), sep = "\n") %>%
           fct_reorder(SES_Cscore)) -> data2

data2
## A tibble: 20 × 5
#   Species   SES_Cscore name          value Species2         
#   <chr>          <dbl> <chr>         <dbl> <fct>            
# 1 BABO_BW        6.73  obs.C-score  328680 "BABO_BW\n6.73"  
# 2 BABO_BW        6.73  exp.C-score  276507 "BABO_BW\n6.73"  
# 3 BABO_RC        5.31  obs.C-score  408360 "BABO_RC\n5.31"  
# 4 BABO_RC        5.31  exp.C-score  345488 "BABO_RC\n5.31"  
# 5 BABO_SKS       4.35  obs.C-score  285090 "BABO_SKS\n4.35" 
# etc.

我們可以通過將其連接到我們想要的 map 到 y 的觀察結果和我們想要用於每個物種的 x position 的觀察結果之間,以一種可能對大數據更有效的方式交替地實現不同的重塑:

left_join(data %>% filter(variable != "SES_Cscore"),
          data %>% filter(variable == "SES_Cscore") %>%
            transmute(Species, x_val = value,
                      Species_label = paste(Species, sprintf(value, 
                        fmt = "%#.2f"), sep = "\n") %>% fct_reorder(value))) 

重塑后,更直接地獲得按每個物種的 SES_Cscore 排序的 plot:

ggplot(data2, aes(Species2, value, fill = name)) +
  geom_col(position = "dodge")

在此處輸入圖像描述


如果您想要 plot 具有與 SES_Cscore 相關的連續 x 軸,您可能會遇到一些圖形設計挑戰,因為在某些情況下數據可能會聚集在一起。 請注意默認條形寬度是如何被壓縮的,以便 ggplot 可以防止第二和第三種條形圖重疊。

這種方法也需要更多的工作,因為 ggplot 的軸適用於離散(分類)數據或連續數據,並且沒有設計用於管理組合的默認值,分類數據是連續映射的。 所以你必須恢復到某種geom_text來制作手動標簽,如果你想讓它們看起來更像普通的軸標簽,還需要進行一些定制。

ggplot(data2, aes(SES_Cscore, value, fill = name)) +
  geom_col(position = "dodge") +
  ggrepel::geom_text_repel(aes(y = 0, label = Species), 
                           angle = 90, direction = "x", hjust = 0, lineheight = 0.8, size = 3,
                           data = data2 %>% distinct(Species, .keep_all = TRUE))

在此處輸入圖像描述

在前面,縮放數據並使用第二個軸可能會在視覺上歪曲數據:不難快速查看這個 plot 並推斷出藍色條的值與紅色/綠色條的含義相同。

話雖如此,試試這個:

library(ggplot2)
library(dplyr)
fac <- 50000
mycolors <- c("obs.C-score" = "red", "exp.C-score" = "green", "SES_Cscore" = "blue")
data %>%
  mutate(value = value * ifelse(variable == "SES_Cscore", fac, 1)) %>%
  ggplot(aes(x = Species, y = value)) +
  geom_bar(aes(fill = variable), stat = "identity", position = "dodge") +
  scale_y_continuous(
    sec.axis = sec_axis(name = "SES_Cscore", ~ . / fac),
    breaks = ~ scales::extended_breaks()(pmax(0, .))
  ) +
  scale_color_manual(values = mycolors) +
  theme(
    axis.title.y.right = element_text(color = mycolors["SES_Cscore"]),
    axis.text.y.right = element_text(color = mycolors["SES_Cscore"]),
    axis.ticks.y.right = element_line(color = mycolors["SES_Cscore"])
  )

帶第二軸的ggplot

我在第二個(右)軸上使用藍色 colors 來嘗試在視覺上將它與藍色條配對。 根據我對數據的推斷,我還冒昧地將主軸(左)保持在 0 或更大; 根本不需要。 另外,我可以省略scale_color_manual(.)並假設使用element_text(color="blue")是正確的; 如果/當您的數據在variable中以更少或更多級別發生變化時,那將失敗,所以我手動控制它們......我嘗試為第二個軸上的所有內容分配正確的顏色:-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM