I am able to create my desired chart as a standard ggplot2
data <- structure(list(Date = structure(c(19205, 19236, 19266, 19205,
19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205,
19236, 19266, 19205, 19236, 19266, 19205, 19236, 19266, 19205,
19236, 19266, 19205, 19236, 19266), class = "Date"), Key = c("Average Hourly Earnings",
"Average Hourly Earnings", "Average Hourly Earnings", "Case Shiller House Price Index",
"Case Shiller House Price Index", "Case Shiller House Price Index",
"HPA", "HPA", "HPA", "Industrial Production", "Industrial Production",
"Industrial Production", "Personal Consumption Expenditures",
"Personal Consumption Expenditures", "Personal Consumption Expenditures",
"Retail Sales", "Retail Sales", "Retail Sales", "Capacity Utilisation",
"Capacity Utilisation", "Capacity Utilisation", "Total Vehicle Sales",
"Total Vehicle Sales", "Total Vehicle Sales", "Construction Spending",
"Construction Spending", "Construction Spending"), Value = c(-0.223065575886151,
-1.40315318073944, -1.91465670559936, -2.51599837113228, NA,
NA, -2.39639074829503, NA, NA, -0.620070909725157, 0.438262897380392,
-1.02195804568898, -1.18062194826764, -1.04966383725284, NA,
-0.434581634758551, -0.671474725212731, -0.689827602986322, 0.814973303786158,
0.792591156917412, 0.36832537554409, 2.29199981656987, 2.23432584415557,
1.83201171904481, 0.283236872921727, 0.721164674024409, NA),
Color = c("#e6cc00", "#ff0000", "#ff0000", "#7b0000", NA,
NA, "#7b0000", NA, NA, "#e6cc00", "#ece75f", "#ff0000", "#ff0000",
"#ff0000", NA, "#e6cc00", "#e6cc00", "#e6cc00", "#ece75f",
"#ece75f", "#ece75f", "#0a5d00", "#0a5d00", "#0eff00", "#ece75f",
"#ece75f", NA)), row.names = c(NA, -27L), class = c("tbl_df",
"tbl", "data.frame"))
library(tidyverse)
library(plotly)
p <- data2 %>%
{ggplot(.,aes(Date, Key, fill = Color))
geom_tile()
theme_light()
scale_fill_identity(guide = 'legend', breaks = c('NA','#0a5d00','#0eff00', "#ece75f",'#e6cc00','#ff0000','#7b0000'),
labels = c("NA",'> 2 Standard Deviations from mean', 'Between 1 and 2 Standard Deviations from mean',
'Between 0 and 1 Standard Deviations from mean', 'Between 0 and -1 Standard Deviations from mean',
'Between -1 and -2 Standard Deviations from mean', '> -2 Standard Deviations from mean'))
}
p
However when I try to convert it into an interactive chart using ggplotly
, it ignores all of the customisations to the legend that I did in the ggplot
. Is there a way to manually set the order of the legend items as well as the labels in the legend as I have done in my ggplot
?
p %>% ggplotly(tooltip = c('Date','Key')) %>%
layout(legend = list(orientation = "h", x = 0.4, y = -0.2))
CodePudding user response:
To make this happen, I created another variable in your data frame. I copied the breaks and labels from your original call to scale_fill_manual
.
I want to point out that in the viewer pane, the legend will reflect as a stack if the window isn't large enough for it to reflect the labels horizontally.
The new variable.
data2 <- data2 %>%
mutate(labs = Color %>% as.factor() %>% plyr::mapvalues(
# copied from breaks; NA removed
from = c('#0a5d00','#0eff00',"#ece75f",'#e6cc00','#ff0000','#7b0000'),
# copied from labels; NA removed
to = c('> 2 Standard Deviations from mean',
'Between 1 and 2 Standard Deviations from mean',
'Between 0 and 1 Standard Deviations from mean',
'Between 0 and -1 Standard Deviations from mean',
'Between -1 and -2 Standard Deviations from mean',
'> -2 Standard Deviations from mean')))
A modification to the plot—setting, filter out the NA, change fill
to fill = labs
, and instead of scale_fill_identity
, I've used scale_fill_manual
. In that call, you will map the colors to the color labels. (Instead of the reverse, which is what you did originally.)
(p <- data2 %>% filter(!is.na(Color)) %>%
ggplot(.,aes(Date, Key, fill = labs))
geom_tile()
theme(legend.position = "bottom")
scale_fill_manual(values = levels(as.factor(data2$Color)),
breaks = levels(as.factor(data2$labs))))
I've got 2 different versions for you to look at for this as a Plotly object. The first centers the legend on the plot (just the gridded area). The second is left-aligned.
p %>% ggplotly() %>%
layout(legend = list(xanchor = "center", y = -.2,
x = .5, orientation = "h"))
p %>% ggplotly() %>%
layout(legend = list(xanchor = "left", y = -.2,
x = -.2, orientation = "h"))
The first image is the centered variation; the second is the left-aligned version.
FYI: If you were partial to the order in which the labels were provided in ggplot
(y-axis), you can force Plotly to respect them if you make them an ordered factor.
Your original legend title was Color
. If you want that to be the legend title for this plot, simply add it to the layout
call.
p %>% ggplotly() %>%
layout(legend = list(xanchor = "left", y = -.2,
x = -.2, orientation = "h",
title = list(text = "Color")))