geom_rect gives empty plot with no rectangle - r

I would like to get a rectangle box between every point of dawn and dusk. I don't understand why the code below is not giving the desired result
dawn = seq(200, 210, by = 0.5)
dusk = seq(200.5, 210.5, by = 0.5)
night = data.frame("dusk" = dusk, "dawn" = dawn)
ggplot()+
geom_rect(data = night, aes(xmin = dawn , xmax = dusk ,
ymin = -Inf, ymax = Inf),
fill = "blue", alpha = 0.5, colour = NA)
I couldnt see the filled rectangle.

As an alternative, you could define the coordinate system with limits...
ggplot()+
geom_rect(data = night, aes(xmin = dawn , xmax = dusk ,
ymin = -Inf, ymax = Inf),
fill = "blue", alpha = 0.5, colour = NA) +
coord_cartesian(ylim=c(0.2,0.8))
In this way it works with Inf as well.

You need a y aesthetic. What do you want to plot anyways??
library(ggplot2)
dawn = seq(200, 210, by = 0.5)
dusk = seq(200.5, 210.5, by = 0.5)
night = data.frame("dusk" = dusk, "dawn" = dawn, y = 1)
ggplot(night, aes(dawn, y))+
geom_rect(data = night, aes(xmin = dawn , xmax = dusk ,
ymin = -Inf, ymax = Inf),
fill = "blue", alpha = 0.5, colour = NA)
Created on 2021-02-09 by the reprex package (v0.3.0)

Related

How to remove border colour of geom_rect_pattern from {ggpattern}?

I want to plot two rectangles with internal gradients beside each other using ggpattern::geom_rect_pattern(pattern = "gradient") without a border around each rectangle.
Example:
library(tidyverse)
library(ggpattern)
tibble(
id = c("a", "b"),
xmin = c(-1, -1),
xmax = c(1, 1),
ymin = c(-1, 0),
ymax = c(0, 1)
) |>
ggplot() +
geom_rect_pattern(
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, pattern_fill2 = id),
pattern_fill = "white", pattern = "gradient", pattern_orientation = "horizontal"
) +
theme_classic() +
coord_fixed(xlim = c(-1.1,1.1), ylim = c(-1.1,1.1), ratio = 1)
Which produces:
My issue is how do I remove the border around the rectangles?
Setting colour = "white" in geom_rect_pattern() will work to remove the outer border, but will introduce an internal border which is undesirable for my figure:
Setting colour = NA and/or pattern_colour = NA produces the same plot as the first
.
Is there an aesthetic I am missing here?
There seems to be a gray-filled rectGrob under the gradient fill on the finished plot, and you can just see the edges of it. If you set fill = NA this disappears.
library(tidyverse)
library(ggpattern)
tibble(
id = c("a", "b"),
xmin = c(-1, -1),
xmax = c(1, 1),
ymin = c(-1, 0),
ymax = c(0, 1)
) |>
ggplot() +
geom_rect_pattern(
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, pattern_fill2 = id),
pattern_fill = "white", pattern = "gradient", fill = NA,
pattern_orientation = "horizontal",
) +
theme_classic() +
coord_fixed(xlim = c(-1.1,1.1), ylim = c(-1.1,1.1), ratio = 1)

Distinguish theme (background) color for negative and positive values in geom_boxplot

For data of this type:
set.seed(123)
df <- data.frame(
Q = c(rep("q_pol",10), rep("q_wh",10)),
slope = c(rnorm(10,-0.5), rnorm(10, 0.5)),
Recipient = rep(c("A", "B"),10)
)
how can I color the theme (or background) of these boxplots in two different colors: the upper half for values > 0, say, "lightblue" and the lower half for values < 0, say, "darkblue":
library(ggplot2)
ggplot(df,
aes(x = Q, y = slope, color = Recipient)) +
geom_boxplot(notch = TRUE)
One option would be to add different filled backgrounds using geom_rect:
library(ggplot2)
ggplot(df,
aes(x = Q, y = slope, color = Recipient)) +
geom_rect(data = data.frame(
xmin = c(-Inf, -Inf),
xmax = c(Inf, Inf),
ymin = c(-Inf, 0),
ymax = c(0, Inf),
fill = c("darkblue", "lightblue")
), aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill), inherit.aes = FALSE, alpha = .5) +
scale_fill_manual(values = c("darkblue" = "darkblue", "lightblue" = "lightblue"), guide = "none") +
geom_boxplot(notch = TRUE)

