R ggplot2: Plot geom_point with black and white without using shape? - r

I would like to plot in black and white with ggplot2 however I don't want to use shape (ie solid black vs open black outline) because I need the shape to describe another group.
library(ggplot2)
str(mtcars)
p <- ggplot(data = mtcars, aes(x = wt, y=mpg, col=factor (vs), shape= factor (cyl) ))
p + geom_point(size=10) +
theme_bw() +
theme(legend.position="bottom", legend.title=element_blank(), legend.key = element_blank(),
axis.text.x = element_text(size=17),
axis.text.y = element_text(size=17),
axis.title.x = element_text(size=20),
axis.title.y = element_text(size=20),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
legend.text =element_text(size=22)
) +
scale_colour_manual(values = c("red", "blue"))
The plot looks like this.
I would like to have 0 and 1 be plotted as black and white (black outline) however in this case its difficult since the shape has already been taken with factor (vs). Is there any other thing I can do? thanks.

If you want two separate legends for the two factors as you have in your example, you can use "fillable" shapes and the fill aesthetic instead of the color aesthetic. Shapes are shown here; the fillable ones are the ones in yellow, 21-25.
To get your legends to look how you want them, particularly the fill legend, you can override the shape via override.aes in guide_legend. Here I also fill the shape legend in black, but that isn't necessary if you don't mind the white legend.
ggplot(data = mtcars, aes(x = wt, y=mpg, fill = factor(vs), shape = factor (cyl)
)) +
geom_point(size=10) +
theme_bw() +
scale_fill_manual(values = c("black", "white")) +
scale_shape_manual(values = c(21, 24, 22) ) +
guides(fill = guide_legend(override.aes = list(shape = 21) ),
shape = guide_legend(override.aes = list(fill = "black" ) ) )

Here's a solution:
str(mtcars)
p <- ggplot(data = mtcars, aes(x = wt, y=mpg, shape=paste0(vs,cyl) ))
p + geom_point(size=10) +
theme_bw() +
theme(legend.position="bottom", legend.title=element_blank(), legend.key = element_blank(),
axis.text.x = element_text(size=17),
axis.text.y = element_text(size=17),
axis.title.x = element_text(size=20),
axis.title.y = element_text(size=20),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
legend.text =element_text(size=22)
)+scale_shape_manual(values = c("04"=15,"06"=16,"08"=17,"14"=0,"16"=1,"18"=2))

Related

how can I draw a connecting line between the label and the plot in R

This is my script for the plot,
data = data.frame(Kingdom = c("Bacteria", "Archaea"),
Total = c(273523, 2616))
sizeRange <- c(0,30)
library(ggplot2)
ggplot(data, aes(x=0,y=Kingdom,color=Kingdom)) +
geom_point(aes(size = Total,alpha=10),colour="blue",stroke=2) +
scale_size(range = sizeRange)+
theme_bw() +
theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "white"))
somebody, please tell me how can I get a connecting line between my y-axis label and the plot
My plot looks like this
I want something like this
A clean alternative would be to label the points directly, and remove the y-axis if wanted. e.g.:
ggplot(data, aes(x=0,y=Kingdom,color=Kingdom)) +
ggrepel::geom_text_repel(aes(label = Kingdom), vjust = -1,colour="black") +
geom_point(aes(size = Total),colour="blue",stroke=2) +
scale_size(range = sizeRange)+
theme_bw() +
theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "white"),
axis.text.y=element_blank(),
axis.title.y = element_blank(),
axis.ticks.y=element_blank())
you can manually add segments, but then the alpha of your points will kind of show them.
Here is a try, altought it's not perfect if the x axis expend.
ggplot(data, aes(x=0,y=Kingdom,color=Kingdom)) +
# Added the segments here before the points.
# I tried to alpha it but I can't figure out how to limit the
# segment to the point border.
geom_segment(x = rep(-100,2), xend = rep(0,2),
y = c(1, 2), yend = c(1,2),colour="blue", alpha = 10) +
geom_point(aes(size = Total,alpha=10),colour="blue",stroke=2) +
scale_size(range = sizeRange)+
theme_bw() + guides(alpha = "none") + # remove alpha from legend.
theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "white"))

Combining and resizing barplot and ggplot

I have two plots I would like to combine. My data looks like this:
Year<-rep(2001:2005, each = 5)
name<-c("John","Ellen","Mark","Randy","Luisa")
Name<-c(rep(name,5))
Value<-sample(seq(0,25,by=1),25)
mydata<-data.frame(Year,Name,Value)
This is the first barplot:
tot<-aggregate(mydata$Value,list(mydata$Year),FUN=sum)
tot_y<-tot$x
tot_x<-tot$Group.1
tot_barplot <- ggplot(tot, aes(x=tot_x,y=tot_y)) +
geom_bar(stat = "identity",fill="#73D055FF") +
scale_y_continuous(limits = c(0, 125), breaks = seq(0, 125, by = 25)) +
#xlab("Pathways") +
#ylab("N° of species") +
theme(axis.line = element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_text(size=14,margin=margin(l=10),colour="black"),
axis.ticks = element_blank(),
axis.title=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank())
tot_barplot
And this is the second plot:
p <- ggplot(mydata, aes(x=Year, y=Name, size = Value)) +
geom_point(aes(fill = Value,
alpha = I(as.numeric(Value > 0))), shape=21, colour = "black") +
scale_fill_viridis_c(option = "D", direction = -1,limits = c(1, 25), breaks=seq(1, 25, 5))+
scale_size_area(guide = "none") +
ylab("Name") +
theme(axis.line = element_blank(),
axis.text.x=element_text(size=11,margin=margin(b=10),colour="black"),
axis.text.y=element_text(size=13,margin=margin(l=10),colour="black",
face="italic"),
axis.ticks = element_blank(),
axis.title=element_text(size=18,face="bold"),
panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(),
legend.text = element_text(size=14),
legend.title = element_text(size=18))
p
I combine them like this:
grid.arrange(arrangeGrob(tot_barplot,p,nrow=2))
Now I would like to re-size the barplot to fit it better to the second plot (imagine that the original data produce a wider barplot where the bars start above the Name and end above the legend Value). I would like the bars of the barplot to be exactly centred above the line of points and the Year, but I am not very familiar with ggplot aesthetics.
Any suggestion would be appreciated. Thanks!

