ggplot2: sorting a plot
I have a data.frame, that is sorted from highest to lowest. For example:
x <- structure(list(variable = structure(c(10L, 6L, 3L, 4L, 2L, 8L,
9L, 5L, 1L, 7L), .Label = c("a", "b", "c", "d", "e", "f", "g",
"h", "i", "j"), class = c("ordered", "factor")), value = c(0.990683229813665,
0.975155279503106, 0.928571428571429, 0.807453416149068, 0.717391304347826,
0.388198757763975, 0.357142857142857, 0.201863354037267, 0.173913043478261,
0.0496894409937888)), .Names = c("variable", "value"), row.names = c(10L,
6L, 3L, 4L, 2L, 8L, 9L, 5L, 1L, 7L), class = "开发者_开发问答data.frame")
ggplot(x, aes(x=variable,y=value)) + geom_bar(stat="identity") +
scale_y_continuous("",label=scales::percent) + coord_flip()
Now, the data is nice and sorted, but when I plot, it comes out sorted by factor. It's annoying, how do I fix it?
This seems to be what you're looking for:
g <- ggplot(x, aes(reorder(variable, value), value))
g + geom_bar() + scale_y_continuous(formatter="percent") + coord_flip()
The reorder()
function will reorder your x axis items according to the value
of variable
.
Here are a couple of ways.
The first will order things based on the order seen in the data frame:
x$variable <- factor(x$variable, levels=unique(as.character(x$variable)) )
The second orders the levels based on another variable (value in this case):
x <- transform(x, variable=reorder(variable, -value) )
I've recently been struggling with a related issue, discussed at length here: Order of legend entries in ggplot2 barplots with coord_flip() .
As it happens, the reason I had a hard time explaining my issue clearly, involved the relation between (the order of) factors and coord_flip(), as seems to be the case here.
I get the desired result by adding + xlim(rev(levels(x$variable)))
to the ggplot statement:
ggplot(x, aes(x=variable,y=value)) + geom_bar() +
scale_y_continuous("",formatter="percent") + coord_flip()
+ xlim(rev(levels(x$variable)))
This reverses the order of factors as found in the original data frame in the x-axis, which will become the y-axis with coord_flip(). Notice that in this particular example, the variable also happen to be in alphabetical order, but specifying an arbitrary order of levels within xlim()
should work in general.
I don't know why this question was reopened but here is a tidyverse
option.
x %>%
arrange(desc(value)) %>%
mutate(variable=fct_reorder(variable,value)) %>%
ggplot(aes(variable,value,fill=variable)) + geom_bar(stat="identity") +
scale_y_continuous("",label=scales::percent) + coord_flip()
You need to make the x-factor into an ordered
factor with the ordering you want, e.g
x <- data.frame("variable"=letters[1:5], "value"=rnorm(5)) ## example data
x <- x[with(x,order(-value)), ] ## Sorting
x$variable <- ordered(x$variable, levels=levels(x$variable)[unclass(x$variable)])
ggplot(x, aes(x=variable,y=value)) + geom_bar() +
scale_y_continuous("",formatter="percent") + coord_flip()
I don't know any better way to do the ordering operation. What I have there will only work if there are no duplicate levels for x$variable
.
精彩评论