Reputation: 169
I want to generate an output of x plots with ggplot on differennt pages. The y labels are text variables with different lengths.
Depending on the max. length of these labels the plots are not looking the same, label and diagram area are automatically optimized by ggplot.
There should be a way to have always the same width for the y labels or not?
Code fragment of ggplot command:
print(ggplot(dfPriceArt[ixStart:ixEnde, ], aes(x=reorder(BATArtikelKomplett, MaxEinzelpreisPerc), y=MaxEinzelpreisPerc, size=MaxEinzelpreisPerc)) +
geom_point() +
coord_flip() +
labs(y='BATArtikel',x='MaxEinzelpreis') +
theme(axis.text=element_text(size=6)) +
scale_y_continuous(limits=c(100, maxEinzelpreisPerc)) +
scale_size_continuous(limits=c(100, maxEinzelpreisPerc)))
Upvotes: 1
Views: 1833
Reputation: 17648
you can try
library(tidyverse)
library(grid)
library(gridExtra)
# some data and plots
df <- iris %>%
bind_rows(iris %>% mutate(Species=paste0(Species,"_", Species)), .id = "gr") %>%
group_by(gr,Species) %>%
summarise(y=mean(Sepal.Length)) %>%
nest(-gr) %>%
mutate(plots= map(data, ~ggplot(data=.x, aes(Species, y)) +
geom_point() +
coord_flip()))
df$plots
[[1]]
[[2]]
# updating the width
gp1<- ggplot_gtable(ggplot_build(df$plots[[1]]))
gp2<- ggplot_gtable(ggplot_build( df$plots[[2]]))
maxWidth = unit.pmax(gp1$widths[2:3], gp2$widths[2:3])
gp1$widths[2:3] <- maxWidth
gp2$widths[2:3] <- maxWidth
grid.arrange(gp1)
grid.arrange(gp2)
Finally you can save the plots using
ggsave("test1.jpeg",grid.arrange(gp1))
ggsave("test2.jpeg",grid.arrange(gp2))
The idea was
Upvotes: 2
Reputation: 169
The first comment to left align two graph edges (ggplot) helped a lot to find an own solution additionally with Align multiple plots in ggplot2 when some have legends and others don't (last edit).
As @Jimbou pointed out I wanted to have one plot per page, sorry to have not mentioned that.
This is what my solution now looks like:
library(gridExtra)
...
for (i in 1:iLast) {
...
p <- ggplot(dfPriceArt[ixStart:ixEnde, ], aes(x=reorder(BATArtikelKomplett, MaxEinzelpreisPerc), y=MaxEinzelpreisPerc, size=MaxEinzelpreisPerc)) +
geom_point() +
coord_flip() +
labs(y='BATArtikel',x='MaxEinzelpreis') +
theme(axis.text=element_text(size=6)) +
scale_y_continuous(limits=c(100, maxEinzelpreisPerc)) +
scale_size_continuous(limits=c(100, maxEinzelpreisPerc))
plot_list[[i]] <- ggplotGrob(p)
widths_list[[i]] <- plot_list[[i]]$widths[2:5]
...
}
maxWidth <- do.call(grid::unit.pmax, widths_list)
for (i in 1:iLast) {
plot_list[[i]]$widths[2:5] <- as.list(maxWidth)
grid.draw(plot_list[[i]])
if (i != iLast) {
grid.newpage()
}
}
Upvotes: 1
Reputation: 3311
There is no direct way I know of, but you can pad the y-labels and use a fixed width font to align the plots. Since you didn't supply any sample data, this is a short made up example:
library(tidyverse)
library(gridExtra)
# create two data.frames with differing lengths for the labels
df1 <- tribble(~x, ~y,
1, paste0(letters[1:10], collapse = ""))
df2 <- tribble(~x, ~y,
1, paste0(letters[1:20], collapse = ""))
# find the length of the longest label
max_length <- max(str_length(df2$y))
# pad the shorter labels
df1 <- mutate(df1, y = str_pad(y, max_length, side = "left"))
# create plots using a fixed width font
p1 <- ggplot(df1, aes(x, y)) +
geom_point()+
theme(axis.text.y = element_text(family = "mono"))
p2 <- ggplot(df2, aes(x, y)) +
geom_point()+
theme(axis.text.y = element_text(family = "mono"))
# arrange them for demonstrative purposes
grid.arrange(p1, p2)
Created on 2018-04-20 by the reprex package (v0.2.0).
Upvotes: 1