Home > Back-end >  Grouping data on X axis using ggplot
Grouping data on X axis using ggplot

Time:06-28

I have a simple dataset:

myData<-structure(list(Name = c("Rick", "Rick", "Rick", "Rick", "Rick", 
"Rick", "Rick", "Rick", "Jane", "Jane", "Jane", "Jane", "Jane", 
"Jane", "Jane", "Jane", "Ellen", "Ellen", "Ellen", "Ellen", "Ellen", 
"Ellen", "Ellen", "Ellen"), City = c("Boston", "Boston", "Boston", 
"Boston", "Seattle", "Seattle", "Seattle", "Seattle", "Boston", 
"Boston", "Boston", "Boston", "Seattle", "Seattle", "Seattle", 
"Seattle", "Boston", "Boston", "Boston", "Boston", "Seattle", 
"Seattle", "Seattle", "Seattle"), Transport = c("Car", "Train", 
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane", "Car", "Train", 
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane", "Car", "Train", 
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane"), Time = c(0L, 
1L, 0L, 9L, 0L, 0L, 3L, 7L, 1L, 3L, 2L, 0L, 0L, 2L, 3L, 0L, 1L, 
3L, 3L, 4L, 8L, 4L, 7L, 7L)), class = "data.frame", row.names = c(NA, 
-24L))

I want a ggplot that looks in this way: City on the X axis, Time on Y axis, and the value of each column filled with the different transport. But I would like to have the data on the X axis also grouped by person. So far I've wrote:

city<-as.factor(myData$City) 
Transport<-myData$Transport 
time<-myData$Time

p<-ggplot(myData, 
          aes(x=city,
              y=time,
              fill=Transport))  
  geom_bar(position="dodge", 
           stat="identity")   
  scale_color_viridis(discrete = TRUE) 
  scale_fill_viridis(discrete = TRUE)  
  scale_x_discrete(breaks = waiver(),
                   limits=NULL)  
  scale_y_continuous(limits = c(0, 10), 
                     breaks = seq(0, 10, by = 1))  
  xlab("City")   
  ylab("Time")  
  ggtitle("People")  
  theme(axis.line = element_blank(),
        axis.text.x=element_text(size=14,
                                 margin=margin(b=10),
                                 colour="black"),
        axis.text.y=element_text(size=14,
                                 margin=margin(l=10),
                                 colour="black"),
        axis.ticks = element_blank(),
        axis.title=element_text(size=18,
                                face="bold"),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        plot.title = element_text(size=18,
                                  hjust=0.5), 
        legend.text = element_text(size=14),
        legend.title = element_text(size=18))
p

I cannot figure out how to group data on the X axis based on the person's name. I tried to use group=name (both using name<-myData$name and name<-as.factor(myData$Name)) inside and outside aes() but it is not working. I don't know if this plot has sense or if there is a better way to visualize this, but I wanted to try.

CodePudding user response:

It sounds as though you are looking for a nested categorical x axis. You do can do this using the 'facet that doesn't look like a facet' trick, which works particularly well with the styling you have chosen.

A few other points to consider:

  1. You don't need to make a copy of the vectors you want to use out of your data frame. You can use the names of the columns in your data frame directly in ggplot
  2. geom_bar(stat = "identity") is just a long way of writing geom_col()
  3. You haven't mapped the color aesthetic, so scale_color_viridis doesn't do anything
  4. You can save some time and space by using labs, and setting your x, y, and title labels there in a single call.
  5. Your scale_x_discrete wasn't changing anything in the plot and can be removed.
  6. Instead of setting every single theme parameter, start with a theme that is close to the one you want, then only changing what you need to. Remember, the more things you have to explicitly code, the harder your script gets to read and debug.

Putting all these together, we have:

ggplot(myData, aes(Name, Time, fill = Transport))  
  geom_col(position = "dodge")   
  scale_fill_viridis_d()  
  scale_y_continuous(limits = c(0, 10), breaks = 0:10)  
  labs(x = "City", y = "Time", title = "People")   
  facet_grid(. ~ City, switch = 'x')  
  theme_minimal(base_size = 14)  
  theme(strip.placement = 'outside',
        strip.background = element_blank(),
        strip.text = element_text(size = 15, face = 'bold'),
        axis.ticks = element_blank(),
        axis.title = element_text(size = 18, face = "bold"),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),
        plot.title = element_text(size = 18, hjust = 0.5, face = 'bold'))

enter image description here

  • Related