Slight point strokes in ggplot points - r

Consider the following:
library(ggplot2)
df = data.frame(x = rep(0,9), y = rep(0,9), alp = c(1:8/20,1))
ggplot(df) +
geom_point(aes(x, y, alpha=alp), size = 20, col = 'red') +
theme_minimal() + facet_wrap(~ alp) + guides(alpha = F)
As you can see there are feint outlines. It makes overlaying many low-transparency points look a bit like frogspawn. Is this just a Mac thing? Any idea how to remove it?

The default point shape for ggplot2 is pch = 19. It's not one of those points where the colour of its border and its inside can be controlled separately; for instance, in the following, fill = 'black' has no effect.
library(ggplot2)
df = data.frame(x =runif(1000), y = runif(1000))
p = ggplot(df) +
geom_point(aes(x, y), alpha = .1, size = 5, fill = 'black', colour = 'red') +
theme_bw()
p
Yet the point does have a boundary line. The line's width can be changed with stroke; as follows:
p = ggplot(df) +
geom_point(aes(x, y), stroke = 2, alpha = .1, size = 5, fill = 'black', colour = 'red') +
theme_bw()
p
Unfortunately, setting stroke to zero will not remove the boundary line; it seems there is a lower limit.
To remove the boundary line, use one of the shapes that has a border that can be manipulated; for instance, shape = 21. Set its "fill" to red and its "colour" to transparent.
p = ggplot(df) +
geom_point(aes(x, y), shape = 21, alpha = .1, size = 5, fill = 'red', colour = 'transparent') +
theme_bw()
p

see::geom_point2 draws points without this border.
library(ggplot2)
library(see)
df = data.frame(x = rep(0,9), y = rep(0,9), alp = c(1:8/20,1))
ggplot(df) +
geom_point2(aes(x, y, alpha=alp), size = 20, col = 'red') +
theme_minimal() + facet_wrap(~ alp) + guides(alpha = F)
Created on 2020-05-14 by the reprex package (v0.3.0)

Related

Add label to geom_vline within a ggplot2 figure

so far I can manage to build the following geom_density figure using ggpot2:
cuts1 <- data.frame(Ref="p", vals=c(140))
cuts2 <- data.frame(Ref="s", vals=c(300))
cuts3 <- data.frame(Ref="m", vals=c(250))
cuts <- rbind(cuts1, cuts2, cuts3)
ggplot(mtcars, aes(x=disp)) +
geom_density(color = "black",
fill = 4,
alpha = 1) +
geom_vline(data = cuts , aes(xintercept=vals, color= Ref) )
And I wondered if someone knew a way to plot the geom_vline much more like that :
Where the lines do not reach the top and bottom of the figure and where the labels are all displayed with a rotation.
Here is one potential solution:
library(ggplot2)
cuts1 <- data.frame(Ref="p", vals=c(140))
cuts2 <- data.frame(Ref="s", vals=c(300))
cuts3 <- data.frame(Ref="m", vals=c(250))
cuts <- rbind(cuts1, cuts2, cuts3)
ggplot(mtcars, aes(x=disp)) +
geom_density(color = "black",
fill = 4,
alpha = 1) +
geom_segment(data = cuts, aes(x=vals, xend = vals,
y = 0, yend = max(density(mtcars$disp)[[2]]),
color= Ref), key_glyph = "vpath") +
geom_text(data = cuts, aes(x = vals, y = max(density(mtcars$disp)[[2]]) * 1.02,
label = Ref), nudge_x = 5, angle = 45)
Created on 2022-08-29 by the reprex package (v2.0.1)
Take a look at geom_segment, you can set the yend parameter to where you want your lines to end.

How to put a black border around certain dots on a ggplot geom_point plot

I am trying to make a geom plot using ggplot for some pathways of interest. I would like to put a black border around certain dots that are significant. -log10 > 1.2, so they are easier to identify. Is there anyway to do this in the package so I do not have to do in an illustrator package after I have produced the image? Thank you kindly for advice.
Image of current dot image:
Image of raw data:
cols <- c("blue",
"white",
"red")
li <- c(-2, 2)
D1 <- ggplot(Practice, aes(Practice$case, Practice$pathway,
colour = Enrichment_score, size = Practice$ln)) +
geom_point(alpha = 0.8) +
scale_colour_gradientn(colours = cols) +
theme(legend.position="bottom") +
scale_size(breaks = c(0, 1.2, 1.4), range = c(0.06,12)) +
guides(size=guide_legend(title = "-log10(q value)"),
scale_colour_gradient()) +
labs(colour = "Enrichment Score") +
theme_bw()
D1 + ggtitle("") +
xlab("") + ylab("") +
scale_x_discrete(limits=c("Responder vs Non-responder",
"Non-responder vs Control",
"Responder vs Control",
"Case vs Control"))
Since I do not have your original data, and you don't have an example graph, I'll use diamonds to see if this is want you want.
To "circle" the data point that you want to highlight, we can use an extra geom_point, and use some subset of data in it.
In your case, the subset can be like geom_point(data = subset(Practice, -log10(Enrichment_score) > 1.2), col = "black", stroke = 3, shape = 21).
library(tidyveres)
cols <- c("blue", "white", "red")
ggplot(diamonds, aes(cut, clarity,
colour = price, size = depth)) +
geom_point(alpha = 0.8) +
scale_colour_gradientn(colours = cols) +
theme(legend.position="bottom") +
scale_size(breaks = c(0, 1.2, 1.4), range = c(0.06,12)) +
guides(size=guide_legend(title = "-log10(q value)"),
scale_colour_gradient()) +
labs(colour = "Enrichment Score") +
theme_bw() +
geom_point(data = subset(diamonds, depth > 70), col = "black", stroke = 3, shape = 21)
Also, you don't need to use the dollar sign $ to specify column names in ggplot.
Another way, which may be simpler, is to use shape 21 with geom_point:
library(ggplot2)
ggplot(mtcars, aes(factor(cyl), mpg)) +
geom_point(shape = 21, stroke = 1, aes(colour = disp >= 250, fill = hp)) +
scale_colour_manual(values = c(`TRUE` = "black", `FALSE` = rgb(0,0,0,0)))
The manual colour scale makes the edge of shape 21 either black or transparent. Note the backticks for TRUE or FALSE.

