Size Scale Disappears ggplotly - r

When I try to use ggplotly(), I lose the legend that explains the color scale. If I use color instead of size the legend appears. How do I get the legend to appear when using size?
library(dplyr)
library(plotly)
plot <- mtcars %>%
ggplot(aes(x = mpg, y = cyl, size = disp, frame = hp)) +
geom_point()
ggplotly(plot) %>%
layout(showlegend = T)

I think the issue is that using as size a numeric variable such as disp will create a very large legend e.g.:
p <- ggplot(data=mtcars, aes(x = mpg, y = cyl, colour=factor(disp), size = factor(disp))) +
geom_point()
p <- ggplotly(p)
p
PS: I'm not sure you can use frame and still have the desired legend using ggplotly.
Option 2: Use directly plot_ly e.g.:
plot_ly(mtcars,x = ~ mpg, y= ~ cyl, size = ~disp , type='scatter', mode = 'markers', frame = ~disp) %>%
layout(showlegend = T)

Related

Colour rows by one factor in geom_table

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))))

create single ggplot figure with a standalone ggplot and a ggplot created with facet_wrap()?

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")

Save a list of plots dynamically

I am able to generate some plots based on a list of data frames:
df1 <- mtcars
df2 <- mtcars
combined_mtcars <- list(first_df = df1, second_df = df2)
# make the plots
imap(.x = combined_mtcars, ~ggplot(.x, aes(x = hp, y = mpg, group = cyl)) +
geom_line() +
ggtitle(.y))
I wanted to then save each plot to a directory called /plots. So I tried adding ggsave like so:
imap(.x = combined_mtcars, ~ggplot(.x, aes(x = hp, y = mpg, group = cyl)) +
geom_line() +
ggtitle(.y)) %>%
imap(~ggsave(plot = .y, file = paste0("/plots/", .y, ".png")))
This resulted in error "Saving 6.62 x 5.57 in image
Error in UseMethod("grid.draw") :
no applicable method for 'grid.draw' applied to an object of class "character"".
How can I save each iteration where the filename is the same as the title .y?
We need to make sure the ggplot object is being passed as the first argument, using the tag argument in the labs() function allows us to assign the plot to a "variable".
imap(.x = combined_mtcars, ~ggplot(.x, aes(x = hp, y = mpg, group = cyl)) +
geom_line() +
labs(title = .y, tag="Plot")%>%
imap(~ggsave(plot = Plot, file = paste0("/plots/", .y, ".png")))
If that does not work, try this since ggsave may default to the correct plot.
imap(.x = combined_mtcars, ~ggplot(.x, aes(x = hp, y = mpg, group = cyl)) +
geom_line() +
ggtitle(.y)) %>%
imap(~ggsave(file = paste0("/plots/", .y, ".png")))

plotly does not show titles of multiple plots in R

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

fill Interaction not working with ggplot2 and plotly

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")

Resources