2

I was aiming to create a chart with the following measurements and appearance:

result aimed for

I used tjebos answer to a former question of mine and the answer by stefan to a follow up question tjebo posted to create the following userfunction. I also used information found in this discussion to adjust the legend keys.

library(tidyverse)
library(cowplot)
library(gtable)
library(grid)
library(patchwork)

custom_barplot <- function(dataset, x_value, y_value, fill_value, nfill, xlab, ylab, y_limit, y_steps) {
 # Example color set to choose from
  colors=c("#CF232B","#942192","#000000","#f1eef6","#addd8e","#d0d1e6","#31a354","#a6bddb")
  
  # user function for adjusting the size of key-polygons in legend
  draw_key_polygon2 <- function(data, params, size) {
    lwd <- min(data$size, min(size) / 4)
    
    grid::rectGrob(
      width = grid::unit(0.8, "npc"),
      height = grid::unit(0.8, "npc"),
      gp = grid::gpar(
        col = data$colour,
        fill = alpha(data$fill, data$alpha),
        lty = data$linetype,
        lwd = lwd * .pt,
        linejoin = "mitre"
      ))
}
  # user function for the plot itself
    plot <- function(dataset, x_value, y_value, fill_value, nfill, xlab, ylab, y_limit, y_steps,legend) 
      {ggplot(data=dataset, mapping=aes(x={{x_value}}, y={{y_value}}, fill={{fill_value}})) +
      geom_col(position=position_dodge(width=0.85),width=0.8,key_glyph="polygon2",show.legend=legend) + 
      labs(x=xlab,y=ylab) +
      theme(text=element_text(size=9,color="black"),
            panel.background = element_rect(fill="white"),
            panel.grid = element_line(color = "black",linetype="solid",size= 0.3),
            panel.grid.minor = element_blank(),
            panel.grid.major.x=element_blank(),
            axis.text=element_text(size=9),
            axis.line.x=element_line(color="black"),
            axis.ticks= element_blank(),
            legend.text=element_text(size=9),
            legend.position = "right",
            legend.justification = "top",
            legend.title = element_blank(),
            legend.key.size = unit(4,"mm"),
            legend.key = element_rect(fill="white")) +
      scale_y_continuous(breaks= seq(from=0, to=y_limit,by=y_steps),
                         limits=c(0,y_limit+1), 
                         expand=c(0,0)) +
      scale_fill_manual(values = colors[1:nfill])}
    
    # taking the legend of the plot and removing the first column of the gtable within the legend
    p_legend <- gtable_squash_cols(cowplot::get_legend(plot(dataset, {{x_value}}, {{y_value}}, {{fill_value}},nfill, xlab, ylab, y_limit, y_steps,legend=TRUE)),1)
    
    # printing the plot without legend
    p_main <- plot(dataset, {{x_value}}, {{y_value}}, {{fill_value}}, nfill, xlab, ylab, y_limit, y_steps,legend=FALSE)
    
    #joining it all together
    Obj<- p_main+plot_spacer() + p_legend +
      plot_layout(widths=c(12.5,1.5,4))
    
    return(Obj)
    
}

For the orginal use case I get the result aimed for using this function call: custom_barplot(dataset=data, x_value=county,y_value=Percent, fill_value=Variable, nfill=3, xlab="County",ylab="Percent",y_limit=50, y_steps=5)

But if I change the contents of the plot for example by calling the following arguments there is slightly more space between the legend and the plot than the desired 1.5 cm.

custom_barplot(dataset=data, x_value=Variable,y_value=Percent,fill_value=county, nfill=5, xlab="Variable",ylab="Percent",y_limit=50,y_steps=5)

Could you point me in the right direction to find the underlying reasons? I tried to find the reason with looking at the gtable plots, but did not succeed.

thuettel
  • 165
  • 1
  • 11
  • Just a guess - have you tried setting the margin for each plot to 0? e.g. `theme(plot.margin = margin())` - you could try to pass this globally by adding to the patchwork construct with `& theme(etc.)` – tjebo Apr 13 '21 at 08:01
  • I just tried. The items of the legend moved slightly closer to the plot itself, but the delta of the spaces within plot and legend box remained the same for the two cases. As far as I know there is no padding for the legend. Also within `element_rect()` which is used for the legend keys there is no margin or padding argument. – thuettel Apr 13 '21 at 14:46

0 Answers0