GGplot generates two legends with a bubble plot, how to delete one of them

The following code block generates a plot with two legends:
Spend7d_bubble <- ggplot(cluster_visuals,
aes(x = ltv_7d, y = avg_daily_sessions,
color = factor(cluster8), size = n)) +
geom_point(alpha = 0.5) +
scale_size_continuous(range = c(2, 25))
Notice how this generates two legends on the right, one for n and one for factor(cluster8).
How can I only include the legend for factor(cluster8) and also rename it to just 'cluster'?
Spend7d_bubble <- ggplot(cluster_visuals,
aes(x = ltv_7d, y = avg_daily_sessions,
color = factor(cluster8), size = n)) +
geom_point(alpha = 0.5) +
scale_size_continuous(range = c(2, 25), guide = 'none') +
labs(color = "Cluster")
Whichever of those aesthetics (color or size) that you don't want a legend for, should be out of aes(). As you see, you don't have any legend for alpha in geom_point since it is not an argument of aes.
ggplot(cluster_visuals,
aes(x = ltv_7d, y = avg_daily_sessions, color = factor(cluster8)), size = n) +
geom_point(alpha = 0.5) +
scale_size_continuous(range = c(2, 25))

how to remove inclined lines added to legend?

How to remove inclined lines added to legend? And also the dots on the yellow and gray... Why is it happening?
library(ggplot2)
x <- seq(from = 1, to = 10, by = 1)
df = data.frame(x=x, y=x^2, v=2*x)
df2 = data.frame(x=x, y=x^2-5*x-10)
ggplot(df, aes(x, y)) +
geom_point(aes(size = v)) +
theme_classic() +
scale_size("blabla") +
geom_point(data=df2, aes(x, y, color = "blue")) +
geom_line(data=df2, aes(x, y, color = "blue")) +
geom_hline(aes(color="gray",yintercept=25)) +
geom_abline(aes(color="yellow", intercept=0, slope=1)) +
scale_color_manual(values = c("blue","gray","yellow"), labels = c("nanana","hhh","abab"), name = "other")
That's the legend for the color aesthetic and it tries to combine all the needed information for geom_point, geom_line, geom_hline, and geom_abline. To get rid of the lines, we instead need
geom_abline(aes(color = "yellow", intercept = 0, slope = 1), show.legend = FALSE)
while for the dots we have to add
guides(color = guide_legend(override.aes = list(shape = c(19, NA, NA))))
This gives

How to merge legends for color and shape when geom_hline has a separate (additional) entry in the color legend?

