Search code examples
rggplot2bar-chartwidth

How to make ggplot wider, when there are many bars?


I'm using code in the reports, where a graph gets generated. The problem is that sometimes we get just a few categories - then the plot looks very nice, but sometimes many categories and then the plot become unreadable.

I want ggplot to make these graphs wider and I can't figure out how.

Does anybody know how to do that? Below is an example.

enter image description here

Here is a short version of the reproducible example:

tmp_data <- data.frame('topic_main_keyword_category' = c(paste0(c("Avoid Ticks In Dog", "Bedbugs Ticks & Fleas", "Cat & Dog Fleas Difference"), 1:55)), 
                       'topic_search_volume' = sample(seq(10, 550, 10)), 
                       'category_count' = sample(1:55))
multiplier <- max(tmp_data$topic_search_volume) / max(tmp_data$category_count)
            
ggplot(tmp_data) + geom_col(mapping = aes(x = topic_main_keyword_category, y = category_count, fill = topic_main_keyword_category)) +
                      geom_line(group = 1, mapping = aes(x = topic_main_keyword_category, y = topic_search_volume/multiplier),
                                color = 'darkorange1', size=1) + 
                      ylab('Topics count') +
                      xlab('Categories') +
                      ggtitle('Topic categories') +
                      theme_bw(base_size = text_size_on_plots) +
                      scale_fill_viridis(discrete = TRUE) +
                      guides(fill = "none") +
                      scale_y_continuous(
                        sec.axis = sec_axis(~.*multiplier, name = "Search volume", 
                                            labels=function(x) format(x, big.mark = " ", scientific = FALSE))) +
                      theme(axis.text.x = element_text(angle = 90, hjust=1))

EDIT: I wanted to make these plots automatically - meaning that they get saved as png with the proper width without the need of adjusting it manually. In the end I made it like this (although I don't think it is an optimal solution..):

width <- 5 # image width
  if(length(unique(tmp_data$topic_main_keyword_category))<35) { width <- 5}
  if(length(unique(tmp_data$topic_main_keyword_category))>=35 & length(unique(tmp_data$topic_main_keyword_category))<55) { width <- 10}
  if(length(unique(tmp_data$topic_main_keyword_category))>=55 & length(unique(tmp_data$topic_main_keyword_category))<100) { width <- 15}
  if(length(unique(tmp_data$topic_main_keyword_category))>=100) { width <- 25}

  g <-  ggplot(tmp_data) +
          geom_col(mapping = aes(x = topic_main_keyword_category, y = category_count, fill = topic_main_keyword_category)) +
          geom_line(group = 1, mapping = aes(x = topic_main_keyword_category, y = topic_search_volume/multiplier),
                    color = 'darkorange1', size=1) + 
          ylab('Topics count') +
          xlab('Categories') +
          ggtitle('Topic categories') +
          theme_bw(base_size = text_size_on_plots) +
          scale_fill_viridis(discrete = TRUE) +
          guides(fill = "none") +
          scale_y_continuous(
            sec.axis = sec_axis(~.*multiplier, name = "Search volume", 
                                labels=function(x) format(x, big.mark = " ", scientific = FALSE))) +
          theme(axis.text.x = element_text(angle = 90, hjust=1))
  ggsave('Topics_categories.png', plot = g, width=width)

Solution

  • Have you tried to resize the plot window (e.g., clicking the "zoom" button in the plot pane in RStudio and then dragging the borders) and the save the image? This is the result I get, it seems acceptable to me:

    enter image description here

    If you want the get the image programmatically, you can save it using ggsave setting the width= option to an adequate value.