簡體   English   中英

手動將圖例添加到 R/ggplot2 圖而不干擾圖

[英]Adding legend manually to R/ggplot2 plot without interfering with the plot

問題:是否可以向與情節本身無關的情節添加圖例,並且 - 至關重要的是 - 不會干擾情節中的顏色?

解釋

我擁有傳奇所需的所有信息。 特別是,我有顏色的十六進制代碼和標簽。 我不在乎顯示什么形狀(線、點,以最簡單的為准)。

我希望這應該可以解決問題(這是一個非常簡化的最小工作示例):

the_colors <- c("#e6194b", "#3cb44b", "#ffe119", "#0082c8", "#f58231", "#911eb4", "#46f0f0", "#f032e6", 
                "#d2f53c", "#fabebe", "#008080", "#e6beff", "#aa6e28", "#fffac8", "#800000", "#aaffc3", 
                "#808000", "#ffd8b1", "#000080", "#808080", "#ffffff", "#000000")
the_labels <- c("01", "02", "03", "04", "05", "06", "07", "08", "09", "10")

the_df <- data.frame("col1"=c(1, 2, 2, 1), "col2"=c(2, 2, 1, 1), "col3"=c(1, 2, 3, 4))

the_plot <- ggplot() + geom_point(data=the_df, aes(x=col1, y=col2), color=the_colors[[4]])

the_plot <- the_plot +
  scale_color_manual("Line.Color", values=the_colors[1:length(the_labels)],
                      labels=the_labels)

不幸的是,它甚至不會顯示圖例。

遵守規則,並在aesthetics元素中包含color參數,我可以讓它顯示一個圖例。

the_plot <- ggplot() + geom_point(data=the_df, aes(x=col1, y=col2, color=the_colors[[4]]))

但是,當然,它不會再認真對待作為color參數 () 傳遞的值,而是將其解釋為某種標簽,並將這些數據點的顏色更改為the_colors列表中的第一個顏色。 同時,它只會在傳說中包含這個,地獄似乎沒有辦法說服它也包含其他。

在其他語言中,這非常容易。 在 R/ggplot2 中,這似乎非常困難。

我想這樣做的原因:我想要一個不會干擾我情節中顏色的圖例。 這有時非常不方便。 也沒有更深層次的原因說明圖例必須弄亂圖中的顏色,只是這就是它在 R/ggplot2 中的實現方式。

方法:我希望有一種方法可以通過仍然將其視為傳奇來輕松做到這一點。 否則,可能會添加一個帶有一些顏色點和一些文本的框,從而從頭開始構建圖例。

其他問題:有很多其他問題在問同樣的事情。 答案確實提出了解決 OP 的具體問題的變通方法(通常通過應用melt()左右),而不提供所提出問題的解決方案(如何手動添加圖例而不會弄亂情節)。 例如這里這里 這不是我感興趣的。我想知道是否可以在任意情節中添加任意圖例,如果可以,如何添加。

軟件: R 3.6.3,ggplot2 3.2.1

編輯(2020 年 3 月 30 日):

解決方案:如下面@Tjebo 的回答所述,可以使用scale_color_identity創建一個與繪圖合理獨立並定義繪圖中未顯示的附加數據系列的scale_color_identity 使用@Tjebo 的答案中的選項 #1,我可以解決我眼前的問題:

the_colors <- sort(c("#e6194b", "#3cb44b", "#ffe119", "#0082c8", "#f58231", "#911eb4", "#46f0f0", "#f032e6", 
            "#d2f53c", "#fabebe", "#008080", "#e6beff", "#aa6e28", "#fffac8", "#800000", "#aaffc3", 
            "#808000", "#ffd8b1", "#000080", "#808080"))

color_df <- data.frame(the_colors=the_colors[1:length(the_labels)], the_labels=the_labels)

the_df <- data.frame("col1"=c(1, 2, 2, 1), "col2"=c(2, 2, 1, 1), "col3"=c(1, 2, 3, 4))

the_plot <- ggplot() + 
    geom_point(data = color_df, aes(x = the_df$col1[[1]], y = the_df$col2[[1]], color = the_colors)) +
    scale_color_identity(guide = 'legend', labels = color_df$the_labels) 

the_plot <- the_plot +
  geom_point(data=the_df, aes(x=col1, y=col2), color=the_colors[[4]]) 

print(the_plot)

解決方案的說明:更一般地說,正如 Tjebo 所解釋的那樣,它將情節與圖例分開。 傳奇仍然需要一個情節。 這是首先構建的:

the_plot <- ggplot() + 
  geom_point(data = color_df, aes(x = the_df$col1[[1]], y = the_df$col2[[1]], color = the_colors)) +
  scale_color_identity(guide = 'legend', labels = color_df$the_labels)

這樣創建的繪圖仍然具有錯誤的顏色,但選擇了這些點,以便通過添加我實際想要以適當顏色顯示的繪圖來隱藏它們:

the_plot <- the_plot + 
  geom_point(data=the_df, aes(x=col1, y=col2), color=the_colors[[4]])

它也很靈活,可以在the_colors變量中預定義的任何顏色中添加更多數據系列:

the_plot <- the_plot +
  geom_point(data=the_df, aes(x=col1, y=col3), color=the_colors[[6]]) 

(注意:如果顏色被定義為數據框中的第三列,數據系列也可以一次繪制。我只是想指出解決方案是靈活的,以后可以修改繪圖而不會干擾圖中已經排列的數據點的圖例或顏色。)

編輯 2(2020 年 3 月 30 日),附加說明:使用此解決方案,圖例將按其十六進制代碼對顏色進行排序。 我無法開始理解為什么它會這樣做,但確實如此。 因此,為了使圖例中的顏色與預期顏色匹配,應事先對十六進制代碼的向量進行排序(如上面的代碼中所做的那樣)。

像這樣的意外行為在 R 和 ggplot2 的正常使用中不會成為問題(您讓 ggplot2 為您做圖例並嚴格限制自己使用的設計)。 這個解決方案基本上是一個關於如何在 ggplot2 中使用圖例的黑客(不幸的是非常嚴格)。 因此,此 hack 可能會在 ggplot 或 R 的未來版本中中斷。

也許這就是你想要的......圖 1 絕對不是一種聰明的 ggplot-y 繪圖方式(本質上,你沒有可視化數據的維度)。 在另一個選項下面(圖 2)...

下面 - 創建新的數據框並使用scale_color_identity 使用第二個圖的數據點,它排在第二位並覆蓋第一個圖,因此該點消失了。

library(tidyverse)
the_colors <- c("#e6194b", "#3cb44b", "#ffe119", "#0082c8", "#f58231", "#911eb4", "#46f0f0", "#f032e6", 
                "#d2f53c", "#fabebe", "#008080", "#e6beff", "#aa6e28", "#fffac8", "#800000", "#aaffc3", 
                "#808000", "#ffd8b1", "#000080", "#808080", "#ffffff", "#000000")

color_df <- data.frame(the_colors, the_labels = seq_along(the_colors))

the_df <- data.frame("col1"=c(1, 2, 2, 1), "col2"=c(2, 2, 1, 1), "col3"=c(1, 2, 3, 4))

#the_plot <- 
  ggplot() + 
    geom_point(data = color_df, aes(x = the_df$col1[[1]], y = the_df$col2[[1]], color = the_colors)) +
    scale_color_identity(guide = 'legend', labels = color_df$the_labels) +
    geom_point(data=the_df, aes(x=col1, y=col2), color=the_colors[[4]]) 

一種更 ggplot-y 的方式

現在,最后一個情節真的很奇怪,因為正如您所說,“顏色與情節無關”[與數據],因此,顯示它們絕對沒有意義。 您真正想要的是可視化數據的維度。

因此,我相信並希望您將這些值與繪制的數據聯系起來。 我正在考慮col3是選擇的變量,它將用顏色表示。

首先,創建一個命名向量,以便您可以將其作為scale_colorvalues參數scale_color 名稱應該是您的列的值,它將用顏色表示,在本例中為col3

names(the_colors) <- str_pad(seq_along(the_colors), width = 2, pad = '0')

the_df <- data.frame("col1"=c(1, 2, 2, 1), "col2"=c(2, 2, 1, 1), "col3"=str_pad(c(1, 2, 3, 4), width = 2,pad='0'))

ggplot() + 
  geom_point(data=the_df, aes(x=col1, y=col2, color = col3))  +
  scale_color_manual(limits = names(the_colors), values = the_colors)

reprex 包(v0.3.0) 於 2020 年 3 月 28 日創建

暫無
暫無

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

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