ggplot geom_rect() error "object not found" - r

I'm trying to plot a geom_rect(). Why do I receive an Error in FUN(X[[i]], ...) : object 'Month' not found? If I run df$Month in my console the object is there:
df$Month
#> [1] 2019-01 2019-02 2019-03
#> Levels: 2019-01 2019-02 2019-03
Here's my code block:
library(tidyverse)
df <- tibble(Month = factor(c("2019-01", "2019-02", "2019-03")),
Value = c(4, 9, 7))
ggplot(df, aes(Month, Value, group = 1)) +
geom_line() +
theme_minimal() +
geom_rect(data =
data.frame(xmin = min(as.integer(df$Month)) - 0.5,
xmax = max(as.integer(df$Month)) + 0.5,
ymin = min(df$Value),
ymax = max(df$Value)),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
alpha = 0.2, fill = "green")
#> Error in FUN(X[[i]], ...) : object 'Month' not found

This works:
ggplot(df, aes(Month, Value, group = 1)) +
geom_line() +
theme_minimal() +
geom_rect(data =
data.frame(xmin = min(as.integer(df$Month)) - 0.5,
xmax = max(as.integer(df$Month)) + 0.5,
ymin = min(df$Value),
ymax = max(df$Value)),
aes(x = NULL,y = NULL,xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
alpha = 0.2, fill = "green")
by unmapping the inherited x/y aesthetics from the top ggplot call. It's understandable that this might be confusing, though, since the description in ?geom_rect sorta kinda implies that geom_rect isn't looking for those aesthetics at all.

You just have an extra step of setting up a dataframe in geom_rect which coincide with data in ggplot. Simply provide your max and min values to geom_rect and it works:
ggplot(df, aes(Month, Value, group = 1)) +
geom_line() +
theme_minimal() +
geom_rect(aes(xmin = min(as.integer(Month)) - 0.5,
xmax = max(as.integer(Month)) + 0.5,
ymin = min(Value),
ymax = max(Value)),
alpha = 0.2/nrow(df), fill = "green")

I was able to return your desired result by calling df in geom_line() after gemo_rect(). However leaving the Month field as is returned the error: Error: Discrete value supplied to continuous scale.
I worked around this by wrapping as.integer() around Month.
ggplot() +
theme_minimal() +
geom_rect(data =
data.frame(xmin = min(as.integer(df$Month)) - 0.5,
xmax = max(as.integer(df$Month)) + 0.5,
ymin = min(df$Value),
ymax = max(df$Value)),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
alpha = 0.2, fill = "green") +
geom_line(data = df, aes(as.integer(Month), Value, group = 1))
You might have to clean up your x-axis label but it achieves desired outcome!

Related

Not able to add data to geom_rect in ggplot in pipe version; however without pipe (%>%) it works

I could not understand where is the error in this code.
The following code works fine
ggplot(mtcars) + geom_point(aes(wt, mpg)) +
geom_rect(data=data.frame(xmin = -Inf, xmax = 4, ymin = -Inf, ymax = Inf),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "light blue", alpha = 0.5)
However the same code while using %>% or in dplyr version gives error
mtcars %>%
ggplot(aes(x= wt, y= mpg)) + geom_point() +
geom_rect(data=data.frame(xmin = -Inf, xmax = 4, ymin = -Inf, ymax = Inf),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "light blue", alpha = 0.5)
The following error is displayed
Error in FUN(X[[i]], ...) : object 'wt' not found
Edit: Since there could be mapping issue as pointed below
however the following works; just the data part is removed from geom_rect
ggplot(mtcars, aes(wt, mpg)) + geom_point() +
geom_rect(aes(xmin = -Inf, xmax = 4, ymin = -Inf, ymax = Inf),
fill = "light blue", alpha = 0.05)
Thanks for your time and suggestion.
In your pipe version, the mapping is specified in ggplot which gets applied to geom_rect also. Specify it in geom_point instead.
mtcars %>%
ggplot() +
geom_point(aes(x= wt, y= mpg)) +
geom_rect(data=data.frame(xmin = -Inf, xmax = 4, ymin = -Inf, ymax = Inf),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "light blue", alpha = 0.5)

Adding colored rectangles to a titration graph

I have a data frame with a titration curve of pH, function of volume. I would like to put two colored/shadowed horizontal rectangles to show the range of pH of two indicators, methyl orange (3.2
Here is a reproducible exemple :
Volume <- c(1:5)
pH <- c(3,4,9,10,12)
df <- data.frame(Volume,pH)
ggplot(df,aes(x=Volume,y=pH))+geom_line(color="purple")+
geom_rect(aes(ymin=3.2,ymax=4.4,xmin=-Inf,xmax=Inf))+
geom_rect(aes(ymin=8.2,ymax=10,xmin=-Inf,xmax=Inf))+
scale_fill_manual(values = alpha(c("orange", "pink"),alpha = .3))
Which gives me this result :
How can theses rectangles be orange, pink and shadowed ?
Try this:
Volume <- c(1:5)
pH <- c(3,4,9,10,12)
df <- data.frame(Volume,pH)
ggplot(df,aes(x=Volume,y=pH))+geom_line(color="purple")+
geom_rect(aes(ymin=3.2,ymax=4.4,xmin=-Inf,xmax=Inf), fill="orange", alpha=.3)+
geom_rect(aes(ymin=8.2,ymax=10,xmin=-Inf,xmax=Inf), fill="pink", alpha=.3)
When something is not working, it is often a problem of referencing the wrong data or aesthetic in your geom_... calls.
Try to be very explicit when calling your geom.
Below I am creating an explicit data frame for your rectangles. You should explicitly call this data and also add inherit.aes = FALSE, so that it won't try to read the aesthetic from the ggpolt main call.
library(tidyverse)
mydf <- data.frame(Volume = c(1:5), pH = c(3, 4, 9, 10, 12))
ann_rect <- bind_rows(
data.frame(ymin = 3.2, ymax = 4.4, xmin = -Inf, xmax = Inf, fill = "orange"),
data.frame(ymin = 8.2, ymax = 10, xmin = -Inf, xmax = Inf, fill = "pink")
)
ggplot(mydf, aes(x = Volume, y = pH)) +
geom_rect(
inherit.aes = FALSE,
data = ann_rect,
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill)
) +
geom_line(color = "purple") +
scale_fill_identity()
Alternatively, leave the main call empty and explicitly reference the data in each geom call.
ggplot() +
geom_rect(data = ann_rect, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill)) +
geom_line(data = mydf, aes(x = Volume, y = pH), color = "purple") +
scale_fill_identity()
Created on 2020-03-19 by the reprex package (v0.3.0)

