ggplot2: separate color scale per facet - r

Intuitively I'm looking for something like: facet_(scales="free_color")
I do something like
p <- ggplot(mpg, aes(year, displ, color=model)) + facet_wrap(~manufacturer)
p + geom_jitter()
That is: plot 2d measurements from individuals(model) belonging to different species(manufacturer) faceted by a species, indicating the individual by color.
The problem is that all individuals share the same color scale - so that the points in a facet have very similar colors.
Using the group aesthetic with geom_line would solve the problem, but lines tell different story than dots.
Another obvious solution would be to drop the faceting and draw a separate plot for each subset. (If this should be the only solution: are there any quick, smart or proven ways to do that?)

I'm not sure that this is an available option when you're colouring by a factor. However, a quick way to produce the individual plots would be something like this:
d_ply(mpg, .(manufacturer), function(df) {
jpeg(paste(df$manufacturer[[1]], ".jpeg", sep=""))
plots <- ggplot(df, aes(year, displ, color=factor(model))) + geom_jitter()
print(plots)
dev.off()
})
Related Answers:
Different legends and fill colours for facetted ggplot?

I think you simply want to color by class, where each manufacturer makes several models, each only one or two per class:
p <- ggplot(mpg, aes(year, displ, color=class)) + facet_wrap(~ manufacturer)
p + geom_jitter()

Related

ggplot: How to display multiple groups via color and shape with point and line

I want to draw a point-line chart of x-y-variables and highlight two groupings. I know some of the options to distinguish factors, like fill, shape, col or group. For the first group I would like to have color and for the second shape (which may or may not have the same color). And I need a legend to distinguish both groupings (which I already have). Perhaps I have to put aes in geom_line or geom_point, but I'm not sure. Since later on I would like to adjust size of the shapes (to better distinguish those).
How to connect those points by colored lines?
How to adjust size of the shape group?
Here is my code:
library(ggplot2)
data <- data.frame(id1=c(1,1,1,2,2,2,3,3,3,4,4,4),
id2=seq(1:3), year=seq(from=2007, to=2018, by=1),
variable=rep(c(5:8), each=3))
# two groups by color and shape, but it drops the line (seperate legends, thats nice)
ggplot(data, aes(x=year, y=variable, col=factor(id1), shape=factor(id2))) +
geom_line() + geom_point()
Based on further information in comments from the OP, we are looking for something like this:
ggplot(data, aes(x=year, y=variable, col=factor(id1))) +
geom_line() +
geom_point(aes(shape=factor(id2), size = factor(id2))) +
labs(shape = "group 2", colour = "group 1", size = "group 2")

scale_color_brewer (ggplot2) does not colour all the lines

When running this ggplot2 code:
ggplot(canine_lower, aes(x=x, y=y, colour=Teeth)) +
geom_smooth(method="lm", formula= y~poly(x,4), se=FALSE) +
scale_color_grey(start=0.9, end=0.1)
I get this plot thanks to the scale_color_grey function:
There is a gradual grey transition among all groups of teeth (from 1 to 16).
However, I would like to colourize it. For this reason I employed the scale_color_brewer, with partly success. The run code is:
ggplot(canine_lower, aes(x=x, y=y, colour=Teeth)) +
geom_smooth(method="lm", formula= y~poly(x,4), se=FALSE)+
scale_color_brewer(palette="Reds")
which offers this unfinished plot:
As seen above, from 10 to 16 there is no color.
How can I span the color range using this function? Is there any other alternative function?
I must say that I tried with scale_color_gradient with no success.
The maximum number of colors from brewer.pal (in the package RColorBrewer), the function scale_color_brewer uses to generate the colors, is 9 for sequential palettes. If you look at the help for brewer.pal you can check the maximum number of colors for each of the palette types.
You can generate larger palettes in many other ways, such as scale_color_viridis as shown by #NateDay, or with the two examples below, but it will be difficult to distinguish so many different colors in the graph.
mtcars$rowname=rownames(mtcars)
ggplot(mtcars[1:16, ], aes(mpg, hp, color=rowname)) +
geom_point() +
scale_colour_manual(values=hcl(seq(0,360,length=17)[1:16], 100,65))
ggplot(mtcars[1:16, ], aes(mpg, hp, color=rowname)) +
geom_point() +
scale_colour_manual(values=hcl(0,100,seq(40,100,length=16)))
you could use library(viridis) as an alternative:
# a reproducible example
mtcars <- add_rownames(mtcars)
ggplot(mtcars, aes(mpg, hp, color = rowname)) +
geom_point() +
viridis::scale_color_viridis(discrete = TRUE)
scale_color_gradient() is failing you because it is designed to be used to map to continuous values, not discrete ones.

