'Arranging bars in multi-panel Lollipop chart using ggplot2

I am trying to plot a multi-panel Lollipop chart using ggplot2 using the following code

#Data
df =structure(list(Indices = c("Time", "Z11", "Z51", "Z61", "Z161", 
"Z251", "Z361", "Z461", "Z561", "Time", "Z31", "Z51", "Z61", 
"Z131", "Z231", "Z251", "Z341", "Z351", "Z461", "Z561"), VIP = c(1, 
0.633198623979687, 0.674275322585927, 0.31516962333157, 0.398880016441834, 
0.464989310628079, 0.157525654949432, 0.527651811310211, 0.204307874098501, 
0.225201314721995, 0.459386037453838, 0.359145104082875, 0.463893290221156, 
0.192967039386417, 0.831690706361273, 0.359429897427331, 1, 0.325583927766342, 
0.955745441016107, 0.355352779693069), Station = c("Alleppey", 
"Alleppey", "Alleppey", "Alleppey", "Alleppey", "Alleppey", "Alleppey", 
"Alleppey", "Alleppey", "East Godavari", "East Godavari", "East Godavari", 
"East Godavari", "East Godavari", "East Godavari", "East Godavari", 
"East Godavari", "East Godavari", "East Godavari", "East Godavari"
)), row.names = c(NA, 20L), class = "data.frame")

#Plotting
ggplot(data=df, aes(Indices, VIP)) +
  geom_segment( aes(xend=Indices, yend=0), color="skyblue", size=1) +
  geom_point( color="blue", size=4, alpha=0.6) + facet_wrap(Station ~ ., scales="free", ncol = 2)+
  theme_bw() +
  coord_flip()

This code is giving me the following plot enter image description here

But I want the y-axis should come in arranged order from highest to lowest. How to do it?



Solution 1:[1]

Here is one possibility (non-dynamic). Make one chart per factor level, and combine them with ggpubr::ggarrange():

p1 <- df[df$Station == "Alleppey",] %>%
  arrange(desc(VIP)) %>%
  mutate(Indices = factor(Indices, levels = rev(unique(Indices)))) %>% 
  ggplot(aes(x = Indices, y = VIP, fill = Station)) +
  geom_segment( aes(xend=Indices, yend=0), color="skyblue", size=1,, show.legend = F) +
  geom_point( color="blue", size=4, alpha=0.6, show.legend = F) +
  facet_wrap(Station ~ ., scales="free", ncol = 2)+
  theme_bw()+
  coord_flip()

p2 <- df[df$Station == "East Godavari",] %>%
  arrange(desc(VIP)) %>%
  mutate(Indices = factor(Indices, levels = rev(unique(Indices)))) %>% 
  ggplot(aes(x = Indices, y = VIP, fill = Station)) +
  geom_segment( aes(xend=Indices, yend=0), color="skyblue", size=1, show.legend = F) +
  geom_point( color="blue", size=4, alpha=0.6, show.legend = F) +
  facet_wrap(Station ~ ., scales="free", ncol = 2)+
  theme_bw() +
  coord_flip()

ggpubr::ggarrange(p1,p2)

Here is an adaption of the solution mentioned by jazzurro from ggplot2 Facet Wrap Reorder by y-axis, Not x-axis.

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}


scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}


df%>%
  ggplot(aes(reorder_within(Indices, VIP, Station), VIP, fill = Station)) +
  geom_point(color="blue", size=4, alpha=0.6, show.legend = F)+
  geom_segment( aes(xend=reorder_within(Indices, VIP, Station), yend=0), color="skyblue", size=1) +
  facet_wrap(Station ~ ., scales="free")+
  labs(x = NULL, y = "VIP") +
  scale_x_reordered()+
  theme_bw() +
  coord_flip()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1