MisBlearnsR
MisBlearnsR

Reputation: 29

How to reorder bars in the chart and the legend

I'm struggling to reorder the bars in the plot and the legend, following the data structure (SD,MB,FI,FO,NP). Here is my data;

    Data <- tibble::tribble(
  ~Year,    ~SD,    ~MB,      ~FI,       ~FO,       ~NP,
  "2010",   41,     36.7,    10.2,        5.3,     6.8,
  "2011",   49.1,   50.9,    NA,          NA,      NA,
  "2012",   41.1,   32.4,    11.4,        8.6,     6.4,
  "2013",   38.9,   29.6,    10,          13.7,    7.7,
  "2014",   38.8,   36.5,    5.2,         10.4,    9,
  "2015",   43.4,   39.1,    NA,          11.9,    5.5, 
  "2016",   40.6,   38,      10.5,        8.8,     2.2,
  "2017",   38.3,   42.3,    9.7,         6.8,     2.9,
  "2018",   37.8,   40.3,    9.3,         10.6,    2,
  "2019",   33.8,   41.6,    8.1,         14.2,    2.3

)

The code;

    Data %>%
  pivot_longer(-Year) %>% 
  ggplot(aes(x = Year, y = value, fill = name, reorder(TRUE))) +  ylab("Students") +
  xlab("Year") +
  geom_bar(stat = "identity", position = "dodge") +
  facet_wrap(~ Year, scales = 'free_x', ncol = 10, strip.position = "bottom") +
  theme_minimal() +
  theme(axis.title.x=element_blank(),
         axis.text.x=element_blank(),
         axis.ticks.x=element_blank()+
   theme(strip.placement  = "outside",
         panel.spacing    = unit(0, "points"),
        axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        strip.background = element_blank(),
        strip.background.y = element_blank(),
        panel.background = element_rect(fill = "white"),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(), 
        strip.text       = element_text(face = "bold", size = 9)) +
   scale_fill_continuous(name = "Legend", label = c("SD","MB","FI","FO","NP", ordered(TRUE))) + 
   theme(legend.position = "right", axis.text.x = element_text(angle = 90,vjust = 0.4)))

thank you in advance.

Here is the edit on the code:

The csv file is here: https://1drv.ms/x/s!AjskoWp__th-kEJOld80Tb0Bxx-C?e=JoSmGf

Rtutorial <- read.csv("C:Desktop/statistics/Rtutorial.csv", header=TRUE)

Rtutorial<-as.data.frame(Rtutorial)

library(ggplot2)
library(tidyr)
library(dplyr)

Rtutorial %>%

  pivot_longer(c(-Year, -Total))) %>%

  mutate(name = factor(name, levels=c('Total',
                                      'Sable-Antelope',
                                      'Monkey',
                                      'Frogs and reed buck',
                                      'Fox and jackals',
                                      'Side striped jackal'
                                    ))) %>%

  ggplot(aes(x=as.factor(Year), y=value, fill=name, reorder(TRUE))) +
  scale_y_continuous(labels = scales::comma_format()) +
  ylab("Total Population") +
  xlab("Year") +
  labs(fill="Legend") + 
  geom_bar(stat = "identity", position = "dodge") +
  theme_classic() +
  theme(strip.placement  = "outside",
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank() ,
    legend.position = "right", 
    axis.text.x = element_text(angle = 0, vjust = 0)) +
  scale_fill_brewer(palette = "Greens", name = "Legend", label=c('Total 
Population','Sable-Antelope','Monkey','Frogs and reed buck','Fox and 
jackals','Side striped jackal', ordered(T)) + 
theme(legend.position = "right", axis.text.x = element_text(angle = 
90,vjust = 0.4)))

I still get errors when I run the code, I tried looking at several examples on stackoverflow and couldn't see where the problem is.

One of the errors I get is with Error in factor - name.

Upvotes: 1

Views: 68

Answers (1)

DaveArmstrong
DaveArmstrong

Reputation: 22072

If you put this line:

  mutate(name = factor(name, levels=c("SD","MB","FI","FO","NP"))) %>%

after your pivot_longer(-Year) function, it should work. This will make the variable name into a factor with the levels ordered as you want.

Data %>%
  pivot_longer(-Year) %>% 
  mutate(name = factor(name, levels=c("SD","MB","FI","FO","NP"))) %>%
  ggplot(aes(x = Year, y = value, fill = name, reorder(TRUE))) +  ylab("Students") +
  xlab("Year") +
  geom_bar(stat = "identity", position = "dodge") +
  facet_wrap(~ Year, scales = 'free_x', ncol = 10, strip.position = "bottom") +
  theme_minimal() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank()+
          theme(strip.placement  = "outside",
                panel.spacing    = unit(0, "points"),
                axis.title.x=element_blank(),
                axis.text.x=element_blank(),
                axis.ticks.x=element_blank(),
                strip.background = element_blank(),
                strip.background.y = element_blank(),
                panel.background = element_rect(fill = "white"),
                panel.grid.major = element_blank(),
                panel.grid.minor = element_blank(),
                panel.border = element_blank(), 
                strip.text       = element_text(face = "bold", size = 9)) +
          scale_fill_continuous(name = "Legend", label = c("SD","MB","FI","FO","NP", ordered(TRUE))) + 
          theme(legend.position = "right", axis.text.x = element_text(angle = 90,vjust = 0.4)))

enter image description here


EDIT - answer comment below.

You could streamline the function a bit, like the following:

Data <- tibble::tribble(
  ~Year,    ~`Sable-Antelope`,    ~`Monkey`,      ~`Frogs and reed buck`,       ~`Fox and jackals`,       ~`Side striped jackal`,
  "2010",   41,     36.7,    10.2,        5.3,     6.8,
  "2011",   49.1,   50.9,    NA,          NA,      NA,
  "2012",   41.1,   32.4,    11.4,        8.6,     6.4,
  "2013",   38.9,   29.6,    10,          13.7,    7.7,
  "2014",   38.8,   36.5,    5.2,         10.4,    9,
  "2015",   43.4,   39.1,    NA,          11.9,    5.5, 
  "2016",   40.6,   38,      10.5,        8.8,     2.2,
  "2017",   38.3,   42.3,    9.7,         6.8,     2.9,
  "2018",   37.8,   40.3,    9.3,         10.6,    2,
  "2019",   33.8,   41.6,    8.1,         14.2,    2.3)


Data %>%
  pivot_longer(-Year) %>% 
  mutate(name = factor(name, levels=c("Sable-Antelope",
                                      "Monkey",
                                      "Frogs and reed buck",
                                      "Fox and jackals",
                                      "Side striped jackal"))) %>%
  ggplot(aes(x = Year, y = value, fill = name)) +  
  ylab("Students") +
  xlab("Year") +
  labs(fill="Legend") + 
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_brewer(palette="Greens") +  
  theme_minimal() +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank() ,
    legend.position = "right", 
    axis.text.x = element_text(angle = 0, vjust = 7.5))```

enter image description here


EDIT 2 - Using updated data and syntax.

There were a couple of things that prevented your code from running.

  1. It looks like you want the Total group in the plot as well, so you shouldn't select it out in the pivot_longer() function.
  2. There was an extra parenthesis at the end of the pivot_longer()
  3. When you use read.csv() spaces in variable names are replaces with periods, so the levels you're specifying won't work. You'll have to specify the levels as the names with periods and the labels as the names with spaces instead of periods.
  4. While less problematic, the second theme() call overrides things in the first theme() call. These could be combined.

The code below solves these problems.

Rtutorial %>%
  
  pivot_longer(c(-Year)) %>%
  
  mutate(name = factor(name, levels=c('Total',
                                       'Sable.Antelope',
                                       'Monkey',
                                       'Frogs.and.reed.buck',
                                       'Fox.and.jackals',
                                       'Side.striped.jackal'), 
                             labels=c('Total',
                                      'Sable-Antelope',
                                      'Monkey',
                                      'Frogs and reed buck',
                                      'Fox and jackals',
                                      'Side striped jackal'))) %>%
  
  ggplot(aes(x=as.factor(Year), y=value, fill=name, reorder(TRUE))) +
  scale_y_continuous(labels = scales::comma_format()) +
  ylab("Total Population") +
  xlab("Year") +
  labs(fill="Legend") + 
  geom_bar(stat = "identity", position = "dodge") +
  theme_classic() +
  theme(strip.placement  = "outside",
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank() ,
        legend.position = "right", 
        axis.text.x = element_text(angle = 90,vjust = 0.4)) +
  scale_fill_brewer(palette = "Greens", name = "Legend")  

enter image description here

Upvotes: 2

Related Questions