Skip to main content
Stack Overflow
  1. About
  2. For Teams

Return to Answer

Post Timeline

added 466 characters in body
Source Link
L Tyrone
  • 8.4k
  • 23
  • 34
  • 47
library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
toy_data# Map list of colours to columns
col_map <- tibblec(
 fyv1 = c("2019""blue", "2020", "2022",v2 "2023",= "2024")"purple",
 v1v3 = "darkgreen"
)
# Pivot to long form
toy_data <- toy_data %>%
 pivot_longer(-c(0.0438688113641111fy, 0.052572706935123,id))
head(toy_data)
# 0.0111137572437882,# 0.0118893212278426,A tibble: 6 ×ばつ 4
# fy id name value
# <chr> <dbl> <chr> <dbl>
# 1 2019  1 v1 0.01225),0439
# 2 2019  1 v2 = c(0.0411,
# 0.0741,3 0.1075,2019 0.0255, 0.0244),
 1 v3 = c(0.42359475940349, 0.40169349585931, 0.279370529327611,424 
# 4 2020 1 v1 0.324827447947991,0526
# 5 2020 1 v2  0.344568567026194),0741
# 6 id2020 = c(1, 1, 1, 1, 1)
) v3 0.402
# Convert fy to numeric
toy_data$fy <- as.numeric(toy_data$fy)
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -0.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = 0.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map) +
 scale_x_continuous(expand = expansion(add = c(0.75, 0.75)),
 breaks = 2019:2024) +
 guides(colour = guide_legend(override.aes = list(label = "")))
library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
toy_data <- tibble(
 fy = c("2019", "2020", "2022", "2023", "2024"),
 v1 = c(0.0438688113641111, 0.052572706935123, 0.0111137572437882, 0.0118893212278426, 0.01225),
 v2 = c(0.0411, 0.0741, 0.1075, 0.0255, 0.0244),
 v3 = c(0.42359475940349, 0.40169349585931, 0.279370529327611, 0.324827447947991, 0.344568567026194),
 id = c(1, 1, 1, 1, 1)
)
# Convert fy to numeric
toy_data$fy <- as.numeric(toy_data$fy)
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = .25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map) +
 scale_x_continuous(expand = expansion(add = c(0.75, 0.75)),
 breaks = 2019:2024) +
 guides(colour = guide_legend(override.aes = list(label = "")))
library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
# Map list of colours to columns
col_map <- c(
 v1 = "blue", v2 = "purple",
 v3 = "darkgreen"
)
# Pivot to long form
toy_data <- toy_data %>%
 pivot_longer(-c(fy, id))
head(toy_data)
# # A tibble: 6 ×ばつ 4
# fy id name value
# <chr> <dbl> <chr> <dbl>
# 1 2019  1 v1 0.0439
# 2 2019  1 v2 0.0411
# 3 2019 1 v3 0.424 
# 4 2020 1 v1 0.0526
# 5 2020 1 v2  0.0741
# 6 2020 1 v3 0.402
# Convert fy to numeric
toy_data$fy <- as.numeric(toy_data$fy)
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -0.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = 0.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map) +
 scale_x_continuous(expand = expansion(add = c(0.75, 0.75)),
 breaks = 2019:2024) +
 guides(colour = guide_legend(override.aes = list(label = "")))
added 398 characters in body
Source Link
L Tyrone
  • 8.4k
  • 23
  • 34
  • 47

As alluded to by Greg Snow, it is better to format your data to work for ggplot2 rather than trying to make ggplot2 work for your data. If you combine your V* data into a single column, then you only have to call each geom_*() once.

To do this, you can pivot your data to long form using tidyr::pivot_longer(). I have also created a named list for assigning colour values. Your example plot only has labels at the first and last value so I modified the filter() for geom_text_repel(), edit to suit.

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently. It also makes sense to convert your fy values to numeric. Currently 2021 is not showing which makes the plot 'lie' as years are actually continuous variables.

library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
toy_data <- tibble(
 fy = c("2019", "2020", "2022", "2023", "2024"),
 v1 = c(0.0438688113641111, 0.052572706935123, 0.0111137572437882, 0.0118893212278426, 0.01225),
 v2 = c(0.0411, 0.0741, 0.1075, 0.0255, 0.0244),
 v3 = c(0.42359475940349, 0.40169349585931, 0.279370529327611, 0.324827447947991, 0.344568567026194),
 id = c(1, 1, 1, 1, 1)
)
# Map list of colours to columns
col_map <- c(
 v1 = "blue",
 v2 = "purple",
  v3 = "darkgreen"
)
#Convert Pivotfy to long formnumeric
toy_datatoy_data$fy <- toy_data %>%
 pivot_longer(-c(fy, id))
headas.numeric(toy_datatoy_data$fy)
# # A tibble: 6 ×ばつ 4
# fy id name value
# <chr> <dbl> <chr> <dbl>
# 1 2019 1 v1 0.0439
# 2 2019 1 v2 0.0411
# 3 2019 1 v3 0.424 
# 4 2020 1 v1 0.0526
# 5 2020 1 v2 0.0741
# 6 2020 1 v3 0.402
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() %in%== c(1, n()), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "y""both",
 min.segment.length = Inf,
 fontface = 'bold',
 seed = 102) +
 scale_colour_manual(name = "Values",
  values = col_map)

