Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Grouping data on X axis using ggplot

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading