Reputation: 2722
I would like to reverse the order of the legend for a horizontal bar chart. When adding guides(fill = guide_legend(reverse = TRUE))
to the ggplot
it works fine (see second plot). However, after applying ggplotly()
the legend is again in the default order.
How to reverse the order of the plotly
legend without changing the order of the bars?
library(ggplot2)
library(dplyr)
data(mtcars)
p1 <- mtcars %>%
count(cyl, am) %>%
mutate(cyl = factor(cyl), am = factor(am)) %>%
ggplot(aes(cyl, n, fill = am)) +
geom_col(position = "dodge") +
coord_flip()
p1
p2 <- p1 + guides(fill = guide_legend(reverse = TRUE))
p2
plotly::ggplotly(p2)
Upvotes: 3
Views: 1865
Reputation: 2722
Adding to the great answer of @Zac Garland here is a solution that works with legends of arbitrary length:
library(ggplot2)
library(dplyr)
reverse_legend_labels <- function(plotly_plot) {
n_labels <- length(plotly_plot$x$data)
plotly_plot$x$data[1:n_labels] <- plotly_plot$x$data[n_labels:1]
plotly_plot
}
p1 <- mtcars %>%
count(cyl, am) %>%
mutate(cyl = factor(cyl), am = factor(am)) %>%
ggplot(aes(cyl, n, fill = am)) +
geom_col(position = "dodge") +
coord_flip()
p2 <- mtcars %>%
count(am, cyl) %>%
mutate(cyl = factor(cyl), am = factor(am)) %>%
ggplot(aes(am, n, fill = cyl)) +
geom_col(position = "dodge") +
coord_flip()
p1 %>%
plotly::ggplotly() %>%
reverse_legend_labels()
p2 %>%
plotly::ggplotly() %>%
reverse_legend_labels()
Upvotes: 6
Reputation: 163
When you call ggplotly, it's really just creating a list and a function call on that list.
So if you save that intermediate step, you can modify the list directly. and as such, modify the plot output.
library(ggplot2)
library(dplyr)
data(mtcars)
p1 <- mtcars %>%
count(cyl, am) %>%
mutate(cyl = factor(cyl), am = factor(am)) %>%
ggplot(aes(cyl, n, fill = am)) +
geom_col(position = "dodge") +
coord_flip()
html_plot <- ggplotly(p1)
replace_1 <- html_plot[["x"]][["data"]][[2]]
replace_2 <- html_plot[["x"]][["data"]][[1]]
html_plot[["x"]][["data"]][[1]] <- replace_1
html_plot[["x"]][["data"]][[2]] <- replace_2
html_plot
Upvotes: 3
Reputation: 99
A simple solution is to define the order of the levels of the factor variable am
:
library(ggplot2)
library(dplyr)
data(mtcars)
df <- mtcars %>%
count(cyl, am) %>%
mutate(cyl = factor(cyl), am = factor(as.character(am), levels = c("1", "0")))
head(df)
p1 <- df %>%
ggplot(aes(cyl, n, fill = am)) +
geom_col(position = "dodge") +
coord_flip()
p1
plotly::ggplotly(p1)
Upvotes: 1