Keep x and y scales same (so square plot) in ggplotly

Viewed 944

I created a plot that has the same x and y limits, same scale for x and y ticks, hence guaranteeing the actual plot is perfectly square. Even with a legend included, the code below seems to keep the static plot (sp object) itself perfectly square even when the window in which it is positioned is rescaled:

library(ggplot2)
library(RColorBrewer)
set.seed(1)
x = abs(rnorm(30))
y = abs(rnorm(30))
value = runif(30, 1, 30)
myData <- data.frame(x=x, y=y, value=value)
cutList = c(5, 10, 15, 20, 25)
purples <- brewer.pal(length(cutList)+1, "Purples")
myData$valueColor <- cut(myData$value, breaks=c(0, cutList, 30), labels=rev(purples))
sp <- ggplot(myData, aes(x=x, y=y, fill=valueColor)) + geom_polygon(stat="identity") + scale_fill_manual(labels = as.character(c(0, cutList)), values = levels(myData$valueColor), name = "Value") + coord_fixed(xlim = c(0, 2.5), ylim = c(0, 2.5))

However, I am now attempting to transfer this static plot (sp) into an interactive plot (ip) through ggplotly() that can be used in a Shiny app. I notice now that the interactive plot (ip) is no longer square-shaped. The MWE to show this is below:

ui.R

library(shinydashboard)
library(shiny)
library(plotly)
library(ggplot2)
library(RColorBrewer)

sidebar <- dashboardSidebar(
  width = 180,
  hr(),
  sidebarMenu(id="tabs",
    menuItem("Example plot", tabName="exPlot", selected=TRUE)
  )
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "exPlot",
      fluidRow(
        column(width = 8,
          box(width = NULL, plotlyOutput("exPlot"), collapsible = FALSE, background = "black", title = "Example plot", status = "primary", solidHeader = TRUE))))))

dashboardPage(
  dashboardHeader(title = "Title", titleWidth = 180),
  sidebar,
  body
)

server.R

library(shinydashboard)
library(shiny)
library(plotly)
library(ggplot2)
library(RColorBrewer)

set.seed(1)
x = abs(rnorm(30))
y = abs(rnorm(30))
value = runif(30, 1, 30)

myData <- data.frame(x=x, y=y, value=value)

cutList = c(5, 10, 15, 20, 25)
purples <- brewer.pal(length(cutList)+1, "Purples")
myData$valueColor <- cut(myData$value, breaks=c(0, cutList, 30), labels=rev(purples))

# Static plot
sp <- ggplot(myData, aes(x=x, y=y, fill=valueColor)) + geom_polygon(stat="identity") + scale_fill_manual(labels = as.character(c(0, cutList)), values = levels(myData$valueColor), name = "Value") + coord_fixed(xlim = c(0, 2.5), ylim = c(0, 2.5))

# Interactive plot
ip <- ggplotly(sp, height = 400)

shinyServer(function(input, output, session){

  output$exPlot <- renderPlotly({
    ip
  })

})

It seems there may not be a built-in/clear solution at this time (Keep aspect ratio when using ggplotly). I have also read about a HTMLwidget.resize object that might help solve a problem like this (https://github.com/ropensci/plotly/pull/223/files#r47425101), but I was unsuccessful determining how to apply such syntax to the current problem.

Any advice would be appreciated!

1 Answers
Related