Reputation: 1655
The below code generates two plots using ggplot
and ggplotly
. Despite of using the layout()
to ggplotly the legend is still at the right side. The legend is required to be at the bottom. Could anyone help to move the legend to bottom in the ggplotly? I have tried the solution at R + shiny + plotly: ggplotly moves the legend to the right and is not working here. Can someone help if im missing the obvious.
measure<-c("MSAT","MSAT","GPA","MSAT","MSAT","GPA","GPA","GPA")
score<-c(500, 490, 2.9, 759, 550, 1.2, 3.1, 3.2)
data<-data.frame(measure,score)
ui <- fluidPage(
mainPanel(
plotOutput("myplot" ),
plotlyOutput("myplot2" )
)
)
server <- function(input, output) {
myplot <- reactive({
gpl1 <- ggplot(data,aes(y=reorder(measure, score),x=score,fill=score)) +
geom_bar(stat="identity")+
theme(legend.position="bottom")+
xlab("x")+
ylab("y")+
labs(title = NULL)
gpl1
})
myplot2 <- reactive({
gpl2 <- ggplot(data,aes(y=reorder(measure, score),x=score,fill=score)) +
geom_bar(stat="identity") +
theme(legend.position="bottom")+
xlab("x")+
ylab("y")+
labs(title = NULL)
ggplotly(gpl2) %>%
layout(legend = list(orientation = 'h', x = 0.45, y = 1.1))
})
output$myplot <- renderPlot({
myplot()
})
output$myplot2 <- renderPlotly({
myplot2()
})
}
shinyApp(ui = ui, server = server)
Upvotes: 5
Views: 6136
Reputation:
As @ismirsehregal mentioned plotly does not yet support the horizontal colorbar, and the colorbar is present to support the continuous-valued fill attribute. So until plotly supports that orientation an alternative solution might serve temporarily: change the fill from continuous value to a discrete value. Here is the reactive using (a) a cut for the discrete values, and (b) plotly anchors for the bottom legend.
myplot2 <- reactive({
gpl2 <- ggplot(data,aes(y=reorder(measure, score),
x=score,
fill=cut(score, breaks=seq(0,800,100)))) +
geom_bar(stat="identity") +
labs(x='x',y='y',title=NULL,fill='Score') +
theme(legend.position = 'bottom') +
# scale_fill_stepsn(colours = terrain.colors(10),n.breaks=10)
scale_fill_viridis_d()
ggplotly(gpl2) %>%
plotly::layout(legend=list(x=0,
xanchor='left',
yanchor='bottom',
orientation='h'))
})
Upvotes: 4
Reputation: 33550
The problem here is, that you are dealing with a colorbar not a legend.
Currently plotly does not offer horizontal colorbars.
Also changing the position of a colorbar seems to be buggy in the ggplotly context:
library(shiny)
library(plotly)
measure<-c("MSAT","MSAT","GPA","MSAT","MSAT","GPA","GPA","GPA")
score<-c(500, 490, 2.9, 759, 550, 1.2, 3.1, 3.2)
data<-data.frame(measure,score)
ui <- fluidPage(
mainPanel(
plotOutput("myplot" ),
plotlyOutput("myplot2" )
)
)
server <- function(input, output) {
myplot <- reactive({
gpl1 <- ggplot(data,aes(y=reorder(measure, score),x=score,fill=score)) +
geom_bar(stat="identity")+
theme(legend.position="bottom")+
xlab("x")+
ylab("y")+
labs(title = NULL)
gpl1
})
myplot2 <- reactive({
fig <- ggplotly(myplot())
fig <- style(fig, marker = list(colorbar = list(xanchor = "center", yanchor = "center", x = 0.5, y = -1, title = "test")), traces = NULL) # try traces = 1 or 1:2
# browser()
# plotly_json(fig)
})
output$myplot <- renderPlot({
myplot()
})
output$myplot2 <- renderPlotly({
myplot2()
})
}
shinyApp(ui = ui, server = server)
Accordingly, for now I'd recommend not to modify the colorbar and use the defaults.
Upvotes: 2
Reputation: 2282
Okay this isn't a full answer, but it is a start that might help someone else pinpoint the problem, and it is too long to fit into a comment. It is possible it is worth opening up an issue, although I am not sure where (i.e. within what package) the problem lies.
I re-ran the code from R + shiny + plotly: ggplotly moves the legend to the right and it works as it should, but for some reason yours doesn't. The only difference is that your fill
is continuous, whereas the fill in that one is categorical.
If you add a categorical group here for score:
measure<-c("MSAT","MSAT","GPA","MSAT","MSAT","GPA","GPA","GPA")
score<-c(500, 490, 2.9, 759, 550, 1.2, 3.1, 3.2)
data<-data.frame(measure,score,score.f=as.factor(score))
Then the code you have works. You need to modify the gpl2
object with fill=score.f
(instead of fill=score
), and also need to change the y value in the layout to get the legend to the bottom:
ggplotly(gpl2) %>%
layout(legend = list(orientation = 'h', x = 0.45, y = -.07))
Yet, as soon as you change the fill group to a continuous
score<-c(500, 490, 2.9, 759, 550, 1.2, 3.1, 3.2)
data<-data.frame(measure,score,score.f=score)
The legend goes back to being on the right:
Upvotes: 3