Is it possible to fix axis margin with ggplot2?
Asked Answered
D

1

6

I have an interactive display consisting of a bar chart that shows a selected statistic for different categories. However, ggplot2 readjusts the y-axis width depending on the labels, and hence makes the bars annoyingly move on the x-direction. See exemple:

library(shiny)
library(dplyr)
library(ggplot2)

shinyApp(
  ui = bootstrapPage(
    selectInput('statistic', label='Chose a statistic', choices=c('carat', 'depth', 'table', 'price')),
    plotOutput('plot')
  ),
  server = function(input, output) {
    output$plot <- renderPlot(
      diamonds %>%
        ggplot(aes(x=color, y=get(input$statistic))) +
        geom_bar(stat = 'sum') +
        theme(text = element_text(size=20), legend.position="none")
    )
  }
)

How can I fix the width of the y-axis label? (or equivalently the width of the plotting panel?)

I did find related questions, but all were solved in a static context, for instance with facets or with gtable.

Did answered 8/1, 2016 at 12:49 Comment(4)
This generates errors for me. And btw, you ought to use aes_string instead of aes(..., get(...)).Mcmahan
can you be more specific about the error? I've just run it and it works hereDid
What are your package versions? I have ggplot2: v1.0.1, shiny: 0.12.2Mcmahan
there's a newer ggplot2 version (2.0.0)Did
M
5

One way would be to provide a label function that normalizes the label widths by padding them with spaces. function(label) sprintf('%15.2f', label) would pad with 15 spaces on the left and print the numeric value with 2 decimal places.

library(shiny)
library(dplyr)
library(ggplot2)

shinyApp(
  ui = bootstrapPage(
    selectInput('statistic', label='Chose a statistic', choices=c('carat', 'depth', 'table', 'price')),
    plotOutput('plot')
  ),
  server = function(input, output) {
    output$plot <- renderPlot(
      diamonds %>%
        ggplot(aes(x=color, y=get(input$statistic))) +
        scale_y_continuous(labels=function(label) sprintf('%15.2f', label)) +
        geom_bar(stat = 'sum') +
        theme(text = element_text(size=20), legend.position="none")
    )
  }
)
Mcmahan answered 8/1, 2016 at 13:45 Comment(4)
Another option would be to rotate the labels so that they are parallel to the Y axis.Mcmahan
difficult to reproduce without my data but it comes from the font 'cause using axis.text.y = element_text(family='mono') in theme fixes itDid
Yes, a single width font will do it.Mcmahan
Getting this to stop 'jiggling' wo a fixed-width font was difficult. I settled on a workaround using ggdraw() + draw_plot(..., width=1) + draw_plot(..., width=.998) + ...Undry

© 2022 - 2024 — McMap. All rights reserved.