Question

I have an R dataframe object in Python, using Rpy2, that looks like this:

cat name num
1   a  bob   1
2   b  bob   2
3   a mary   3
4   b mary   4

I want to plot it as a geom_bar with flipped coords, and have the order of the bars match the order of the legend (without changing the legend). This has been asked on here and other mailing lists, but I am stuck on how to translate the R ordering code to rpy2. This is my current code:

# attempting to reorder bars so that value 'a' of cat is first (in red)
# and value 'b' of cat is second (in green)
labels = tuple(["a", "b"])
labels = robj.StrVector(labels)
variable_i = r_df.names.index("cat")
r_df[variable_i] = robj.FactorVector(r_df[variable_i],
                                     levels=labels)
r.pdf("test.pdf"))
p = ggplot2.ggplot(r_df) + \
    ggplot2.geom_bar(aes_string(x="name",
                                y="num",
                                fill="cat"),
                     position=ggplot2.position_dodge(width=0.5)) + \
    ggplot2.coord_flip()
p.plot()

this gives a graph that has the correct legend ('a' is first in red, 'b' is second in green) but the bars appear in the order green/red ('b', 'a') for each value of 'name'. my impression from prev. posts is that this is because coord_flip() flips the order. how can I change the bars order (not legend order) to match the current legend, plotting red bars first in each dodged bar group? thanks.

edit:*

tried @joran's solution in rpy2:

labels = tuple(["a", "b"])
labels = robj.StrVector(labels[::-1])
variable_i = r_df.names.index("cat")
r_df[variable_i] = robj.FactorVector(r_df[variable_i],
                                     levels=labels)
p = ggplot2.ggplot(r_df) + \
    ggplot2.geom_bar(aes_string(x="name",
                                y="num",
                                fill="cat"),
                     stat="identity",
                     position=ggplot2.position_dodge()) + \
    ggplot2.scale_fill_manual(values = np.array(['blue','red'])) + \
    ggplot2.guides(fill=ggplot2.guide_legend(reverse=True)) + \
    ggplot2.coord_flip() 
p.plot()

this doesn't work because ggplot2.guides is not found, but that's only for setting the legend. My question is: why is the scale_fill_manual necessary? I don't want to specify my own colors, I want the default ggplot2 colors, but I just want to set the ordering to be a particular way. It makes sense that with coord_flip I'd need a reverse ordering but that is not enough to reorder the bars apparently (see my labels[::-1]) independently of the legend. thoughts on this?

Was it helpful?

Solution

I apologize I do not have rpy setup on my machine, but I was able to get what I think you are describing with this R/ggplot2 code:

dat$cat <- factor(dat$cat,levels = c('b','a'))

ggplot(dat,aes(x = name,y = num, fill = cat)) + 
    geom_bar(stat = "identity",position = "dodge") + 
    coord_flip() + 
    scale_fill_manual(values = c('blue','red')) +
    guides(fill = guide_legend(reverse = TRUE))

enter image description here

Basically, I just reversed the factor levels, and reversed the legend order. Convoluted, but it looks like what you described. (Also, you did want stat = "identity", right?)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top