Custom colors for a ggplot2 based pie chart

Based on the answer https://stackoverflow.com/a/26748780/1172302 and the following data
"Category","Driver","Intensity","Intensity (Numeric)","Intensity (Fraction)","ymin","ymax","Color"
"Ec","Loss","High",2,0.0833333333,0,0.0833333333,"orange"
"Ec","Stress","High",2,0.0833333333,0.0833333333,0.1666666666,"orange"
"Ec","Expectations","High",2,0.0833333333,0.1666666666,0.2499999999,"orange"
"Go","Lack","Very high",3,0.125,0.2499999999,0.3749999999,"red"
"Go","Competition","Very high",3,0.125,0.3749999999,0.4999999999,"red"
"So","Disrespect","Low",1,0.0833333333,0.4999999999,0.5833333332,"yellow"
"So","Harassment","High",2,0.0833333333,0.5833333332,0.6666666665,"orange"
"So","Upheaval","Low",1,0.0833333333,0.6666666665,0.7499999998,"yellow"
"Se","Vulnerability","High",2,0.0833333333,0.7499999998,0.8333333331,"orange"
"Se","Police","Very high",3,0.0833333333,0.8333333331,0.9166666664,"red"
"Se","Presence","Low",1,0.0833333333,0.9166666664,0.9999999997,"yellow"
a pie can be derived via
# prepare data
cd <- read.csv("piedata.csv", header = TRUE, check.names = FALSE )[1:8]
cd[[2]] <- as.character(cd[[2]])
cd[[3]] <- factor(cd[[3]], levels(cd[[3]])[c(2, 1, 3)])
# load library
library(ggplot2)
# plot
ggplot(cd) +
geom_rect( aes ( fill = cd[[2]],
ymax = ymax, ymin = ymin, xmax = 4, xmin = 2)) +
geom_rect( aes ( fill = cd[[1]],
ymax = ymax, ymin = ymin, xmax = 2, xmin = 0)) +
xlim( c(0, 4)) +
theme(aspect.ratio = 1) +
coord_polar(theta="y") + theme_void()
How can I use the colors defined in cd$Color for the segments of the outer circle, define another four custom colors for the inner circle and, finally, avoid having the categories from cd$Category ("Ec", "Go", "So" and "Se") be present in the legend alltogether?
I can't answer all of your questions, but if you extend your data frame with an additional column describing the inner color and rewrite the plot code as followed, it should work
#plot
ggplot(cd) +
geom_rect(aes (fill = cd[[2]],
ymax = ymax, ymin = ymin, xmax = 4, xmin = 2), fill = cd$Color_in) +
geom_rect( aes ( fill = cd[[1]],
ymax = ymax, ymin = ymin, xmax = 2, xmin = 0), fill = cd$Color_out) +
xlim(c(0, 4)) +
theme(aspect.ratio = 1) +
coord_polar(theta="y")+theme_void()

How to shade a certain area of time series plot using geom_rect?

