How to prevent x axes overlap ggplotly with facet_wrap(~variable) - r

I have some data that looks nice when plotted with ggpglot but the x-axes and the plots underneath overlap in plotly::ggplotly().
library(gapminder)
library(plotly)
p <- ggplot(gapminder, aes(x=gdpPercap, y=lifeExp)) + geom_point() + scale_x_log10()
p <- p + aes(color=continent) + facet_wrap(~year,scale="free")
gp <- ggplotly(p)
gp
So I've been trying this: R: ggplot and plotly axis margin won't change
Basically I need to increase the white space between each graph object and the one below. Any thoughts would be much appreciated.

You can add vertical space in between your facets using:
theme(panel.spacing.y = unit(1, "line")) # adjust to taste
However, there's a snag related to axis titles and facets when converting to plotly, where the axis title becomes an annotation and needs to be shifted more manually.
See these links for ways how:
https://stackoverflow.com/a/47228372/6851825
Converting ggplot object to plotly object creates axis title that overlaps tick values
https://github.com/ropensci/plotly/issues/1224

Related

Maintaining linked zoom between subplots using plotly

I would like to create a facet plot with ggplot and show the x-axis with ticks on all facets. Then I want to use ggplotly to convert the result to a plotly graph. However when I use scales='free_x' to add the extra x-axes to the facets, the zoom linkage is lost. i.e. when I zoom on one of the facets it doesn't zoom on the others automatically. Is there a way to add that functionality back in?
This is a reprex showing the problem:
library(ggplot2)
library(ggthemes)
library(plotly)
p <- ggplot(mtcars, aes(mpg, hp)) + geom_point() + facet_wrap(~carb, ncol = 1, scales='free_x') +
theme_tufte() + theme(axis.line=element_line()) +
scale_x_continuous(limits=c(10,35)) + scale_y_continuous(limits=c(0,400))
ggplotly(p)
Notice here when I zoom in on the top plot, the other plots remain unchanged:

How do you remove extra space between x-axis and plot for a geom_density_ridges_gradient() plot in R ggplot

I am making a plot using ggplot2 in R. I am using the ggridges package and the geom_density_ridges_gradient() plot type. These plots create a large space between the bottom of the figure and the labels of the x-axis. Is there a way to remove or shrink this added space?
Here is the code I'm using to make the plot.
library(tidyverse)
library(ggridges)
library(scales)
sample_q <- ggplot(data, aes(x=value/1000,y=factor(category),group=category)) +
geom_density_ridges_gradient(scale=.5) +
theme_ridges(center_axis_labels = TRUE,grid=TRUE) +
xlab("Values") +
ylab("Height") +
theme(text=element_text(size=10)) +
scale_x_continuous(expand = c(0,0), limits = c(-15,15), breaks=c(-15,-10,-5,0,5,10,15))
I've tried creating the plot with different values of 'scale'. Here are three plots with scale set equal to 2, 1, and .5.
You can see that the space between the bottom of the density plot and the x-axis labels is large and does not change with scales. I've tried without the theme_ridges line as well and the plot still has the same vertical space between the density plot and the x-axis labels. I'd like the x-axis labels to be just below the 'Group A' plot.

ggplot2: Adjust distance between text and axis

As a followup to the question of how to
Increase distance between text and title on the y-axis, I am wondering whether it is also possible to adjust the distance between an axis and its title/label. This could be useful for creating similarly styled graphs, for example when the tick marks of two graphs are of different magnitudes.
Here are two example plots:
plot_a <- ggplot(mpg, aes(cty, hwy)) + geom_point()
plot_b <- ggplot(mpg, aes(cty, hwy*100)) + geom_point()
Note the difference on the left side of the plots:
Cowplot can, somehow, do the job and set the distance of axis and label the same in two plots:
cowplot::plot_grid (plotlist = list (plot_a, plot_b),
align = "v",
nrow = 2,
ncol = 1,
greedy = T)
However, I'd rather like to adjust the distance bewteen the label and the axis manually. Also, there are cases where it's preferable to draw one single plot per panel, rendering the cowplot-solution useless. So - is there a possibility to manually adjust the distance between axis and label?

grid.draw Cutting Off Facet Grid Title and X&Y Labels