I have the following code, which produces the following plot:
cols <- brewer.pal(n = 3, name = 'Dark2')
p4 <- ggplot(all.m, aes(x=xval, y=yval, colour = Approach, ymax = 0.95)) + theme_bw() +
geom_errorbar(aes(ymin= yval - se, ymax = yval + se), width=5, position=pd) +
geom_line(position=pd) +
geom_point(aes(shape=Approach, colour = Approach), size = 4) +
geom_hline(aes(yintercept = cp.best$slope, colour = "C2P"), show_guide = FALSE) +
scale_color_manual(name="Approach", breaks=c("C2P", "P2P", "CP2P"), values = cols[c(1,3,2)]) +
scale_y_continuous(breaks = seq(0.4, 0.95, 0.05), "Test AUROC") +
scale_x_continuous(breaks = seq(10, 150, by = 20), "# Number of Patient Samples in Training")
p4 <- p4 + theme(legend.direction = 'horizontal',
legend.position = 'top',
plot.margin = unit(c(5.1, 7, 4.5, 3.5)/2, "lines"),
text = element_text(size=15), axis.title.x=element_text(vjust=-1.5), axis.title.y=element_text(vjust=2))
p4 <- p4 + guides(colour=guide_legend(override.aes=list(shape=c(NA,17,16))))
p4
When I try show_guide = FALSE in geom_point, the shape of the point in the upper legend are all set to default solid circles.
How can I make the lower legend to disappear, without affecting the upper legend?
This is a solution, complete with reproducible data:
library("ggplot2")
library("grid")
library("RColorBrewer")
cp2p <- data.frame(xval = 10 * 2:15, yval = cumsum(c(0.55, rnorm(13, 0.01, 0.005))), Approach = "CP2P", stringsAsFactors = FALSE)
p2p <- data.frame(xval = 10 * 1:15, yval = cumsum(c(0.7, rnorm(14, 0.01, 0.005))), Approach = "P2P", stringsAsFactors = FALSE)
pd <- position_dodge(0.1)
cp.best <- list(slope = 0.65)
all.m <- rbind(p2p, cp2p)
all.m$Approach <- factor(all.m$Approach, levels = c("C2P", "P2P", "CP2P"))
all.m$se <- rnorm(29, 0.1, 0.02)
all.m[nrow(all.m) + 1, ] <- all.m[nrow(all.m) + 1, ] # Creates a new row filled with NAs
all.m$Approach[nrow(all.m)] <- "C2P"
cols <- brewer.pal(n = 3, name = 'Dark2')
p4 <- ggplot(all.m, aes(x=xval, y=yval, colour = Approach, ymax = 0.95)) + theme_bw() +
geom_errorbar(aes(ymin= yval - se, ymax = yval + se), width=5, position=pd) +
geom_line(position=pd) +
geom_point(aes(shape=Approach, colour = Approach), size = 4, na.rm = TRUE) +
geom_hline(aes(yintercept = cp.best$slope, colour = "C2P")) +
scale_color_manual(values = c(C2P = cols[1], P2P = cols[2], CP2P = cols[3])) +
scale_shape_manual(values = c(C2P = NA, P2P = 16, CP2P = 17)) +
scale_y_continuous(breaks = seq(0.4, 0.95, 0.05), "Test AUROC") +
scale_x_continuous(breaks = seq(10, 150, by = 20), "# Number of Patient Samples in Training")
p4 <- p4 + theme(legend.direction = 'horizontal',
legend.position = 'top',
plot.margin = unit(c(5.1, 7, 4.5, 3.5)/2, "lines"),
text = element_text(size=15), axis.title.x=element_text(vjust=-1.5), axis.title.y=element_text(vjust=2))
p4
The trick is to make sure that all of the desired levels of all.m$Approach appear in all.m, even if one of them gets dropped out of the graph. The warning about the omitted point is suppressed by the na.rm = TRUE argument to geom_point.
Short answer:
Just add a dummy geom_point layer (transparent points) where shape is mapped to the same level as in geom_hline.
geom_point(aes(shape = "int"), alpha = 0)
Longer answer:
Whenever possible, ggplot merges / combines legends of different aesthetics. For example, if colour and shape is mapped to the same variable, then the two legends are combined into one.
I illustrate this using simple data set with 'x', 'y' and a grouping variable 'grp' with two levels:
df <- data.frame(x = rep(1:2, 2), y = 1:4, grp = rep(c("a", "b"), each = 2))
First we map both color and shape to 'grp'
ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
geom_line() +
geom_point(size = 4)
Fine, the legends for the aesthetics, color and shape, are merged into one.
Then we add a geom_hline. We want it to have a separate color from the geom_lines and to appear in the legend. Thus, we map color to a variable, i.e. put color inside aes of geom_hline. In this case we do not map the color to a variable in the data set, but to a constant. We may give the constant a desired name, so we don't need to rename the legend entries afterwards.
ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
geom_line() +
geom_point(size = 4) +
geom_hline(aes(yintercept = 2.5, color = "int"))
Now two legends appears, one for the color aesthetics of geom_line and geom_hline, and one for the shape of the geom_points. The reason for this is that the "variable" which color is mapped to now contains three levels: the two levels of 'grp' in the original data, plus the level 'int' which was introduced in the geom_hline aes. Thus, the levels in the color scale differs from those in the shape scale, and by default ggplot can't merge the two scales into one legend.
How to combine the two legends?
One possibility is to introduce the same, additional level for shape as for color by using a dummy geom_point layer with transparent points (alpha = 0) so that the two aesthetics contains the same levels:
ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
geom_line() +
geom_point(size = 4) +
geom_hline(aes(yintercept = 2.5, color = "int")) +
geom_point(aes(shape = "int"), alpha = 0) # <~~~~ a blank geom_point
Another possibility is to convert the original grouping variable to a factor, and add the "geom_hline level" to the original levels. Then use drop = FALSE in scale_shape_discrete to include "unused factor levels from the scale":
datadf$grp <- factor(df$grp, levels = c(unique(df$grp), "int"))
ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
geom_line() +
geom_point(size = 4) +
geom_hline(aes(yintercept = 2.5, color = "int")) +
scale_shape_discrete(drop = FALSE)
Then, as you already know, you may use the guides function to "override" the shape aesthetics in the legend, and remove the shape from the geom_hline entry by setting it to NA:
guides(colour = guide_legend(override.aes = list(shape = c(16, 17, NA))))

Resources