如何在 ggplot2 中设置 y 轴标签的宽度 [英] How do I set width of y-axis labels in ggplot2
问题描述
我在 ggplot2 中制作了一系列直方图,并使用 ImageMagick 将它们动画化为 gif.这个想法是所有图中的 x 轴比例应该是相同的,但这并不完全正确,因为 y 轴由于标签的宽度不同而摆动.如何锚定图形,使所有图形具有完全相同的轴位置?
I've made a collection of histograms in ggplot2 and used ImageMagick to animate them into a gif. The idea is that the x-axis scale is supposed to be the same in all the graphs but this isn't quite true because the y-axis wiggles around due to the varying widths of the labels. How can I anchor the graph so that all the graphs have exactly the same axis positions?
如果有帮助,这是我的 ggplot 代码:
Here's 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")
推荐答案
首先,我想指出,由于 y 轴值不同,该图可能误导.观众的注意力将主要集中在直方图而不是值上.因此,我强烈建议在所有图中修复 y 轴.
First and foremost, I would like to point out that the plot might be misleading, due to the different y-axis values. The viewers' attention will go mostly to histogram and not the values. Therefore, I would highly recommend to fix the y-axis across the all of the plots.
library(ggplot2)
library(gridExtra)
library(stringr)
# Generate plots
# For each Species in iris dataset - generate a histogram of the Petal's 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")
.
.
# 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")
.
但是,如果您选择其他方式,我会用空格填充轴标签:
However, if you choose otherwise, I would go for padding the axis-labels with white spaces:
# 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's 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")
有什么不清楚的可以问.
Feel free to ask if there is anything which is not clear.
这篇关于如何在 ggplot2 中设置 y 轴标签的宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!