I am trying to create a facet_grid() in ggplot() and am having issues with the margins of my plot. I am using grid.draw() for my final plot, and cannot figure out how to adjust the margins for printing. When I save my plot, it appears fine (see below). However, when I actually print my plot out to hard copy, half of the X&Y labels and my plot title are cut off.
I've attempted using par() to no avail. Here is a reproducible example, similar to my actual plot. I need to keep the panel <- off part because in my actual plot, I have plotted numbers above each bar and they get cut off by the facet sides for days at the beginning/end of each month. I'm thinking this might be the root of the issue, but I'm not really sure to be honest.
data(airquality)
library(stats)
library(ggplot2)
library(gtable)
library(gridExtra)
library(grid)
library(dplyr)
library(scales)
facet <- ggplot() +
geom_bar(data=airquality,aes(y=Wind,x=Day,fill=Temp),colour="black",stat="identity",position='stack') +
#theme_bw() +
facet_grid(~Month) +
theme(axis.title.x=element_text(face="bold",size=14),axis.title.y=element_text(face="bold",size=14),axis.text.x=element_text(face="bold",size=10),axis.text.y=element_text(face="bold",size=10))+
ylab("Wind") +
theme(panel.margin = unit(5, "mm"),panel.border=element_rect(color="black",fill=NA),panel.background = element_rect(fill="grey84"),plot.title = element_text (size=20,face="bold"),legend.position="right",panel.grid.minor=element_blank(),strip.text.x=element_text(size=12,face="bold"),strip.background=element_rect(fill=NA,colour="black"),legend.title=element_text(size=14,face="bold")) +
ggtitle("Test")
gt <- ggplot_gtable(ggplot_build(facet))
gt$layout$clip[gt$layout$name=="panel"] <- "off"
grid.draw(gt)
Thanks for any and all help! Please, let me know if you need any clarification or have any questions.
you have two options:
set some margins in the ggplot theme
assign a viewport of specific size to the plot/gtable, smaller than the device window by some margin. Here's an illustration of using both strategies at once
library(grid)
fig_size <- c(6, 4) # inches
margin <- unit(4, "line")
p <- ggplot() + theme(plot.background=element_rect(colour="red", size=2, fill="grey50"),
plot.margin = unit(1:4, "line"))
g <- ggplotGrob(p)
g$vp <- viewport(width = unit(fig_size[1], "in") - margin, height=unit(fig_size[2],"in")- margin)
ggsave("plot.pdf", g, width=fig_size[1], height=fig_size[2])

Set margins between plots using multiplot

To display multiple plots I use multiplot (http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/), now I have two plots who share the same x-axis range and are plotted above each other:
multiplot(plot1, plot2)
I removed the x-axis labels and title using:
xlab(NULL) + theme(axis.text.x=element_blank(),axis.ticks.x=element_blank())
But there is still a white margin between the two plots. How can I make this margin smaller or remove it?
To reduce space between the plots, remove the bottom margin of the top plot and remove the top margin of the bottom plot. The code below sets these margins to 0, which still results in a tiny bit of white space between the plots. You can make these margins slightly negative (maybe -0.1 or so) to completely remove the white space. Rather than the multiplot function, we use grid.arrange from the gridExtra package to lay out the plots. :
library(grid)
library(gridExtra)
## Create two sample plots with the same x axis using built-in mtcars data frame
# Top plot: Remove bottom margin, x-labels, and x title
p1 = ggplot(mtcars, aes(wt, mpg)) + geom_point() +
xlab(NULL) +
theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),
plot.margin=unit(c(1,1,0,1), "lines"))
# Bottom plot: Remove top margin
p2 = ggplot(mtcars, aes(wt, carb)) + geom_point() +
theme(plot.margin=unit(c(0,1,1,1), "lines"))
# Lay out plots in one column
grid.arrange(p1, p2, ncol=1)
Two problems with the above layout: (1) the y axes are not justified properly, and (2) the height of the lower plot's plot area is less than that of upper plot's plot area. The code below addresses these issues:
# Left justify plots
# Source: http://stackoverflow.com/a/13295880/496488
gA <- ggplotGrob(p1)
gB <- ggplotGrob(p2)
maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
gA$widths[2:5] <- as.list(maxWidth)
gB$widths[2:5] <- as.list(maxWidth)
# Lay out justified plots. Use heights argument to equalize heights of each plot area
grid.arrange(gA, gB, heights=c(0.47,0.53), ncol=1)
You can exactly equalize the heights of each plot area using the same trick as we used to left-justify the plots (rather than doing it by eye using the heights argument to grid.arrange), but then the plot margins get added back. I'm not sure of how to deal with that, but here's the code for reference:
maxHeight = grid::unit.pmax(gA$heights[2:5], gB$heights[2:5])
gA$heights[2:5] <- as.list(maxHeight)
gB$heights[2:5] <- as.list(maxHeight)
The last update of ggplot2 gives much more control over the plot. See for example:
ggplot(mtcars, aes(disp, mpg)) +
geom_point() +
facet_wrap(~vs)
You can further adjust the labels, number of rows, and how scales will be displayed, for instance: nrow = 2; scales = "free".
It is easier than you might think to re-arrange the data so that you can take advantage of the nice alignment features that already exist in ggplot2. See below for an example replicating eipi10's answer, but without having to use ggplotGrob.
What you have to do is just select the columns you want to plot, along with the ID columns (in this case, the car model and the x-axis value column). Then melt, and it's ready to plot using the standard facet procedure.
Note that the "switch" option in the facet_grid call is a new feature that you can access by updating to the most recent CRAN version. I used that to replace the regular y-axis title, which was omitted using theme.
The nice part about this approach is that the plots will always be perfectly aligned.
library("ggplot2")
library("dplyr")
library("reshape2")
df <- mtcars %>%
add_rownames(var = "Model") %>%
select(Model, wt, mpg, carb) %>%
melt(id.vars = c("Model","wt"))
ggplot(df)+
aes(x=wt, y=value)+
geom_point()+
theme(strip.background=element_blank())+
facet_grid(variable ~ ., scales="free_y", switch="y")

Resources