Force constant bar size for different y values

I'm trying to plot out horizontal bar graphs for different districts/counties, where the x-axis represents a value (count) and the y-axis represents the name of each district/county. On Shiny, I have a reactive component that filters a CSV file with this data and a drop-down to select which state/county to plot. The box function is from bs4Dash

 box(
        title = "Agriculture",
        width = 12,
        status = "primary",
        div(style="max-height:600px; overflow-y: scroll; overflow-x: scroll; position: relative",
             shinycssloaders::withSpinner(plotlyOutput("chart1", height="900px"))
           )
)

I'm using the div element to create a horizontal and vertical scroll bar if the y-axis elements exceed the max-height, which works well. On the server.r side, using the standard ggplot2 and plotly combo with renderPlotly to filter the CSV based on user select and plot a barchart.

  output$chart1 <-renderPlotly({
    data <- health_centre_csv |> filter(state == input$stateSelected)
    ggplot(data = data, aes(x = count, y= name)) + 
      geom_bar(stat='identity', position = position_dodge2(width = 0.5,preserve="single"))
  })

  1. The first chart shows 3 counties with each bar taking up maximum space to cover the chart area, with default aesthetics. The second chart shows over 70 counties.

So here ,would it be possible to force the size of the bar graph to be constant across all values of y? I think the underlying method is to make the bar take up space on the chart area based on the number of y-values, would it be possible to force the bars to the same size regardless of y being 3 or 70?

you can set the bar width to be particular fraction, so for relatively sized charts you can make the smaller charts bar width relatively smaller to match that of the bigger chart.


library(plotly)
library(ggplot2)
library(dplyr)


(bardata <- tibble(
  l=c(letters,LETTERS),
  nums = 1:52
))
(smallerbar_data <- bardata |> slice_head(n=3))



(num_of_bigger <- nrow(bardata))
(num_of_smaller <- nrow(smallerbar_data))
width_multiplier <- 1 # try .5 also  
(width_fraction <- width_multiplier * num_of_smaller/num_of_bigger)

(g1 <- ggplot(data=bardata) + aes(x=l,y=nums) + geom_col(width=width_multiplier)    + coord_flip())
(g2 <- ggplot(data=smallerbar_data) + aes(x=l,y=nums) + geom_col(width=width_fraction)    + coord_flip())
plotly:::subplot(g1,g2)

Thanks for the reply @nirgrahamuk, would it be possible to push "a","b" and "c" closer together? Preferably at the top?


library(plotly)
library(ggplot2)
library(dplyr)


(bardata <- tibble(
  l=c(letters,LETTERS),
  nums = 1:52
))
(smallerbar_data <- bardata |> slice_head(n=3)|>
  mutate(l=factor(l,levels=bardata$l)))



width_multiplier <- 1 # try .5 also  
(num_of_bigger <- nrow(bardata))
(num_of_smaller <- nrow(smallerbar_data))

(g1 <- ggplot(data=bardata) + aes(x=l,y=nums) + 
    geom_col(width=width_multiplier)    + coord_flip())
(g2 <- ggplot(data=smallerbar_data) + 
    aes(x=as.numeric(forcats::fct_rev(l)),y=nums) + 
    geom_col(width=width_multiplier)  + 
    coord_flip() + scale_x_continuous(name="l",
                                      limits = c(1,num_of_bigger+1),
                                      breaks = seq(from=1+num_of_bigger-num_of_smaller,
                                                   to=num_of_bigger,by=1),
                                      expand=c(0,0),
                                      labels=  rev(smallerbar_data$l)))
plotly:::subplot(g1,g2)

1 Like

Thanks so much @nirgrahamuk ! This is an interesting solution. I don't mean to be a bother, but would you be able to recreate this with a sample categorical data linked here?

I'm pretty new to R, appreciate the help.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.