I'm trying to shade a certain area of time series plot using geom_rect.
I used the code below to create the time series plot
library(ggplot2)
set.seed(123)
date <- as.Date(seq(as.Date("2014-01-01"), as.Date("2015-12-31"), by = 1), format="%Y-%m-%d")
a <- runif(730, 3000, 120000)
df <- data.frame(date, a)
ggplot() +
geom_line(data = df, aes(x = date, y = a))
I tried to create the rectangle using geom_rect following the answer to this question
library(lubridate)
rectangle <- data.frame(xmin = decimal_date(as.Date(c("2014-10-01"))),
xmax = decimal_date(as.Date(c("2015-02-01"))),
ymin = -Inf, ymax = Inf)
ggplot() +
geom_line(data = df, aes(x = date, y = a)) +
geom_rect(data = rectangle, aes(xmin=xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "red", alpha = 0.5)
I got this error
Error: Invalid input: date_trans works with objects of class Date only
Any suggestions how to fix that would be appreciated.
This works:
library(lubridate)
rectangle <- data.frame(xmin = as.Date(c("2014-10-01")),
xmax = as.Date(c("2015-02-01")),
ymin = -Inf, ymax = Inf)
ggplot() +
geom_line(data = df, aes(x = date, y = a)) +
geom_rect(data = rectangle, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "red", alpha = 0.5)
Just remove decimal_date()

Using geom_rect for time series shading in R

I am trying to shade a certain section of a time series plot (a bit like recession shading - similarly to the graph at the bottom of this article on recession shading in excel). I have put a little, possibly clumsy, sample together to illustrate.
I first create a time series, plot it with ggplot2 and then want to use geom_rect to provide the shading. But I must get something wrong in the arguments.
a<-rnorm(300)
a_ts<-ts(a, start=c(1910, 1), frequency=12)
a_time<-time(a_ts)
a_series<-ts.union(big=a_ts, month=a_time)
a_series_df<-as.data.frame(a_series)
ggplot(a_series)+
geom_line(mapping=aes_string(x="month", y="big"))+
geom_rect(
fill="red",alpha=0.5,
mapping=aes_string(x="month", y="big"),
xmin=as.numeric(as.Date(c("1924-01-01"))),
xmax=as.numeric(as.Date(c("1928-12-31"))),
ymin=0,
ymax=2
)
Note that I have also tried which also did not work.
geom_rect(
fill="red",alpha=0.5,
mapping=aes_string(x="month", y="big"),
aes(
xmin=as.numeric(as.Date(c("1924-01-01"))),
xmax=as.numeric(as.Date(c("1928-12-31"))),
ymin=0,
ymax=2)
)
Its a bit easier using annotate and also note that the bounds for the rectange can be specified as shown:
ggplot(a_series_df, aes(month, big)) +
geom_line() +
annotate("rect", fill = "red", alpha = 0.5,
xmin = 1924, xmax = 1928 + 11/12,
ymin = -Inf, ymax = Inf) +
xlab("time")
This would also work:
library(zoo)
z <- read.zoo(a_series_df, index = 2)
autoplot(z) +
annotate("rect", fill = "red", alpha = 0.5,
xmin = 1924, xmax = 1928 + 11/12,
ymin = -Inf, ymax = Inf) +
xlab("time") +
ylab("big")
Either one gives this:
Code works fine, conversion to decimal date is needed for xmin and xmax, see below, requires lubridate package.
library("lubridate")
library("ggplot2")
ggplot(a_series_df)+
geom_line(mapping = aes_string(x = "month", y = "big")) +
geom_rect(
fill = "red", alpha = 0.5,
mapping = aes_string(x = "month", y = "big"),
xmin = decimal_date(as.Date(c("1924-01-01"))),
xmax = decimal_date(as.Date(c("1928-12-31"))),
ymin = 0,
ymax = 2
)
Cleaner version, shading plotted first so the line colour doesn't change.
ggplot() +
geom_rect(data = data.frame(xmin = decimal_date(as.Date(c("1924-01-01"))),
xmax = decimal_date(as.Date(c("1928-12-31"))),
ymin = -Inf,
ymax = Inf),
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = "grey", alpha = 0.5) +
geom_line(data = a_series_df,aes(month, big), colour = "blue") +
theme_classic()
To use geom_rect you need to define your rectangle coordinate through a data.frame:
shade = data.frame(x1=c(1918,1930), x2=c(1921,1932), y1=c(-3,-3), y2=c(4,4))
# x1 x2 y1 y2
#1 1918 1921 -3 4
#2 1930 1932 -3 4
Then you give ggplot your data and the shade data.frame:
ggplot() +
geom_line(aes(x=month, y=big), color='red',data=a_series_df)+
geom_rect(data=shade,
mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2), color='grey', alpha=0.2)
library(xts)
library(zoo)
library(ggts)
Creating an xts object
data<-as.xts(x=runif(228,20,40),order.by = seq(as.Date("2000/01/01"), by = "month", length.out = 228))
Creating data frame of dates for which you want to crate shades
date<-data.frame(as.Date("2008-01-01"),as.Date("2009-01-01"))
Now create plot with shaded area
plot_data<-ggts(data)+geom_cycle(date)

Resources