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)
Related
This question already has answers here:
Place a border around points
(5 answers)
Closed 1 year ago.
I have a dataset 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)
And my plot looks like this:
p <- ggplot(mydata, aes(x=Year, y=reorder(Name, desc(Name)), size = Value)) +
geom_point(aes(colour = Value,
alpha = I(as.numeric(Value > 0))))
p <- p + scale_colour_viridis_c(option = "D", direction = -1,
limits = c(1, 25)) +
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))
I would like to improve it in two ways but I couldn't figure out how.
I would like to add a black border around points. I know I should use pch>20 and specify colour, but because my colours are mapped to a feature of the dataset (they depend on value, in this case), I don't know exactly how to do that. Note that value = 0 points are not plotted. Easy stratagems such as plotting bigger black points under my points seem utopic for me.
I would like to change the breaks of the scale (e.g., instead of having breaks every 5, I'd like to have breaks every 2.5), but it is a continuous scale, and I'm not sure how to do that.
I am not very familiar with ggplo2, thus any help would be appreciated!
You can indeed use a shape >20, e.g. I use shape=21 here. Then you need to change your scale_color_ to scale_fill_, because the color is now black (it is the border of the shape).
For breaks, you could just specify them in the scale itself. Combining both:
ggplot(mydata, aes(x=Year, y=reorder(Name, desc(Name)), size = Value)) +
geom_point(aes(fill = Value,
alpha = I(as.numeric(Value > 0))), shape=21, color = "black") +
scale_fill_viridis_c(option = "D", direction = -1,
limits = c(1, 25), breaks=seq(1, 25, 2.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))
I tried to plot a matrix using geom_tile. However, I noticed there are two strange blocks appear at the top and bottom of my plot. My initial guess was these are ticks element. I've tried to specify the theme parameters as far as I know but no luck.
Basically, I want to remove the two wired blocks that I marked in red arrow. The left plot is something that I desired except the white block. The right plot is I tuned the plot.background in theme to show you there are something I don't know occupies the area.
Image here
I also attached the minimal code that could reproduce the left plot:
test2 <- matrix(runif(100*100),nrow = 100)
testdf <- test2 %>% reshape2::melt()
testdf$Var2 <- factor(testdf$Var2,levels=(seq(max(testdf$Var2),1))) # you could ignore this line
testdf %>% ggplot() + geom_tile(aes(x=Var2,y=Var1,fill=log2(value+1))) +
scale_fill_gradientn(colors = c("#ffffff","#f9c979","#ec8121","#b80217","#2f0006")) +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
plot.background = element_blank()) + coord_equal()
These blocks are the result of ggplot2's default expansion of the scale. To get rid of these block set the expansion to zero via scale_y_continuous:
library(ggplot2)
library(reshape2)
test2 <- matrix(runif(100*100),nrow = 100)
testdf <- reshape2::melt(test2)
testdf$Var2 <- factor(testdf$Var2,levels=(seq(max(testdf$Var2),1))) # you could ignore this line
ggplot(testdf) +
geom_tile(aes(x=Var2,y=Var1,fill=log2(value+1))) +
scale_y_continuous(expand = c(0,0)) +
scale_fill_gradientn(colors = c("#ffffff","#f9c979","#ec8121","#b80217","#2f0006")) +
theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.title = element_blank(),
panel.background = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, size=1),
plot.background = element_blank()) + coord_equal()
I am a bit stuck with the following: I want to arrange multiple (gg)plots into a grid with cowplot::plot_grid. Below is an example with two ggplots (g_bottom and g_top), both faceted. The bottom one has the facet labels deleted as they are redundant. However, there seems to remain the contour of the background or so, acting as cutting with a white line the top plot (see image below).
How could I fix this?
What have I tried so far:
Instead of strip.background = element_blank() I also tried strip.background = element_rect(fill = NA, color = NA) in theme, but with no success.
If I set rect = element_blank(), it somehow works, but I lose the entire plot border. I was then hopping that rect = element_rect(fill = "transparent", colour = NA) would do it, but still no success. I also just tried colour = NULL or colour = "transparent" also with no success.
library(ggplot2)
library(cowplot)
g <- ggplot(mpg, aes(class)) +
geom_bar() +
facet_grid(. ~ year) +
theme_bw()
g_bottom <- g +
theme(
strip.text = element_blank(),
strip.background = element_blank(),
# strip.background = element_rect(fill = NA, color = NA) # didn't work either
# Was hoping that this will do the trick, bot no success:
rect = element_rect(fill = "transparent", color = NA)
)
g_top <- g +
labs(x = element_blank()) +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)
plot_grid(g_top, NULL, g_bottom,
# used NULL to be able to tweak spacing between plots with rel_heights
align = "hv",
nrow = 3,
rel_heights = c(1, -0.2, 1))
I could go around the problem by not faceting and creating each of the 4 plots individually, but maybe there is a more straightforward solution with some theme argument which I'm too blinded to see any-further...
Eventually, using rect = element_blank() in theme when making g_bottom and then adding panel.border = element_rect(colour = "black") seems to do the trick. I still fail to understand why the initial trials didn't work as expected.
library(ggplot2)
library(cowplot)
g <- ggplot(mpg, aes(class)) +
geom_bar() +
facet_grid(. ~ year) +
theme_bw()
g_bottom <- g +
theme(
strip.text = element_blank(),
rect = element_blank(),
panel.border = element_rect(colour = "black")
)
g_top <- g +
labs(x = element_blank()) +
theme(
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)
plot_grid(g_top, NULL, g_bottom + theme(panel.border = element_rect(colour = "black")),
align = "hv",
nrow = 3,
rel_heights = c(1, -0.2, 1))
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))
I am trying to add a panel border to my plot - but the border keeps falling somewhere below the x-axis. Does anyone have any suggestions to have the bottom line of the panel border fall directly on the x-axis.
f<- ggplot(nadph, aes(x = reorder(DGRP.Line, MEN), y = MEN)) +
geom_bar(stat = "identity") +
xlab("DGRP Line") + ylab ("MEN activity (standardized)") +
theme(axis.text.x=element_blank(),
panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.ticks.x = element_blank(),
panel.border = element_rect(color = "black", fill= NA, size=1))