当您拥有并非全部列的多个变量时,如何指定GGPLOT传奇顺序?

发布于 2025-01-18 14:35:51 字数 2224 浏览 5 评论 0原文

我使用 ggplot 按不同的时间尺度(周、月、季度等)绘制相同的数据,因此,我从不同的列中提取数据。然而,当我看到我的图例时,我希望它是一个特定的顺序。

我知道如果所有分组变量都在一列中,我可以将其设置为有序因子,正如它所解释的此处,但我的数据分布在多个列中。我还尝试了此处关于重新排序多个geoms的建议,但它没有不工作。

因为我的实际数据集非常复杂,所以我复制了一个较小的版本,其中只有周和月的数据。对于最终答案,请允许它指定特定的顺序,而不仅仅是像 rev() 这样的东西,因为在我的实际数据集中,我有 6 列需要特定的顺序命令。

下面是要重现的代码 - 为此,前 3 个块构成数据集,因此只有用于绘制图的第 4 个块应该与实际解决方案相关。 R 显示顺序的默认情况是在图例中首先显示“分数 - 月份”,所以我想看看如何使其成为第二个。

library(dplyr)
library(ggplot2)
library(lubridate)

#Generates week data -- shouldn't be relevant to troubleshoot
by_week <- tibble(Week = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="weeks"),
                Week_score = c(sample(100:200, 79)),
                Month = ymd(format(Week, "%Y-%m-01")))

#Generates month data -- shouldn't be relevant to troubleshoot                
by_month <- tibble(Month = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="months"),
                   Month_score = c(sample(150:200, 19)))

#Joins data and removes duplications of month data for easier plotting -- shouldn't be relevant to troubleshoot  
all_time <- by_week %>%
  full_join(by_month) %>%
  mutate(helper = across(c(contains("Month")), ~paste(.))) %>% 
  mutate(across(c(contains("Month")), ~ifelse(duplicated(helper), NA, .)), .keep="unused") %>%
  mutate(Month = as.Date(Month))

#Makes plot - this is where I want the order in the legend to be different
all_time %>%
  ggplot(aes(x = Week)) +
  geom_line(aes(y= Week_score, colour = "Week_score")) +
  geom_line(data=all_time[!is.na(all_time$Month_score),], aes(y = Month_score, colour = "Month_score")) + #This line tells R just to focus on non-missing values for Month_score
  scale_colour_discrete(labels = c("Week_score" = "Score - Week", "Month_score" = "Score - Month"))

这就是当前图例的样子——我希望使用可扩展到 2 个以上选项的解决方案来切换顺序。谢谢你!

输入图片此处描述

I'm plotting the same data by different time scales (Week, Month, Quarter, etc.) using ggplot, and as a result, I'm pulling the data from different columns. However, when I see my legend, I want it to be a specific order.

I know if all the grouping variables were in one column, I could set it as an ordered factor, as it explained here, but my data are spread across multiple columns. I also tried the suggestions here about re-ordering multiple geoms, but it didn't work.

Because my actual dataset is very complex, I've reproduced a smaller version that just has week and month data. For the final answer, please allow it to specify a specific order, not just something like rev(), because in my actual dataset, I have 6 columns that need a specific order.

Here's a code to reproduce--for this, the first 3 chunks make the dataset, so only the 4th chunk to make the plot should be relevant for the actual solution. The default that R shows the order is by showing 'Score - Month' first in the legend, so I'd like to see how I could make this the 2nd.

library(dplyr)
library(ggplot2)
library(lubridate)

#Generates week data -- shouldn't be relevant to troubleshoot
by_week <- tibble(Week = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="weeks"),
                Week_score = c(sample(100:200, 79)),
                Month = ymd(format(Week, "%Y-%m-01")))

#Generates month data -- shouldn't be relevant to troubleshoot                
by_month <- tibble(Month = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="months"),
                   Month_score = c(sample(150:200, 19)))

#Joins data and removes duplications of month data for easier plotting -- shouldn't be relevant to troubleshoot  
all_time <- by_week %>%
  full_join(by_month) %>%
  mutate(helper = across(c(contains("Month")), ~paste(.))) %>% 
  mutate(across(c(contains("Month")), ~ifelse(duplicated(helper), NA, .)), .keep="unused") %>%
  mutate(Month = as.Date(Month))