modifying ggplot objects after creation

Is there a preferred way to modify ggplot objects after creation?
For example I recommend my students to save the r object together with the pdf file for later changes...
library(ggplot2)
graph <-
ggplot(mtcars, aes(x=mpg, y=qsec, fill=cyl)) +
geom_point() +
geom_text(aes(label=rownames(mtcars))) +
xlab('miles per galon') +
ggtitle('my title')
ggsave('test.pdf', graph)
save(graph, file='graph.RData')
So new, in case they have to change title or labels or sometimes other things, they can easily load the object and change simple things.
load('graph.RData')
print(graph)
graph +
ggtitle('better title') +
ylab('seconds per quarter mile')
What do I have to do for example to change the colour to discrete scale? In the original plot I would wrap the y in as.factor. But is there a way to do it afterwards?
Or is there a better way on modifying the objects, when the data is gone. Would love to get some advice.
You could use ggplot_build() to alter the plot without the code or data:
Example plot:
data("iris")
p <- ggplot(iris) +
aes(x = Sepal.Length, y = Sepal.Width, colour = Species) +
geom_point()
Colours are respective to Species.
Disassemble the plot using ggplot_build():
q <- ggplot_build(p)
Take a look at the object q to see what is happening here.
To change the colour of the point, you can alter the respective table in q:
q$data[[1]]$colour <- "black"
Reassemble the plot using ggplot_gtable():
q <- ggplot_gtable(q)
And plot it:
plot(q)
Now, the points are black.

R Order of stacked areas with ggplot geom_area

I needed to reinstall R and I now encounter a little problem with ggplot. I am sure there is a simple solution to it and I appreciate all hints!
I am using the stacked area plot quite often, and usually I got the desired stacking and legend order by defining the factor levels and plotting in reverse order. However, this is not working any more after the re-installation.
Here is an example:
dx <- data.frame(x=rep(1:8,3),y=rep(c(2,3,2,4,3,5,3,2),3),z=c(rep("bread",8),rep("butter",8),rep("fish",8)))
ggplot() + geom_area(data=dx, aes(x=x, y=y, fill=z, order=-as.numeric(z)))
This gives the following plot:
It looks as if "order" did not have any impact on the plot.
The desired plot would stack the areas as shown in the legend, i.e. red area on top, blue area at the bottom.
Where is my mistake?
Many thanks in advance!
You can either use (the colors will also be reversed):
dx$z <- factor(dx$z, levels = rev(levels(dx$z)))
ggplot() + geom_area(data=dx, aes(x=x, y=y, fill=z))
Or directly use this (without reversing the factor levels, which won't change the color):
ggplot() + geom_area(data=dx, aes(x=x, y=y, fill=z)) +
guides(fill = guide_legend(reverse=TRUE))

ggplot: adjusting alpha/fill two factors cdf

I'm having some issues getting my ggplot alpha to be sufficiently dark for my plot.
Example code:
ggplot(mtcars, aes(x=mpg, color=factor(gear), alpha=factor(carb))) + stat_ecdf()
As you can see, whenever carb == 1, it's very difficult to see the plot elements. In my real world data set, the factor for color has four levels and the alpha factor has two levels. I was hoping to have the alpha a slightly lighter shade of the color, but more visible than how it's occurring in that example).
You can adjust the alpha scale, as the user in the comment suggests, either by specifying a range or a specific set breaks to scale_alpha_discrete. That doesn't produce a very easy-to-read result, though:
ggplot(mtcars, aes(x=mpg, color=factor(gear), alpha=factor(carb))) +
stat_ecdf() +
scale_alpha_discrete(range=c(0.4, 1))
Another option would be to save color for the many-leveled factor and choose a different aesthetic for the few-leveled one, like maybe linetype
ggplot(mtcars, aes(x=mpg, linetype=factor(gear), color=factor(carb))) +
stat_ecdf()
For readability, though, faceting might be a better bet.
ggplot(mtcars, aes(x=mpg, color=factor(carb))) +
stat_ecdf() + facet_wrap(~gear, nrow=3)

Resources