0

I am trying to change the factor level ordering of a data frame column to control the legend ordering and ggplot coloring of factor levels specified by country name. Here is my dataframe country_hours:

  countries hours    
1    Brazil    17 
2    Mexico    13
3    Poland    20 
4 Indonesia     2 
5    Norway    20 
6    Poland    20 

Here is how I try to plot subsets of the data frame depending on a list of selected countries, user_countries:

make_country_plot<-function(user_countries, country_hours_pre)
{
  country_hours = country_hours_pre[which(country_hours_pre$countries %in% user_countries) ,]
  country_hours$countries = factor(country_hours$countries, levels = c(user_countries))            

  p = ggplot(data=country_hours, aes(x=hours, color=countries))
  for(name in user_countries){
    p = p  +   geom_bar( data=subset(country_hours, countries==name), aes(y = (..count..)/sum(..count..), fill=countries), binwidth = 1, alpha = .3)
  }
  p = p  + scale_y_continuous(labels = percent) + geom_density(size = 1, aes(color=countries), adjust=1) +
  ggtitle("Baltic countries") + theme(plot.title = element_text(lineheight=.8, face="bold")) + scale_fill_discrete(breaks = user_countries)

}

This works great in that the coloring goes according to my desired order as does the top legend, but a second legend appears and shows a different order. Without scale_fill_discrete(breaks = user_countries) I do not get my desired order, but I also do not get two legends. In the plot shown below, the desired order, given by user_countries was

user_countries = c("Lithuania", "Latvia", "Estonia")

enter image description here

I'd like to get rid of this second legend. How can I do it?

I also have another problem, which is that the plotting/coloring is inconsistent between different plots. I'd like the "first" country to always be blue, but it's not always blue. Also the 'real' legend (darker/solid colors) is not always in the same position - sometimes it's below the incorrect/black legend. Why does this happen and how can I make this consistent across plots?

Also, different plots have different numbers of factor groups, sometimes more than 9, so I'd rather stick with standard ggplot coloring as most of the solutions for defining your own colors seem limited in the number of colors you can do (How to assign colors to categorical variables in ggplot2 that have stable mapping?)

Community
  • 1
  • 1
Cauchy Kun
  • 177
  • 2
  • 11
  • Try to add `+ theme(legend.position="none")` in the part of the definition of the plot that you want to be shown without legend. Without reproducible data I can't be sure that it will work, but I believe it's worth a try. – RHertel Jun 25 '15 at 20:29

2 Answers2

3

You are mapping to two different aesthetics (color and fill) but you changed the scale specifications for only one of them. Doing this will always split a previously combined legend. There is a nice example of this on this page

To keep your legends combined, you'll want to add scale_color_discrete(breaks = user_countries) in addition to scale_fill_discrete(breaks = user_countries).

aosmith
  • 34,856
  • 9
  • 84
  • 118
1

I don't have enough reputation to comment, but this previous question has a comprehensive answer.

Short answer is to change geom_density so that it doesn't map countries to color. That means just taking everything inside the aes() and putting it outside.

geom_density(size = 1, color=countries, adjust=1)

(This should work. Don't have an example to confirm).

Community
  • 1
  • 1
oshun
  • 2,319
  • 18
  • 32