I have a faceted plot with very diverse data. So some facets have only 1 x
value, but some others have 13 x
values. I know there is the parameter space='free'
which adjusts the width of each facet by the data it represents.
My question, is there a possibility to adjust this space manually? Since some of my facets are so small, it is no longer possible to read the labels in the facets. I made a little reproducible example to show what I mean.
df <- data.frame(labelx=rep(c('my long label','short'), c(2,26)),
labely=rep(c('a','b'), each=14),
x=c(letters[1:2],letters[1:26]),
y=LETTERS[6:7],
i=rnorm(28))
ggplot(df, aes(x,y,color=i)) +
geom_point() +
facet_grid(labely~labelx, scales='free_x', space='free_x')
So depending on your screen, the my long label
facet gets compressed and you can no longer read the label.
I found a post on the internet which seems to do exactly what I want to do, but this seems to no longer work in ggplot2
. The post is from 2010.
https://kohske.wordpress.com/2010/12/25/adjusting-the-relative-space-of-a-facet-grid/
He suggests to use facet_grid(fac1 + fac2 ~ fac3 + fac4, widths = 1:4, heights = 4:1)
, so widths
and heights
to adjust each facet size manually.
You can adjust the widths of a ggplot object using grid graphics
With complex graphs with many elements, it can be slightly cumbersome to determine which width it is that you want to alter. In this instance it was grid column 4 that needed to be expanded, but this will vary for different plots. There are several ways to determine which one to change, but a fairly simple and good way is to use
gtable_show_layout
from thegtable
package.produces the following image:
in which we can see that the left hand facet is in column number 4. The first 3 columns provide room for the margin, the axis title and the axis labels+ticks. Column 5 is the space between the facets, column 6 is the right hand facet. Columns 7 through 12 are for the right hand facet labels, spaces, the legend, and the right margin.
An alternative to inspecting a graphical representation of the gtable is to simply inspect the table itself. In fact if you need to automate the process, this would be the way to do it. So lets have a look at the TableGrob:
The relevant bits are
in which the names panel-x-y refer to panels in x, y coordinates, and the cells give the coordinates (as ranges) of that named panel in the table. So, for example, the top and bottom left-hand panels both are located in table cells with the column ranges
4- 4
. (only in column four, that is). The left-hand top strip is also in cell column 4.If you wanted to use this table to find the relevant width programmatically, rather than manually, (using the top left facet, ie
"panel-1-1"
as an example) you could useAh yes very sad that functionality to set
widths
andheights
infacet_grid
is gone.Another possible workaround without
ggplotGrob
is to set the text angle intheme(strip.text.x=element_text(angle...))
and facet text wrapping infacet_grid(... labeller=label_wrap_gen(width...))
, e.g.In case you are interested in modifying
ggplot2
in more and other ways, I recommend the vignette:Now for your problem at hand, I think the shortcut of a clean solution goes as follows:
Continuing in new code block to stop the scrolling:
I say shortcut because you could of course write your own version of
facet_grid_new
in addition, allowing you to pass the valuesc(1,4)
from above flexibly as extraparams
.And of course you could make your own
ggproto
object inheriting fromFacetGrid
...Edit:
Another simple way of making this more flexible would be to add a custom
option
, e.g. like:This could then be used inside the custom
draw_panels
method somehow like this: