nouse
nouse

Reputation: 3471

Replacing axis labels with scale_x_discrete

Consider this plot

dat <- data.frame(Sample = c(rep("S01", 3),
                            rep("S02", 3),
                            rep("S03", 3)),
                  Class = as.factor(c(rep(c("A", "B", "C"),3))),
                  Abundance=c(0.3, 0.4, 0.3, 0.3, 0.3, 0.4, 0.4, 0.3, 0.3))

dat <- rbind(dat, dat, dat)
dat$Transect <- as.factor(c(rep("x", 9), rep("y", 9), rep("z", 9)))
dat <- rbind(dat, dat, dat, dat)
dat$Season <- as.factor(c(rep("Ap", 27), rep("Ma", 27), rep("Au", 27), rep("Se", 27)))



ggplot(dat, aes(Sample, Abundance, fill=Class)) +
  theme_bw() +
  geom_bar(col="black", stat="identity", width=0.75) + 
  facet_grid(Season~Transect)

it is not possible to relabel the x-axis with the labels argument within scale_x_discrete by names given in an additional column, so that S01 is replaced with 100, S02 is replaced with 200, and so on:

library(plyr)

dat$Distance <- revalue(dat$Sample, c("S01" = "100",
                                      "S02" = "200",
                                      "S03" = "300"))

ggplot(dat, aes(Sample, Abundance, fill=Class)) +
  theme_bw() +
  geom_bar(col="black", stat="identity", width=0.75) + 
  facet_grid(Season~Transect)+
  scale_x_discrete(labels = dat$Distance) # note that labels=Distance is not working

All axis labels are set to the first level of the naming factor. enter image description here

Note, that in my much more complex real life data, it is not possible to switch to aes(x=Distance), because of the presence of 4 replicates per Sample, which for unknown reasons prevents the plotting of the bars. Also, putting labels = Distance into aes is not working. To the same end, dat$Sample cannot be made a factor. All these approaches would not result in the desired plot. I think the culprit is the labels = dat$distance argument, as ggplot2 doesnt know the correct alignment of Distance and Sample, but using labels = Distance results in "object 'distance' not found". I can build a data frame with a unique mapping with

labs <- unique(as.data.frame(cbind(dat$Sample, dat$Distance)))
names(labs) <- c("Sample", "Distance")

but do not know ho to proceed from there.

Is it possible to have my axis labels replaced with scale_x_discrete?

/edit: As my original data contains ~250 levels of dat$Sample, which are sorted into 5 groups of dat$Distance, it would be possible but tedious to write a complete vector of 250 relabels into scale_x_discrete (thanks to @MrFlick)

Upvotes: 1

Views: 183

Answers (2)

Michiel Duvekot
Michiel Duvekot

Reputation: 1881

# use a named character vector 
labels  <- c("S01" = "100",
             "S02" = "200",
             "S03" = "300")

ggplot(dat, aes(Sample, Abundance, fill=Class)) +
  geom_bar(col="black", stat="identity", width=0.75) + 
  facet_grid(Season~Transect)+
  scale_x_discrete(labels = labels)

Upvotes: 2

Josh Allen
Josh Allen

Reputation: 1280

If the samples are numbered you can play around with seq in the labels argument of scale_x_discrete

library(ggplot2)


ggplot(dat, aes(Sample, Abundance, fill=Class)) +
  theme_bw() +
  geom_bar(col="black", stat="identity", width=0.75) + 
  scale_x_discrete(label = seq(100, 300, 100)) +
  facet_grid(vars(Transect), vars(Season))

Created on 2024-06-18 with reprex v2.1.0

Upvotes: 1

Related Questions