Plot produced by answer code showing points and lines mapped to colours from list

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently:

toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repelscale_colour_manual(dataname = toy_data %>% "Values",
 filter(row_number() == n(), .byvalues = namecol_map), +
 aesscale_x_continuous(fy, value, group = name, colourexpand = name, 
  labelexpansion(add = paste0c(as0.character(round(value * 100, 2))75, "%"0.75)),
 nudge_x = .25,
  direction = "both",
 min.segment.length = Inf,
 fontfacebreaks = 'bold'2019:2024) +
 scale_colour_manualguides(namecolour = "Values",
  guide_legend(override.aes = valueslist(label = col_map"")))

Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls

As alluded to by Greg Snow, it is better to format your data work for ggplot2 rather than trying to make ggplot2 work for your data. If you combine your V* data into a single column, then you only have to call each geom_*() once.

To do this, you can pivot your data to long form using tidyr::pivot_longer(). I have also created a named list for assigning colour values. Your example plot only has labels at the first and last value so I modified the filter() for geom_text_repel(), edit to suit.

library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
toy_data <- tibble(
 fy = c("2019", "2020", "2022", "2023", "2024"),
 v1 = c(0.0438688113641111, 0.052572706935123, 0.0111137572437882, 0.0118893212278426, 0.01225),
 v2 = c(0.0411, 0.0741, 0.1075, 0.0255, 0.0244),
 v3 = c(0.42359475940349, 0.40169349585931, 0.279370529327611, 0.324827447947991, 0.344568567026194),
 id = c(1, 1, 1, 1, 1)
)
# Map list of colours to columns
col_map <- c(
 v1 = "blue",
 v2 = "purple",
  v3 = "darkgreen"
)
# Pivot to long form
toy_data <- toy_data %>%
 pivot_longer(-c(fy, id))
head(toy_data)
# # A tibble: 6 ×ばつ 4
# fy id name value
# <chr> <dbl> <chr> <dbl>
# 1 2019 1 v1 0.0439
# 2 2019 1 v2 0.0411
# 3 2019 1 v3 0.424 
# 4 2020 1 v1 0.0526
# 5 2020 1 v2 0.0741
# 6 2020 1 v3 0.402
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() %in% c(1, n()), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "y",
 min.segment.length = Inf,
 fontface = 'bold',
 seed = 102) +
 scale_colour_manual(name = "Values",
  values = col_map)

Plot produced by answer code showing points and lines mapped to colours from list

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently:

toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
  label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = .25,
  direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
  values = col_map)

Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls

As alluded to by Greg Snow, it is better to format your data to work for ggplot2 rather than trying to make ggplot2 work for your data. If you combine your V* data into a single column, then you only have to call each geom_*() once.

To do this, you can pivot your data to long form using tidyr::pivot_longer(). I have also created a named list for assigning colour values. Your example plot only has labels at the first and last value so I modified the filter() for geom_text_repel(), edit to suit.

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently. It also makes sense to convert your fy values to numeric. Currently 2021 is not showing which makes the plot 'lie' as years are actually continuous variables.

library(tidyr)
library(dplyr)
library(ggplot2)
library(ggrepel)
toy_data <- tibble(
 fy = c("2019", "2020", "2022", "2023", "2024"),
 v1 = c(0.0438688113641111, 0.052572706935123, 0.0111137572437882, 0.0118893212278426, 0.01225),
 v2 = c(0.0411, 0.0741, 0.1075, 0.0255, 0.0244),
 v3 = c(0.42359475940349, 0.40169349585931, 0.279370529327611, 0.324827447947991, 0.344568567026194),
 id = c(1, 1, 1, 1, 1)
)
# Convert fy to numeric
toy_data$fy <- as.numeric(toy_data$fy)
toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = .25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map) +
 scale_x_continuous(expand = expansion(add = c(0.75, 0.75)),
 breaks = 2019:2024) +
 guides(colour = guide_legend(override.aes = list(label = "")))

Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls

added 1538 characters in body
Source Link
L Tyrone
  • 8.4k
  • 23
  • 34
  • 47

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently:

toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = .25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map)

Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls

If you are only intending to plot just the first and last value for each V*, it can be easier to use two geom_text_repel() calls to control each side independently:

toy_data %>%
 filter(id == 1) %>% 
 ggplot() +
 geom_line(aes(fy, value, group = name, colour = name), 
 linewidth = 2) +
 geom_point(aes(fy, value, group = name, colour = name), 
 size = 2, 
 shape = 21, 
 fill = "white") +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == 1, .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = -.25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 geom_text_repel(data = toy_data %>% 
 filter(row_number() == n(), .by = name), 
 aes(fy, value, group = name, colour = name, 
 label = paste0(as.character(round(value * 100, 2)), "%")),
 nudge_x = .25,
 direction = "both",
 min.segment.length = Inf,
 fontface = 'bold') +
 scale_colour_manual(name = "Values",
 values = col_map)

Plot produced by answer code showing points and lines mapped to colours from list with two separate geom_text_repel() calls

Source Link
L Tyrone
  • 8.4k
  • 23
  • 34
  • 47
Loading
lang-r

AltStyle によって変換されたページ (->オリジナル) /