How do I set equal distances between axes ticks irrespective of number of points I plot in a ggplot?

168 Views Asked by At

I wish to have a hint on how I can set fixed distances between ticks on the axes of a dot plot in ggplot. I wish to have the same distances between the axes ticks irrespective of the number of points that I plot. For the sake of a publication, I wish to maintain a fixed formatting for my graphs. I am stuck on how handle the issue and my google search has not led me to a helpful answer.

For example. I have two data sets df1 and df2:

df1 <- as.data.frame(runif(3, min=0, max=100))

colnames(df1) <- "expression"

rownames(df1) <- c("gene1", "gene2", "gene3")

df1$gene <- rownames(df1)

> df1
      expression  gene
gene1   83.94404 gene1
gene2   34.66835 gene2
gene3   33.37749 gene3

ggplot(df1, aes(x = gene, y = expression, fill = gene))+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge")

enter image description here

The second dot plot from the second data set shows that the number of genes plotted has altered the distances between the axes ticks as seen in the plot of df1 above.

df2 <- as.data.frame(runif(10, min=0, max=100))

colnames(df2) <- "expression"

rownames(df2) <- c("gene1", "gene2", "gene3",
                  "gene4", "gene5", "gene6", "gene7", "gene8",
                  "gene9", "gene10")

df2$gene <- rownames(df2)

> df2
       expression   gene
gene1    47.63512  gene1
gene2    89.21983  gene2
gene3    86.43395  gene3
gene4    38.99895  gene4
gene5    77.73207  gene5
gene6    96.06180  gene6
gene7    43.46595  gene7
gene8    71.25147  gene8
gene9    39.99944  gene9
gene10   32.53522 gene10

ggplot(df2, aes(x = gene, y = expression, fill = gene))+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge")

enter image description here

I wish to have an image like the ones below where the number of items plotted has no effect on the distances between the ticks: The image comes from this publication

enter image description here

Than you in advance for any hint.

1

There are 1 best solutions below

2
tjebo On

@HanselPalencia is correct - the graphs you are showing do not really have the same distance between the x categories. Actually, I find them not the best example for a very consistent look. E.g. their width and height are different and more importantly, the legend keys and fonts have different sizes.

If you really want the x categories to have the exact same distance, the easiest solution is faceting - see below. Another solution is to use plot combining packages such as cowplot or (as in my example) patchwork. You'll have to play around with the exact sizing. But in reality, as you have noticed, people won't see the exact dimensions anyways.

df2 <- as.data.frame(runif(10, min=0, max=100))
colnames(df2) <- "expression"
rownames(df2) <- c("gene1", "gene2", "gene3","gene4", "gene5", "gene6", "gene7", "gene8","gene9", "gene10")
df1 <- as.data.frame(runif(3, min=0, max=100))
colnames(df1) <- "expression"
rownames(df1) <- c("gene1", "gene2", "gene3")
df1$gene <- rownames(df1)
df2$gene <- rownames(df2)

library(tidyverse)

solution 1 - facetting

df_comb <- bind_rows(list(a = df1, b= df2), .id = 'group')

ggplot(df_comb, aes(x = gene, y = expression, fill = gene))+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge") +
  facet_grid(~group)
#> `stat_bindot()` using `bins = 30`. Pick better value with `binwidth`.

solution 2 - patching together, here using the patchwork package

p1 <- ggplot(df1, aes(x = gene, y = expression, fill = gene))+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge")
p2 <- ggplot(df_comb, aes(x = gene, y = expression, fill = gene))+
  geom_dotplot(binaxis = "y", stackdir = "center", position = "dodge") 

library(patchwork)
p1+p2 +plot_layout(widths = c(0.3,1))
#> `stat_bindot()` using `bins = 30`. Pick better value with `binwidth`.
#> `stat_bindot()` using `bins = 30`. Pick better value with `binwidth`.

Created on 2019-11-14 by the reprex package (v0.2.1)