Need help formatting a ggplot

Hello,

I am having trouble formatting my ggplot2 into the desired plot. How do I make the name of the animals tagged next to their respective line in the slope plot rather than having a legend on the right hand side. I would also like to remove all the excess gap thats outside 2013-2018 as it makes the graph look funny.
This is my current graph:
Rplot
This is my desired graph:
image

I have attached my code on the bottom. Any help would be appreciated!

data1 <- data_frame(
  Animal = c("Bird", "Elephant", "Lion", "Duck", "Crocodile"),
  year2013 = c(295,353,201,74,423),
  year2018 = c(218,471,205,61,475)
)

data1 %>%
  ggplot(aes(x="2013", xend="2018", y=year2013, yend=year2018,
             group=Animal, color=Animal))+
  geom_segment()+
  labs(title= "Number of Animals in the Zoo",
       subtitle = "Change between 2013 and 2018",
       x = "Year",
       y = "Frequency",
       color = "")+
  theme_classic()

I would really recommend formatting your data in a long format - you currently have the variable "year" embedded in column names. Here is a solution that puts data in long format and then creates your desired plot.


library(ggplot2)

data1 <- data_frame(
    Animal = c("Bird", "Elephant", "Lion", "Duck", "Crocodile"),
    year2013 = c(295,353,201,74,423),
    year2018 = c(218,471,205,61,475)
)

### New code starts here

library(tidyr)

data2 <- data1 %>% 
    pivot_longer(cols = 2:3) %>% 
    mutate(
        year = gsub('year', '', name) %>% 
            as.numeric
    ) %>% 
    select(-name)

data2 %>% 
    ggplot(
        aes(x = year, y = value, group = Animal)
    ) +
    geom_line(
        aes(
            color = Animal
        )
    ) + 
    geom_text(
        aes(
            label = Animal,
            
        ),
        data = data2 %>% 
            filter(year == 2013),
        nudge_x = -0.1
    ) + 
    geom_text(
        aes(
            label = Animal
        ),
        data = data2 %>% 
            filter(year == 2018),
        nudge_x = 0.1
    ) + 
    scale_x_continuous(
        breaks = c(2013, 2018)
    ) +
    labs(
        title = 'Number of Animals in the Zoo',
        subtitle = 'Change between 2013 and 2018',
        x = 'Year',
        y = 'Frequency',
        color = ''
    ) + 
    theme_classic() + 
    theme(
        legend.position = 'none'
    )

Hi dvetsch75,

Thank you for your recommendation - I never thought to do it this way. Is there a way to make the text not overlap each other on the year 2018?

One option would be using ggplot2::position_dodge like so:

geom_text(
    aes(
      label = Animal,
      group = Animal
    ),
    data = data2 %>% 
      filter(year == 2018),
    position = position_dodge(width = 0.5)
  )

Hi dvetsch,

I am required to utilise the text annotation function for my project. I was wondering how would I be able to colour the lines as the same colour of the text? I have attached the current graph along with the desired and my code. Thanks!

data1 <- data_frame(
  Animal = c("Bird", "Elephant", "Lion", "Duck", "Crocodile"),
  year2013 = c(295,353,201,74,423),
  year2018 = c(218,471,205,61,475)
)

### New code starts here

library(tidyr)

data2 <- data1 %>% 
  pivot_longer(cols = 2:3) %>% 
  mutate(
    year = gsub('year', '', name) %>% 
      as.numeric
  ) %>% 
  select(-name)

animalsinthezoo <- data2 %>% 
  ggplot(aes(x = year, y = value, group = Animal)) +
  geom_line(aes(color = Animal),lwd=1.5) + 
  geom_text(aes(label = "",group = ""),
            data = data2 %>% 
              filter(year == 2013),
            position = position_dodge( width = 1, )) + 
  geom_text(aes(label = ""),
            data = data2 %>% 
              filter(year == 2018),
            nudge_x = 0.1) + 
  scale_x_continuous(breaks = c(2013, 2018)) +
  labs(title = 'Number of Animals in the Zoo',
       x = 'Year',
       y = 'Frequency',
       caption = "Data from Australia Zoo")+ 
  theme_classic()+
  theme(text = element_text(family = "montserrat"),
        plot.title = element_markdown(size=16, face = "bold",),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size=14),
        plot.caption = element_markdown(size=10),
        legend.position ='none')

animalsinthezoo + annotate("text", x = 2012.6, y = 420, label = "Crocodile", family = "montserrat", col="darkred")+
  annotate("text", x = 2012.6, y = 350, label = "Elephant", family = "montserrat", col="red")+
  annotate("text", x = 2012.6, y = 300, label = "Bird", family = "montserrat", color="#1a1919")+
  annotate("text", x = 2012.6, y = 200, label = "Lion", family = "montserrat", color="#1a1919")+
  annotate("text", x = 2012.6, y = 80, label = "Duck", family = "montserrat", color="#1a1919")
animalsinthezoo

I would just use ggrepel:

library(tidyr)
library(ggplot2)
library(dplyr)
library(ggtext)
library(ggrepel)

data1 <- data.frame(
Animal = c("Bird", "Elephant", "Lion", "Duck", "Crocodile"),
year2013 = c(295,353,201,74,423),
year2018 = c(218,471,205,61,475)
)

data2 <- data1 %>%
pivot_longer(cols = 2:3) %>%
mutate(
year = gsub('year', '', name) %>%
as.numeric
) %>%
select(-name)

data2 %>%
ggplot(aes(x = year, y = value, group = Animal)) +
geom_line(aes(color = Animal),lwd=1.5) +
geom_text_repel(aes(label=Animal,color=Animal),hjust="inward")+
scale_x_continuous(breaks = c(2013, 2018)) +
labs(title = 'Number of Animals in the Zoo',
x = 'Year',
y = 'Frequency',
caption = "Data from Australia Zoo")+
theme_classic()+
theme(text = element_text(family = "montserrat"),
plot.title = element_markdown(size=16, face = "bold",),
axis.ticks.y = element_blank(),
axis.title.x = element_text(size=14),
plot.caption = element_markdown(size=10),
legend.position ='none')

You use ggrepel for separating the two labels or for some other purpose also...?

Please start a new question if this is a new use case.
ggrepel has many features and use cases what is exactly your new question?

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.