How do you specifically order ggplot2 x axis instead of alphabetical order?
How do you specifically order ggplot2 x axis instead of alphabetical order?
I'm trying to make a heatmap using ggplot2 using the geom_tiles function
here is my code below:
heatmap
ggplot2
geom_tiles
p<-ggplot(data,aes(Treatment,organisms))+geom_tile(aes(fill=S))+
scale_fill_gradient(low = "black",high = "red") +
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme(legend.position = "right",
axis.ticks = element_blank(),
axis.text.x = element_text(size = base_size, angle = 90, hjust = 0, colour = "black"),
axis.text.y = element_text(size = base_size, hjust = 1, colour = "black")).
data is my data.csv file
my X axis is types of Treatment
my Y axis is types of organisms
I'm not too familiar with commands and programming and I'm relatively new at this. I just want to be able to specify the order of the labels on the x axis. In this case, I'm trying to specify the order of "Treatment". By default, it orders alphabetically. How do I override this/keep the data in the same order as in my original csv file?
I've tried this command
scale_x_discrete(limits=c("Y","X","Z"))
where x, y and z are my treatment condition order. It however doesn't work very well, and give me missing heat boxes.
2 Answers
2
It is a little difficult to answer your specific question without a full, reproducible example. However something like this should work:
#Turn your 'treatment' column into a character vector
data$Treatment <- as.character(data$Treatment)
#Then turn it back into a factor with the levels in the correct order
data$Treatment <- factor(data$Treatment, levels=unique(data$Treatment))
In this example, the order of the factor will be the same as in the data.csv file.
data.csv
If you prefer a different order, you can order them by hand:
data$Treatment <- factor(data$Treatment, levels=c("Y", "X", "Z"))
However this is dangerous if you have a lot of levels: if you get any of them wrong, that will cause problems.
Have to wonder why this is even necessary. Why are the axes reordered by ggplot in the first place? Seems dangerous if someone isn't aware this is going to happen.
– Dirk Calloway
Mar 25 '14 at 10:27
I just ran into this problem myself making a heatmap with qplot and automatically applied variable names. Should it be reported?
– bright-star
Mar 25 '14 at 10:29
@DirkCalloway, this behavior makes sense if you think about how factors work in R. A factor is a vector of integers, each of which is associated with a character 'label'. When you create a factor by reading a column of character values in a text file (e.g.
.csv), R assigns the integer values in alphabetical order rather than in the order they appear in the file. You can argue whether that makes sense, but ggplot2 then does the logical thing, which is to display the factor levels in order of their integer values. Your complaint is with read.table, not ggplot2.– Drew Steen
Mar 25 '14 at 14:06
.csv
ggplot2
read.table
ggplot2
@DrewSteen True, I guess it makes sense from that perspective.
– Dirk Calloway
Mar 25 '14 at 18:29
Stumbled upon this answer because of a current duplicate question. The most accepted answer offers a solution which requires changing the underlying data frame. This is not necessary. One can also simply factorise within the aes() call directly or create a vector for that instead.
This is certainly not much different than @Drew Steen's answer, but with the important difference of not changing the original data frame.
level_order <- c('virginica', 'versicolor', 'setosa') #this vector might be useful for other plots/analyses
ggplot(iris, aes(x = factor(Species, level = level_order), y = Petal.Width)) + geom_col()
or
level_order <- factor(iris$Species, level = c('virginica', 'versicolor', 'setosa'))
ggplot(iris, aes(x = level_order, y = Petal.Width)) + geom_col()
edit:
or directly in the aes() call without a pre-created vector:
ggplot(iris, aes(x = factor(Species, level = c('virginica', 'versicolor', 'setosa')), y = Petal.Width)) + geom_col()

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
OMG! I got it! Thanks so much, this was exactly what I needed! :) You just made my day.
– Lisa Ta
Oct 9 '12 at 2:13