ggplot2/colorbrewer qualitative pallette with 125 categories
Asked Answered
N

1

6

I have data as follows:

  • 10 states
  • Each state has two types
  • Each type has between 1 and 29 entities
  • Each state-entity-type has a count

Complete data available as a gist.

I'm trying to visualize what proportion of the counts were made for each entity. To do that, I've used the following code:

icc <- transform( icc, state=factor(state), entity=factor(entity), type=factor(type) )
p <- ggplot( icc, aes( x=state, y=count, fill=entity ) ) +
  geom_bar( stat="identity", position="stack" ) +
  facet_grid( type ~ . )
custom_theme <- theme_update(legend.position="none")
p

plot

Unfortunately, I'm losing a lot of information because state-types with lots of entities aren't displaying enough unique colors.

As mentioned above, I have 125 entities, but the most entities in a state-type is 29. Is there a way to force ggplot2 and colorbrewer to assign a unique (and hopefully fairly distinct) color within each entity-type?

The only way I've come up with so far is to coerce entity to an integer, which works but doesn't provide much color differentiation between levels.

Northrop answered 8/2, 2013 at 15:22 Comment(4)
@Arun Producing such a pallette with a nice diverging scheme is non-trivial (might be a good answer, wink wink). Need to run a color brewer on the entities each state-type (itself problematic, since most pallettes choke on more than about 12, it seems), then put it in the right order.Northrop
It's very difficult to come up with 29 distinct colours. Why not just label the entities with text?Stinky
@Stinky Noted. Text would be great, but is likely to end up a jumbled mess. I guess my requirement is actually much simpler: the colors don't even have to be unique within a state-type, just alternating. I can try something like scale_fill_manual( values=c(rep(c('red','blue'),125/2),'red') ), but then they're not guaranteed to be alternating within each bar.Northrop
You could probably create a new variable with alternate <- function(x) factor(match(x, unique(x)) %% 2)), and apply it within groups with ave: ave(entity, state, FUN = alternate) (untested)Stinky
L
6

Here's an approach that gives you a little more information. Take the color wheel generated by rainbow, and for every other color, swap it with the opposite one on the wheel.

col <- rainbow(30)
col.index <- ifelse(seq(col) %% 2, 
                    seq(col), 
                    (seq(ceiling(length(col)/2), length.out=length(col)) %% length(col)) + 1)
mixed <- col[col.index]

p <- ggplot(icc, aes(x=state, y=count, fill=entity)) +
  geom_bar(stat="identity", position="stack") +
  facet_grid( type ~ . ) + 
  scale_fill_manual(values=rep(mixed, length.out=nrow(icc)))

custom_theme <- theme_update(legend.position='none')
p

enter image description here

Lots answered 8/2, 2013 at 20:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.