How to change the plot.background in Donut ggplot graph?

How to change the plot.background in a 'geom_rect()' + 'coord.polar()' in a Donut ggplot graph?
I dont know what I´m missing, but I´w working in html black background style and needing to set panel as well plot background to black, but the graph sides of my ggplot are white and I need to know which attribute or command I need to use to turn sides to black too.
Below my code:
my_df %>%
ggplot(aes(ymax=max, ymin=min, xmax=4, xmin=3,fill=ResultCode)) +
geom_rect() +
geom_label( x=3.5, aes(y=labelPosition, label=label), size=4, color="white") +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme_void() +
theme(legend.position="none",
plot.background=element_rect(fill = "black"),
panel.background = element_rect(fill = "black"),
panel.border = element_blank(),
legend.key = element_blank(),
axis.ticks = element_blank(),
axis.text.y = element_blank(),
panel.grid = element_blank())
Below the resulted graph (see the "white" sides at right and left I need to fill with black)
The problem here is that ggplot by default calls grid::grid.newpage before drawing. This creates a blank (white) screen. It will then set up a square viewport to fit your plotting window because you are using coord_polar. Once it has done this, it considers the square area to be "the" plotting window. In a sense then, ggplot has no knowledge or control over these white areas. No theme element can touch it.
The solution is to explicitly call grid.newpage yourself, draw a black background manually, and then explicitly print your ggplot using the parameter newpage = FALSE. You could alternatively set the grid gpar parameters so that the background is black by default, but this is likely to have undesired side effects later on.
Here's a reprex with some made-up data:
my_df <- data.frame(max = c(160, 320), min = c(0, 161),
ResultCode = c("A","B"),
labelPosition = c(80, 240), label = c("A", "B"))
p <- my_df %>%
ggplot(aes(ymax=max, ymin=min, xmax=4, xmin=3,fill=ResultCode)) +
geom_rect() +
geom_label( x=3.5, aes(y=labelPosition, label=label), size=4, color="white") +
coord_polar(theta="y") +
xlim(c(2, 4)) +
theme(legend.position="none",
plot.background = element_rect(fill = "black", color = "black"),
panel.background = element_rect(fill = "black", color = "black"),
plot.margin = margin(0,0,0,0),
panel.border = element_blank(),
legend.key = element_blank(),
axis.ticks = element_blank(),
axis.text.y = element_blank(),
panel.grid = element_blank())
grid::grid.newpage()
grid::grid.draw(grid::rectGrob(gp = grid::gpar(fill = "black")))
print(p, newpage = FALSE)

How to keep top and bottom axes in ggplot, while removing the panel border

I would like to keep both x axes (bottom and top), while removing the panel border (or both y axes, left and right).
Code:
library(ggplot2)
p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_line(colour = "blue") +
theme_bw() +
theme(axis.title.y=element_blank(),
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
panel.border = element_blank(),
axis.line.x = element_line(size = 0.5, linetype = "solid", colour = "lightgrey"),
axis.line.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
panel.background = element_blank())
print(p1)
This can be accomplished with sec_axis.
In order to reproduce your white background, I'll add theme_bw() before the call to theme; this also helps me break out the lower x-axis line, then I'll add the second axis.
library(ggplot2)
p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_line(colour = "blue") +
theme_bw() +
theme(axis.title.y=element_blank(),
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
panel.border = element_blank(),
axis.line.x = element_line(size = 2, linetype = "solid", colour = "lightgrey"),
axis.line.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank())
# original
p1
# both lines
p1 + scale_x_continuous(sec.axis=sec_axis(~.))
(side-by-side here for space/presentation, the code did not do that)
Side note: #chemdork123's suggested answer does work here: use annotate to add a specific geometry. While I don't prefer this method, it can suffice. ('green' retained from the linked answer.)
p1 + annotate(geom = 'segment', y = Inf, yend = Inf, color = 'green', x = -Inf, xend = Inf, size = 4)

Increase distance between axis line and plot lines on ggplot

How do I increase the distance between the axis.line.y below and the blue geom_hline below? I want a gap between the two, I don't want them kissing as shown on the plot.
library(tidyverse)
ggplot(mpg, aes(cty, hwy)) +
geom_point() +
geom_hline(yintercept = 25, color = "blue") +
theme_minimal() +
theme(axis.line.y = element_line(color = "black"),
axis.ticks.y.left = element_line(color = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())
I'm not sure if this is exactly what you want but try it.
library(tidyverse)
ggplot(mpg, aes(cty, hwy)) +
geom_point() +
geom_segment(aes(x = min(cty), y = 25,
xend = max(cty), yend = 25),
data = mpg) +
theme_minimal() +
theme(axis.line.y = element_line(color = "black"),
axis.ticks.y.left = element_line(color = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())

Resources