Can I use direct.label() with ggplot's scale_colour_manual()? - r

The following code assigns a manual color scale of red and black to my points:
require(ggplot2)
require(directlabels)
dtest <- data.frame(x=1:20,
y=rnorm(20,0,5),
v=seq(1,2))
p <- ggplot(dtest, aes(x=x,y=y,color=as.factor(v))) + geom_point() + scale_colour_manual(values=c("red","black"))
p #this looks good; red and black as intended
direct.label(p) #this falls back on the default colors
But when I apply direct.label() to the same plot, it overrides the color scale in favor of the ggplot default. Is there a way to prevent this? If not, what's the best way to assign new colors to the default ggplot scale?
Thanks,
Matt

This happens because direct.label(p) operates by adding the label geom to p, then by hiding the color legend, since labeling the colors twice would be redundant. One way to hide the color legend is by adding scale_colour_discrete(legend=FALSE), and this is what I do inside of direct.label. So when directlabels applies scale_colour_discrete, your scale_colour_manual will be lost. The workaround is to use the following idiom:
p <- ggplot(...)
direct.label(p)+
scale_colour_manual(...)

Related

Strange line connection using ggplot geom_line colours

A problem occurs when i add a colour(gradient) into the aesthetics of geom_line. It seems that the dots are no longer connected by a line but instead transformed into squares, which messes up the plot. Does anyone have an idea how to solve this problem or if this is how R or ggplot handles colour(gradients). This problem doesn't occur, when i remove the colours from the aes().
Thanks in advance!
Simple code:
df <- data.frame(c(1,3,4,2,5,8),c(1,2,3,4,5,6))
colnames(df) <- c("x","y")
ggplot()+
theme_classic()+
geom_line(data=df,aes(x=x,y=y,colour=y),size=2)
ggplot()+
theme_classic()+
geom_line(data=df,aes(x=x,y=y),size=2)
Adjusting the lineend parameter should do it, which has a default of "square". The reason the uncolored version looks okay is that in those cases the segments are treated as continuations of the same series, so they are governed then by the linejoin parameter, which has a default of "round."
ggplot()+
theme_classic()+
geom_line(data=df,aes(x=x,y=y,colour=y),size=2, lineend = "round")
PS - if you want the color to vary within each segment, you might look at alternatives like ggforce::geom_link2, which uses interpolation to allow smooth transitions. However, it's parameterized differently, to be like geom_path, which plots data in order of appearance rather than in order of the x value, like geom_line.

Manual coloring of dots by set color in Complex Upset

I would like to create an UpSet plot using the ComplexUpset package. I would like to manually color the dots in the intersection matrix to match the sets' color.
Here's what I've attempted so far:
movies <- read.csv( system.file("extdata", "movies.csv", package = "UpSetR"), header=T, sep=";" )
ComplexUpset::upset(movies, colnames(movies)[3:5], name='genre', width_ratio=0.1,
matrix=(intersection_matrix(geom=geom_point()) +
scale_color_manual(values = c('Action'='red', 'Adventure'='blue', 'Children'='yellow'))),
queries=list(upset_query(set='Action', fill='red'),
upset_query(set='Adventure', fill='blue'),
upset_query(set='Children', fill='yellow')))
Adding scale_color_manual only resulted in an extra legend of dots that was plotted which I do not want. I would like the dots, in the intersection matrix itself, for 'Action' to be red, the dots for 'Adventure' to be blue and the dots for 'Children' to be yellow. The segment line connecting the dots should remain black.
The dots don't change color because you are passing fill (not color) to upset_query; you can keep using fill if you like but in that case you need to also change the shape of the dot so that they have area to be filled, which can be done using shape='circle filled' (there are other shapes too!).
Similarly, the scale_color_manual would not be a perfect choice in plain ggplot2, but given that it is overridden by ComplexUpset it is actually a good idea, but you will need to customize override.aes to make it display as intended.
library(ComplexUpset)
library(ggplot2)
upset(
movies,
colnames(movies)[3:5],
name='genre',
width_ratio=0.1,
matrix=(
intersection_matrix(geom=geom_point(shape='circle filled', size=3))
+ scale_color_manual(
values=c('Action'='red', 'Adventure'='blue', 'Children'='yellow'),
guide=guide_legend(override.aes=list(shape='circle'))
)
),
queries=list(
upset_query(set='Action', fill='red'),
upset_query(set='Adventure', fill='blue'),
upset_query(set='Children', fill='yellow')
)
)
Alternatively, you could simply pass color in addition to fill, but I think that the fill option give nicer visuals.