How to remove border from quadrant lines in geom_point plot (ggplot2) after adding "size"

How to remove border from quadrant lines in geom_point plot (ggplot2) after adding "size"?
ggplot(
DurablesSIZE,
aes(
x = DurablesSIZE$`GDP LQ`,
y = DurablesSIZE$Slope,
color = DurablesSIZE$Sector,
size = DurablesSIZE$`2019 GDP`
)
) +
geom_point() +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 1) +
xlim(0, 5.5) +
ylim(-0.26, 0.26) +
geom_rect(aes(
xmin = 1,
xmax = Inf,
ymin = 0,
ymax = Inf
),
fill = "green",
alpha = 0.03) +
geom_rect(aes(
xmin = -Inf,
xmax = 1,
ymin = -Inf,
ymax = 0
),
fill = "red",
alpha = 0.03) +
geom_rect(aes(
xmin = -Inf,
xmax = 1,
ymin = 0,
ymax = Inf
),
fill = "yellow",
alpha = 0.03) +
geom_rect(aes(
xmin = 1,
xmax = Inf,
ymin = -Inf,
ymax = 0
),
fill = "yellow",
alpha = 0.03) +
labs(y = "Slope of GDP LQ (5Y)",
x = "2019 GDP LQ",
color = "Sector",
size = "2019 GDP") +
ggtitle("Oregon Durable Manufacturing \nTargeting Potential (GDP)") +
geom_text(
aes(label = ifelse(Slope > 0 & LQ > 1, as.character(Sector), '')),
hjust = 0,
vjust = 0,
size = 2.5,
nudge_x = -0.07,
nudge_y = 0.013
) +
theme(legend.key = element_rect(colour = NA, fill = NA),
legend.box.background = element_blank())
After adding size to my points, there is a weird border around the quadrant line weird border.
The size aesthetic is being applied globally, so it is creating a thick border around each geom_rect -- it controls border width for that geom.
To remove it, take size out of the global aes mapping and use geom_point(aes(size = '2019 GDP')) + to apply it to that layer alone.
Another note: if you use geom_rect for annotation purposes, it will be plotted once for each relevant line of your data, leading to massive overplotting and minimal control of alpha. It will be better to use annotate("rect" ...) for those, or to create a separate summary table which those layers can refer to so they only plot once.
Here's some fake data I made up so that I could run your code. Please include something like this in your questions.
DurablesSIZE <- tibble(
`GDP LQ` = 0.5*(1:10),
LQ = 10:1,
Slope = 0.05*(-4:5),
Sector = rep(LETTERS[1:5], 2),
`2019 GDP` = 1:10
)
Result with original code:
Revision with size aesthetic only applied locally:

Ggplotly with tooltip has problems using geom_rect()

