How to set width of y axis labels in ggplot2

I collected the histograms in ggplot2 and used ImageMagick to animate them into gifs. animated gif of graphics made in ggplot2 The idea is that on all graphs it is assumed that the scale along the x axis will be the same, but this is not entirely true because the y axis is shifted around due to the different widths of the marks. How can I snap a graph so that all graphs have exactly the same axis position?

Here is my ggplot code if it helps:

hist.fn<-function(tier,ddf){
    df<-ddf[ddf$tier==tier,]
    l<-match(tier,levels(df$tier))
    hist.png<-ggplot(df,aes(df$"Premium Adult Individual Age 40" ))+
    geom_histogram()+   
    labs(title=paste0(tier," premiums in federal exchanges"),
            x ="Premium", y = "Frequency")+
    coord_cartesian(xlim=c(0, 1500))+
        theme_bw()+
        theme(text = element_text(size=14), plot.title = element_text(face="bold"),axis.title.x =element_text(face="bold"),axis.title.y =element_text(face="bold"))
    file=paste0(l,"hist.jpg")

    ggsave(filename=file, plot=hist.png, width=13, height=8, dpi=50)
    return(hist.png)
}
data.df$tier%>% levels %>% lapply(FUN=hist.fn,ddf=data.df) ->histograms.of.tiers    

system("magick -delay 75 *hist.jpg hist.gif")
+4
source share
2 answers

, , - y. , . y .

library(ggplot2)
library(gridExtra)
library(stringr)

# Generate plots 
# For each Species in iris dataset - generate a histogram of the Petal length
plots = lapply(levels(iris$Species), 
               function(spec){
                 ggplot(iris[iris$Species == spec, ], aes(Petal.Length)) + 
                   geom_histogram() + 
                   ggtitle(spec)
               })

# Show plots side by side 
grid.arrange(grobs = plots, nrow = 1, ncol = 3, top = "Base\n\n")

base_plots

.
,

# Solution 1 (recommended) - Set the same y-axis range for all the plots 
alignLimits = function(plotsList){
  # Extract limits of y-axis for each plot
  y.limits = sapply(plotsList, function(.){layer_scales(.)$y$range$range})
  y.min = min(y.limits[1,]) # Minimum of all the ranges
  y.max = max(y.limits[2,]) # Maximum of all the ranges 

  # Apply new limits for each plot
  return(lapply(plotsList, 
                function(.){. + coord_cartesian(ylim=c(y.min, y.max))}))
}

# Align limits of original plots and display
plots.limits = alignLimits(plots)
grid.arrange(grobs = plots.limits, nrow = 1, ncol = 3, top = "Aligned limits\n\n")

limits

.


, , :

# Use whitespaces to pad 
alignLables = function(plotsList){
  # Extract labels of y-axis
  # Note: Don't use the as.character on the maximum limit, 
  #       as decimal places in labels may increase the character count 
  y.labels = lapply(plotsList, function(.){ggplot_build(.)$layout$panel_ranges[[1]]$y.labels}) 

  # Calculate the maximum number of characters for each plot labels
  maxChars = sapply(y.labels, function(.){max(nchar(.))})

  # Define a function that would space-pad the labels and apply
  format.labels = function(label){str_pad(label, max(maxChars), pad = " ")}
  return(lapply(plotsList, function(.){return(. + scale_y_continuous(labels = format.labels))}))
}

# Align labels of original plots and display
plots.labels = alignLables(plots)
grid.arrange(grobs = plots.labels, nrow = 1, ncol = 3, top = "Aligned labels\n\n")

labels

, - .

+4

gtable ,

library(ggplot2)
library(grid)
library(gridExtra)

plot_random <- function(){
  ggplot() +
    labs(y=paste(letters[sample(1:24, sample(1:3))], collapse = "\n"))
}

pl <- replicate(3, plot_random(), simplify = FALSE)
gl <- lapply(pl, ggplotGrob)
wl <- lapply(gl, function(g) g$widths[2])
wmax <- do.call(unit.pmax, wl)
gl <- lapply(gl, function(g) {g$widths[2] <- wmax; g})

grid.arrange(arrangeGrob(grobs = pl, top = "Normal case"),
             arrangeGrob(grobs = gl, top = "Standardised left"))
+2

Source: https://habr.com/ru/post/1691804/


All Articles