I am trying to layout 2 plots together using ggplot2 and plotly. Here's what I tried:
library(ggplot2)
library(plotly)
mt_mpg <- ggplot(data = mtcars)+
geom_boxplot(aes(x = as.factor(cyl), y = mpg))+
ggtitle("mpg vs cyl")
mt_disp <- ggplot(data = mtcars)+
geom_boxplot(aes(x = as.factor(cyl), y = disp))+
ggtitle("disp vs cyl")
subplot(mt_mpg, mt_disp)
Everything works great but the title of the combined plot only contains "disp vs cyl". I want to include both titles on the top of their corresponding plots. But I don't see any option in subplot() command to do so. Any ideas how this can be fixed? Thanks.
one way is to use facet_wrap instead of ggtitle. For example:
df <- mtcars
df$lab1 <- 'mpg vs cyl'
df$lab2 <- 'disp vs cyl'
mt_mpg <- ggplot(df)+
geom_boxplot(aes(x = as.factor(cyl), y = mpg))+
facet_wrap(~lab1)
mt_disp <- ggplot(df)+
geom_boxplot(aes(x = as.factor(cyl), y = disp))+
facet_wrap(~lab2)
subplot(mt_mpg, mt_disp)
Cheers,
Branden
Related
I am trying to make a ggplot2 graph in which I have a "classic" dot plot together with a table.
This is an example of the plot I am making:
library(dplyr)
library(tibble)
library(ggplot2)
library(ggpmisc)
mtcars[1:10,] %>%
select(cyl, mpg, wt) -> tb
df <- tibble(x = 5.45, y = 34, tb = list(tb))
# using defaults
ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) +
geom_point() +
geom_table(data = df, aes(x = x, y = y, label = tb))
This is the output of the code:
I would however the rows of the table be coloured according to the factor cyl. So every rows which has carb==4 is red, ==6 is green and ==8 is blue.
I don't need the column cyl to appear in the table, so that can be removed (if possible).
Is there a way to do it?
Thanks a lot in advance for your precious help,
Luca
Unlike most of the ggplot ecosystem, you can't just use a fill aesthetic inside geom_table, and instead need to create a table theme which gets passed to table.theme inside geom_table. This means it is somewhat inconvenient to achieve the desired effect, but it is possible with something like the following:
thm <- gridExtra::ttheme_default()
fills <- scales::hue_pal()(3)[as.numeric(factor(df$tb[[1]]$cyl))]
thm$core$bg_params$fill <- fills
df$tb[[1]] <- df$tb[[1]][-1]
ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) +
geom_point() +
geom_table(data = df, aes(x = x, y = y, label = tb), table.theme = thm)
It is a bit hacky, but using the table.theme argument, you can supply the table with your own background colors (see Controlling the colors of rows in ggplot table annotation).
First, we construct a vector which contains a required background color for each row. Then, we use those colors in the table.theme argument of geom_table.
library(dplyr)
library(tibble)
library(ggplot2)
library(ggpmisc)
mtcars[1:10,] %>%
select(cyl, mpg, wt) -> tb
df <- tibble(x = 5.45, y = 34, tb = list(tb))
# Construct vector of required background colors (from default ggplot2 theme)
colors <- scales::hue_pal()(n_distinct(tb$cyl))
colors <- colors[factor(tb$cyl)]
# using defaults
ggplot(mtcars, aes(wt, mpg, colour = factor(cyl), fill = factor(cyl))) +
geom_point() +
geom_table(data = df, aes(x = x, y = y, label = tb),
table.theme = gridExtra::ttheme_default(core = list(bg_params=list(fill=colors))))
I have my an empty panel in my facetted ggplot. I would like to insert my standalone plot into this. Is this possible? See below for example code.
I found a possible solution Here, but can't get it to 'look nice'. To 'look nice' I want the standalone plot to have the same dimensions as one of the facetted plots.
library(ggplot2)
library(plotly)
data("mpg")
first_plot = ggplot(data = mpg, aes(x = trans, y = cty)) +
geom_point(size= 1.3)
facet_plot = ggplot(data = mpg, aes(x = year, y = cty)) +
geom_point(size = 1.3) +
facet_wrap(~manufacturer)
facet_plot # room for one more panel which I want first_plot to go?
# try an merge but makes first plot huge, compared with facetted plots.
subplot(first_plot, facet_plot, which_layout = 2)
Besides the options to manipulate the gtable or using patchwork one approach to achieve your desired result would be via some data wrangling to add the standalone plot as an additional facet. Not sure whether this will work for your real data but at least for mpg you could do:
library(ggplot2)
library(dplyr)
mpg_bind <- list(standalone = mpg, facet = mpg) %>%
bind_rows(.id = "id") %>%
mutate(x = ifelse(id == "standalone", trans, year),
facet = ifelse(id == "standalone", "all", manufacturer),
facet = forcats::fct_relevel(facet, "all", after = 1000))
ggplot(data = mpg_bind, aes(x = x, y = cty)) +
geom_point(size = 1.3) +
facet_wrap(~facet, scales = "free_x")
I have a problem with outliers appearing when they shouldn't when I use plotly, and I'm wondering how to stop this from happening. I'll use the mtcars dataset as an example.
I'll set an obvious outlier:
mtcars[1,1] = 60
The first plot, with outliers included:
p <- ggplot(mtcars) +
+ geom_boxplot(
+ aes(x = cyl, y = mpg, group = cyl))
Now I make a plot with outliers removed:
p <- ggplot(mtcars) +
geom_boxplot(
aes(x = cyl, y = mpg, group = cyl),
outlier.shape = NA)
Now I convert the plot to ggplotly and save
p <- plotly::ggplotly(p)
The outliers are showing. Does anyone know how I can get around this problem / have a solution when using ggplotly?
Found a solution:
for (i in 1:3) {
p$x$data[[i]]$marker <- list(opacity = 0)
}
I am trying to plot a list of plots using GGiraph in Rstudio.
The solution to plot multiple plots is either through Cowplot (ggobj = plot_grid(plot1, plot2)) or Patchwork (code = print(plot / plot)). This works if you individually print single plots. However, it looks like it does not accept a list of plots. I want the plots to be arranged in one column with multiple rows.
Does anyone have a solution to this?
You could try the plotlist argument in plot_grid.
#Using the example from giraffe
library(ggiraph)
library(ggplot2)
dataset <- mtcars
dataset$carname = row.names(mtcars)
gg_point = ggplot( data = dataset,
mapping = aes(x = wt, y = qsec, color = disp,
tooltip = carname, data_id = carname) ) +
geom_point_interactive() + theme_minimal()
#using the plotlist argument
library(cowplot)
girafe(ggobj = plot_grid(plotlist=list(gg_point, gg_point), ncol=1))
You can also do this with functional assembly in patchwork, using the wrap_plots() function and the ncol or nrow arguments. wrap_plots() can take either a series of graphs or a list.
library(ggiraph)
library(ggplot2)
library(patchwork)
# Demo figure
g <- ggplot(data = mpg, aes(x = cyl, y = hwy, color = class,
tooltip = model, data_id = model)) +
geom_point_interactive()
# Use wrap_plots from patchwork
g <- wrap_plots(list(g, g), ncol = 1)
girafe(ggobj = g)
I want to add interaction to the fill argument of my plotly figure, as e.g. answered here.
However, although the ggplot figure comes out correctly, the plotly does not. I am using the following versions and show a MWE below:
ggplot2: version 2.0.0.9000, plotly: version 2.0.19
library(plotly)
g <- ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = interaction(factor(cyl),carb))) + geom_boxplot()
(gg <- ggplotly(g))
Any ideas why g and gg differs above?
Not a complete solution. Include the interaction to your x term:
# use lex.order to obtain correct ordered levels
a <- ggplot(mtcars, aes(x = interaction(cyl, carb, lex.order = T), y = mpg,fill = interaction(cyl, carb, lex.order = T))) +
geom_boxplot()
# check the plot
a
# plotly
ggplotly(a)
actually there is an alternative that will give you exactly what you want.
mtcars$intec <- interaction(factor(cyl),carb)
mtcars %>%
plot_ly(x = cyl, y = mpg, type = "box", color = as.factor(intec), fill=as.factor(intec)) %>%
layout(boxmode = "group")