I am trying to plot some data in a ggplotly plot.
The x-axis contains dates. Ggplotly doesn't work well with dates as when I hover over a point, the date is displayed as a number.
I solved this by setting a tooltip like below.
Some sample data:
x <- data.frame(Date = as.Date(seq(Sys.Date(), Sys.Date() + 29, by = "days")), Amount = seq(-10000, 19000, by = 1000),
stringsAsFactors = FALSE)
The plot:
ggplotly(ggplot(x, aes(x = Date, y = Amount, group = 1, text = paste("Date: ", Date, "<br>Amount: ", Amount))) + geom_line() + geom_point()
, tooltip = "text")
Now I want to use geom_rect() to get some background colors depending on the value of the y-axis. This gives me problems as the rectangles seem to be placed on top of the geom_line(). Also, the rectangles are labeled by ggplotly too, which I don't want either.
Here is the code I tried (the background coloring works fine when I am not using a custom tooltip, but then the problem with the dates in the labels occurs):
ggplotly(ggplot(x, aes(x = Date, y = Amount, group = 1, text = paste("Date: ", Date, "<br>Amount: ", Amount))) + geom_line() + geom_point()
+
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 10000, ymax = max(max(x$Amount) + 1000, 11000), fill = "1")) +
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 0, ymax = 10000, fill = "2")) +
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = min(min(x$Amount) - 1000, 0), ymax = 0, fill = "3"))
+
scale_fill_manual(values = alpha(c("green", "orange", "red"), 0.2))
, tooltip = "text")
Result
Any help would be appreciated, thanks!
EDIT:
The following code results in working geom_rect():
ggplotly(ggplot(x, aes(x = Date, y = Amount)) + geom_line() + geom_point()
+
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 10000, ymax = max(max(x$Amount) + 1000, 11000), fill = "1")) +
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 0, ymax = 10000, fill = "2")) +
geom_rect(aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = min(min(x$Amount) - 1000, 0), ymax = 0, fill = "3"))
+
scale_fill_manual(values = alpha(c("green", "orange", "red"), 0.2)))
Result
You could try this:
ggplotly(ggplot() +
geom_rect(data = x, aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 10000, ymax = max(max(x$Amount) + 1000, 11000), fill = "1")) +
geom_rect(data = x, aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = 0, ymax = 10000, fill = "2")) +
geom_rect(data = x, aes(xmin = as.Date(Sys.Date()),
xmax = as.Date(Sys.Date() + 30),
ymin = min(min(x$Amount) - 1000, 0), ymax = 0, fill = "3")) +
geom_line(data = x, aes(x = Date, y = Amount, group = 1, text = paste("Date: ", Date, "<br>Amount: ", Amount))) +
geom_point(data = x, aes(x = Date, y = Amount, text = paste("Date: ", Date, "<br>Amount: ", Amount))) +
scale_fill_manual(values = alpha(c("green", "orange", "red"), 0.2))
, tooltip = "text")

How to use ggplot in a loop with computed parameters?

I am trying to produce a variable number of rectangles (layers) in a ggplot of a zoo object. I would like to do this in a loop since I do not know ahead of time how many rectangles I will need. Here is a toy example.
library("zoo")
library("ggplot2")
set.seed(1)
y <- runif(50, min = 1, max = 2)
start <- as.numeric(as.Date("2018-01-01"))
x <- as.Date(start:(start + 49))
x.zoo <- zoo(y, order.by = x)
## Fill areas
bars <- data.frame(start = c(x[5], x[20], x[35]),
end = c(x[10], x[25], x[40]))
I can plot these manually with this code:
## Plot manually
print(autoplot.zoo(x.zoo, facets = NULL) +
geom_rect(aes(xmin = bars[1,1],
xmax = bars[1,2], ymin = -Inf, ymax = Inf),
fill = "pink", alpha = 0.01) +
geom_rect(aes(xmin = bars[2,1],
xmax = bars[2,2], ymin = -Inf, ymax = Inf),
fill = "pink", alpha = 0.01) +
geom_rect(aes(xmin = bars[3,1],
xmax = bars[3,2], ymin = -Inf, ymax = Inf),
fill = "pink", alpha = 0.01))
This gives me this desired image:
I tried using the loop below but it only plots the last bar. How do I do this??
## This didn't work but illustrates what I am trying to do
p = autoplot.zoo(x.zoo, facets = NULL)
for(i in 1:3) {
p = p + geom_rect(aes(xmin = bars[i,1],
xmax = bars[i,2], ymin = -Inf, ymax = Inf),
fill = "pink", alpha = 0.01)
}
print(p)
You don't need a loop. geom_rect is vectorised
autoplot.zoo(x.zoo, facets = NULL) +
geom_rect(aes(xmin = start, xmax = end, ymin = -Inf, ymax = Inf), data = bars, fill = "pink", alpha = 0.4, inherit.aes = FALSE)
One way to avoid the for loop is to convert x.zoo into a data.frame and map the data to geom_line. This way, you can map the bars data to geom_rect separately.
dat <- data.frame(index = index(x.zoo), data.frame(x.zoo))
ggplot() +
geom_rect(data = bars, aes(xmin = start, xmax = end, ymin =-Inf, ymax = Inf), fill = 'pink', alpha = .5) +
geom_line(data=dat, aes(x = index, y = x.zoo))

Resources