0

I would like to create a dual-sided bar chart with text in the middle. How can I achieve this in R? Are there any existing packages available for this, or can it be done using ggplot? Thank you very much.

enter image description here

how to plot two sided bar with text in middle chart in R

neilfws
  • 32,751
  • 5
  • 50
  • 63
  • 1
    I think you want to look into `coord_flip` in ``ggplot2` to get the barplot mirrored, and `cowplot` for the layout. The difficulty is to align the text in the center panel. This link may help for the text arrangement: https://paulvanderlaken.com/2018/08/29/add-a-self-explantory-legend-to-your-ggplot2-boxplots/ . I would suggest that you first get the barplots in the correct form and then experiment with `cowplot` to arrange the panels. – David Jun 20 '23 at 01:41
  • 2
    It's easier to answer if you [make this question reproducible](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) by including a small representative dataset in a plain text format - for example the output from `dput(yourdata)`, if that is not too large. – neilfws Jun 20 '23 at 01:51
  • 1
    I think you could adapt some of the answers [to this question](https://stackoverflow.com/questions/4559229/drawing-pyramid-plot-using-r-and-ggplot2) - but again, data would help. – neilfws Jun 20 '23 at 02:48

1 Answers1

1

This can be achieved by editing the plot and axis margin, and arranging the plots using ggpubr:

library(ggplot2)
library(ggpubr)

test_data <-
  data.frame(
    sample = c("label a", "label b", "label c", "label d", "label e", "label f"),
    var1 = c(20, 24, 19, 21, 45, 23),
    var2 = c(4000, 3890, 4020, 3760, 4322, 5434)
  )

axis_margin <- 5.5

p1 <- ggplot(test_data, aes(var1, sample)) +
  geom_col() +
  scale_x_reverse() +
  scale_y_discrete(position = "right") +
  theme(
    axis.text.y = element_blank(),
    axis.title.y = element_blank(),
    plot.margin = margin(axis_margin, 0, axis_margin, axis_margin)
  )

p2 <- ggplot(test_data, aes(var2, sample)) +
  geom_col() +
  theme(
    axis.title.y = element_blank(),
    plot.margin = margin(axis_margin, axis_margin, axis_margin, 0),
    axis.text.y.left = element_text(margin = margin(0, axis_margin, 0, axis_margin))
  )

ggarrange(p1, p2)

For the left plot, you need to hide the y-axis labels and title. Set the axis position to "right" for the ticks to be in the correct position. Then you need to remove the right margin for the plot (default is 5.5). Also, you need to flip the x-axis.

For the right plot, you remove the y-axis title and remove the left margin of the plot. The distance between the two plots is controlled by setting the margin of the axis.text.y.left

enter image description here

f.lechleitner
  • 3,554
  • 1
  • 17
  • 35