0

I'm trying to plot the GDP for every country on a bar chart. The country name goes on the x-axis and the GDP value on the y. However, there are a lot of countries, and I'd like the bar chart to just show the top 3 GDPs, and the bottom 3 GDPs and in between I want perhaps some dots or something to indicate that there are other countries in between. How do I go about this?

Barry
  • 105
  • 4

2 Answers2

3

Building on @steveLangsford's solution - doing things in a (possibly) slightly more principled way

There might be a more "tidy" way to do this part:

  • find breakpoints for GDP categories:
GDP_sorted <- sort(toydata$GDP)
GDP_breaks <- c(-Inf,GDP_sorted[hm_selected],
                 GDP_sorted[hm_rows-hm_selected],
                Inf)
  • use cut()to define GDP categories, and order countries by GDP:
toydata <- toydata %>%
  mutate(GDP_cat=cut(GDP,breaks=GDP_breaks,labels=
                       c("Lowest","Mid","Highest")),
         country=reorder(factor(country),GDP)) %>%
  filter(GDP_cat != "Mid") %>%
  droplevels()

Plot with facets (add a bit of extra space between the panels to emphasize the axis break):

ggplot(toydata,aes(x=country,y=GDP,fill=GDP_cat))+
  geom_bar(stat="identity")+
  theme_bw()+
  theme(legend.position="none",
    panel.spacing.x=grid::unit(5,"lines")
  )+xlab("")+
  scale_fill_brewer(palette="Dark2")+
  facet_wrap(~GDP_cat,scale="free_x")

enter image description here

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
2

1) You will get faster better answers if you give a toy data set
2) Putting "dots or something" on your plot is likely to make data visualization people wince a little. You're basically suggesting a discontinuity in the x-axis, which is a common enough thing to do, but specifically excluded from ggplot (see here: Using ggplot2, can I insert a break in the axis? and here: https://groups.google.com/forum/#!topic/ggplot2/jSrL_FnS8kc)

But, this same discussion suggests facets as a solution to your problem. One way to do that might be something like this:

library(tidyverse)
library(patchwork)
hm_rows <- 50
hm_selected <- 3
toydata <- data.frame(country=paste("Country",1:hm_rows) ,GDP=runif(hm_rows,0,5000))%>%
    arrange(desc(GDP))%>%
    filter(row_number()<=hm_selected | row_number()>(hm_rows-hm_selected))%>%droplevels

toydata$status <- rep(c("Highest","Lowest"),each=hm_selected)

ggplot(toydata%>%filter(status=="Highest"),aes(x=country,y=GDP))+
    geom_bar(stat="identity")+
    ggtitle("Highest")+
    ylim(c(0,max(toydata$GDP)))+
    ggplot(toydata%>%filter(status=="Lowest"),aes(x=country,y=GDP))+
    geom_bar(stat="identity")+
    ggtitle("Lowest")+
    ylim(c(0,max(toydata$GDP)))+
    theme(#possibly questionable, but tweaks the results closer to the single-graph requested:
        axis.text.y=element_blank(),
        axis.ticks=element_blank()
    )+ylab("")
steveLangsford
  • 646
  • 5
  • 9
  • 1
    note `devtools::install_github("thomasp85/patchwork")` ... why are you using `patchwork` rather than ordinary faceting? – Ben Bolker Mar 11 '18 at 16:33
  • Ordinary faceting keeps the x-axis consistent across the facets. Patchwork let me have country A ,B, C for the x-axis in the left panel and country X, Y, Z on the right. There might be better ways but this was quickest/easiest for me. Thanks for commenting the github install, I forgot about that! – steveLangsford Mar 11 '18 at 16:45
  • See my solution (`scale=="free_x"`) – Ben Bolker Mar 11 '18 at 16:47
  • Oh, that is nice. Didn't know about that, thanks for pointing it out! – steveLangsford Mar 11 '18 at 16:54