[英]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_color
的values
參數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.