I am using ggplot to plot Proportional Stacked Bar plot. And the Plot I am getting is something like this:
And this is the self written function I am using:
df <- data.frame(id=letters[1:3],val0=1:3,val1=4:6,val2=7:9, val3=2:4, val4=1:3, val5=4:6, val6=10:12, val7=12:14)
PropBarPlot<-function(df, mytitle=""){
melteddf<-melt(df, id=names(df)[1], na.rm=T)
ggplot(melteddf, aes_string(x=names(df)[1], y="value", fill="variable")) +
geom_bar(position="fill") +
theme(axis.text.x = element_text(angle=90, vjust=1)) +
labs(title=mytitle)
}
print(PropBarPlot(df))
Here val4
and val5
are not very different.
But due to colors some of them are not distinguishable. Can someone tell me how to choose better colors so that they are differentiable?
Thanks.
Key functions to change gradient colors The default gradient colors can be modified using the following ggplot2 functions: scale_color_gradient() , scale_fill_gradient() for sequential gradients between two colors. scale_color_gradient2() , scale_fill_gradient2() for diverging gradients.
Change ggplot colors by assigning a single color value to the geometry functions ( geom_point , geom_bar , geom_line , etc). You can use R color names or hex color codes. Set a ggplot color by groups (i.e. by a factor variable). This is done by mapping a grouping variable to the color or to the fill arguments.
Format cells by using color scalesOn the Home tab, click Conditional Formatting. Point to Color Scales, and then click the color scale format that you want. The top color represents larger values, the center color, if any, represents middle values, and the bottom color represents smaller values.
How about using scale_fill_brewer
which makes use of colour palettes from the ColorBrewer
website, implemented by the package RColorBrewer
?
ggplot(diamonds, aes(clarity, fill=cut) ) +
geom_bar( ) +
scale_fill_brewer( type = "div" , palette = "RdBu" )
There are a number of different diverging palettes you can choose from.
require(RColorBrewer)
?brewer.pal
If you need more colours you can use the colorRampPalette
features to interpolate between some colours (and I would use a brewer.pal
palette for this). You can do this like so:
# Create a function to interpolate between some colours
mypal <- colorRampPalette( brewer.pal( 6 , "RdBu" ) )
# Run function asking for 19 colours
mypal(19)
[1] "#B2182B" "#C2373A" "#D35749" "#E47658" "#F0936D" "#F4A989" "#F8BFA5"
[8] "#FCD6C1" "#F3DDD0" "#E7E0DB" "#DAE2E6" "#CBE1EE" "#ADD1E5" "#90C0DB"
[15] "#72AFD2" "#5B9DC9" "#478BBF" "#3478B5" "#2166AC"
In your example which requires 8 colours you an use it like this with scale_fill_manual()
:
PropBarPlot<-function(df, mytitle=""){
melteddf<-melt(df, id=names(df)[1], na.rm=T)
ggplot(melteddf, aes_string(x=names(df)[1], y="value", fill="variable")) +
geom_bar(position="fill") +
theme(axis.text.x = element_text(angle=90, vjust=1)) +
labs(title=mytitle)+
scale_fill_manual( values = mypal(8) )
}
print(PropBarPlot(df))
Borrowing some code from @SimonO101
library(ggplot2)
library(reshape2)
library(RColorBrewer)
mypal <- colorRampPalette( brewer.pal( 9 , "Set1" ) ) #you can try using different palete instead
#of "Set1" until it looks good to you
intercalate <- function(n){ #my crude attempt to shuffle the colors
c(rbind(1:(n/2), n:(n/2+1))) #it will only work for even numbers
}
PropBarPlot<-function(df, mytitle=""){
melteddf<-melt(df, id=names(df)[1], na.rm=T)
ggplot(melteddf, aes_string(x=names(df)[1], y="value", fill="variable")) +
geom_bar(position="fill") +
theme(axis.text.x = element_text(angle=90, vjust=1)) +
labs(title=mytitle)+
scale_fill_manual( values = mypal(8)[intercalate(8)] )
#better would be to calculate the different number of categories
#you have and put that instead of the number 8
}
df <- data.frame(id=letters[1:3],
val0=1:3,
val1=4:6,
val2=7:9,
val3=2:4,
val4=1:3,
val5=4:6,
val6=10:12,
val7=12:14)
print(PropBarPlot(df))
See if that works better for your needs.
Thanks @zelite and @SimonO101 for your help. This is simpler version of what both of you proposed. Adding here for the completeness.
library(ggplot2)
library(reshape2)
library(RColorBrewer)
getColors<-function(n){
mypal<-colorRampPalette(brewer.pal(12, "Paired"))
sample(mypal(n), n, replace=FALSE)
}
PropBarPlot<-function(df, mytitle=""){
melteddf<-melt(df, id=names(df)[1], na.rm=T)
n<-length(levels(factor(melteddf$variable)))
ggplot(melteddf, aes_string(x=names(df)[1], y="value", fill="variable")) +
geom_bar(position="fill") +
scale_fill_manual(values=getColors(n)) +
theme(axis.text.x = element_text(angle=90, vjust=1)) +
labs(title=mytitle)
}
df <- data.frame(id=letters[1:3],
val0=1:3,
val1=4:6,
val2=7:9,
val3=2:4,
val4=1:3,
val5=4:6,
val6=10:12,
val7=12:14)
print(PropBarPlot(df))
Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With