ggplot2, why so blue? How to set a different color palette in gradient

Why doesn't this pick up the green colors? It stays blue...
require(ggplot2)
data(iris)
ggplot(iris,aes(Sepal.Length,Sepal.Width,col=Petal.Length,pch=Species,size=Petal.Width))+
scale_fill_gradient(low="green",high="darkgreen")+
ggtitle('Why so blue?')+geom_point()
Any suggestions?
You've used scale_fill_gradient(), yet your aes() contains a color argument. Try scale_color_gradient() instead.
data(iris)
ggplot(iris,aes(Sepal.Length,Sepal.Width,
col=Petal.Length,pch=Species,size=Petal.Width))+
scale_color_gradient(low="green",high="darkgreen")+
ggtitle('Now so green')+geom_point()
Output:
Explanation:
Whether to use scale_fill or scale_color is determined by the arguments supplied to the aes() portion of ggplot code. Color arguments are typically used for things like geom_point() and geom_line(); fill arguments are typically used for the color of bars in a bar graph for example.

Change contour colours using directlabels

I'm fairly new to ggplot2, and I'm trying to create a contour plot of data that has missing values. Because there's missing values I can't have the contours by themselves, so I'm combining a tiles background with a contour. The problem is the labels are the same colour as the background.
Suppose I have data like so:
DF1 <- data.frame(x=rep(1:3,3),y=rep(1:3,each=3),z=c(1,2,3,2,3,4,3,NA,NA))
I can make a plot like this:
require(ggplot2); require(directlabels)
plotDF <- ggplot(DF1,aes(x,y,z=z)) + geom_tile(aes(fill=z)) + stat_contour(aes(x,y,z=z,colour= ..level..),colour="white")
direct.label(plotDF)
This gives me a plot similar to what I want but I'd like to be able to change the colours of the labels to be black. Any ideas?
I spotted a similar post and thought this would be easy, something along the lines of direct.label(p, list("last.points", colour = "black"). I could not make it work, unfortunately; I believe, this is not directly supproted.
I then decided to use black magic and managed to do the trick by manually overriding the colour scale:
direct.label(plotDF +
scale_colour_gradient(low="black", high="black"))

Unusual legend using size mapping and density2d

I am trying to make a scatterplot in ggplot2 with a size mapping to a third variable and density2d contours. It seems as if the legend is being confused by the inclusion of density2d contours.
For example, the following code works:
library('ggplot2')
set.seed(1)
x=rnorm(100); y=rnorm(100,sd=10); z=seq(1,10,length.out=100)
dd=data.frame(x=x,y=y,z=z)
ggplot(dd,aes(x,y,size=z))+geom_point()
But now, note the legend behaves unusually when I add in a call to stat_density2d(). In particular, the plot legend shows blue blocks instead of black circles:
ggplot(dd,aes(x,y,size=z))+geom_point()+stat_density2d()
As size= is one of the aesthetics you can set for the stat_density2d() and in this case it is set in ggplot() call, legend is made for both - lines and points (points are hided under lines in legend as geom_point() is called before stat_density2d()). To remove blue lines from legend, you can set manually size=0.5 (or some other value) inside the stat_density2d() and then legend will be correct.
ggplot(dd,aes(x,y,size=z))+geom_point()+stat_density2d(size=0.5)

Resources