#Makes plot - this is where I want the order in the legend to be different
all_time %>%
  ggplot(aes(x = Week)) +
  geom_line(aes(y= Week_score, colour = "Week_score")) +
  geom_line(data=all_time[!is.na(all_time$Month_score),], aes(y = Month_score, colour = "Month_score")) + #This line tells R just to focus on non-missing values for Month_score
  scale_colour_discrete(labels = c("Week_score" = "Score - Week", "Month_score" = "Score - Month"))

Here's what the current legend looks like--I want the order switched with a solution that is scalable to more than 2 options. Thank you!

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼波传意 2025-01-25 14:35:51

正如 @stefan 在评论中提到的,您应该在 scale_colour_discretelimits 选项中设置标签名称。您可以自己添加更多列。您可以使用以下代码:

library(dplyr)
library(ggplot2)
library(lubridate)

#Generates week data -- shouldn't be relevant to troubleshoot
by_week <- tibble(Week = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="weeks"),
                  Week_score = c(sample(100:200, 79)),
                  Month = ymd(format(Week, "%Y-%m-01")))

#Generates month data -- shouldn't be relevant to troubleshoot                
by_month <- tibble(Month = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="months"),
                   Month_score = c(sample(150:200, 19)))

#Joins data and removes duplications of month data for easier plotting -- shouldn't be relevant to troubleshoot  
all_time <- by_week %>%
  full_join(by_month) %>%
  mutate(helper = across(c(contains("Month")), ~paste(.))) %>% 
  mutate(across(c(contains("Month")), ~ifelse(duplicated(helper), NA, .)), .keep="unused") %>%
  mutate(Month = as.Date(Month))

#Makes plot - this is where I want the order in the legend to be different
all_time %>%
  ggplot(aes(x = Week)) +
  geom_line(aes(y= Week_score, colour = "Week_score")) +
  geom_line(data=all_time[!is.na(all_time$Month_score),], aes(y = Month_score, colour = "Month_score")) + #This line tells R just to focus on non-missing values for Month_score
  scale_colour_discrete(labels = c("Week_score" = "Score - Week", "Month_score" = "Score - Month"), limits = c("Week_score", "Month_score"))

输出:

在此处输入图像描述

如您所见,标签的顺序已更改。

As @stefan mentioned right in the comments, you should set the names of your labels in the limits option of scale_colour_discrete. You can add more columns by yourself. You can use the following code:

library(dplyr)
library(ggplot2)
library(lubridate)

#Generates week data -- shouldn't be relevant to troubleshoot
by_week <- tibble(Week = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="weeks"),
                  Week_score = c(sample(100:200, 79)),
                  Month = ymd(format(Week, "%Y-%m-01")))

#Generates month data -- shouldn't be relevant to troubleshoot                
by_month <- tibble(Month = seq(as.Date("2011-01-01"), as.Date("2012-07-01"), by="months"),
                   Month_score = c(sample(150:200, 19)))

#Joins data and removes duplications of month data for easier plotting -- shouldn't be relevant to troubleshoot  
all_time <- by_week %>%
  full_join(by_month) %>%
  mutate(helper = across(c(contains("Month")), ~paste(.))) %>% 
  mutate(across(c(contains("Month")), ~ifelse(duplicated(helper), NA, .)), .keep="unused") %>%
  mutate(Month = as.Date(Month))

#Makes plot - this is where I want the order in the legend to be different
all_time %>%
  ggplot(aes(x = Week)) +
  geom_line(aes(y= Week_score, colour = "Week_score")) +
  geom_line(data=all_time[!is.na(all_time$Month_score),], aes(y = Month_score, colour = "Month_score")) + #This line tells R just to focus on non-missing values for Month_score
  scale_colour_discrete(labels = c("Week_score" = "Score - Week", "Month_score" = "Score - Month"), limits = c("Week_score", "Month_score"))

Output:

enter image description here

As you can see the order of the labels is changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文