第 3 章 Layers
Geometries:
geom_line
- Aesthetics: x, y, color; size
source("support/time-trend.R")
3.1 Time series data
- package: lubridate
Basic data types do not have time
or date
type. Time/Date are class that is constructed on top of character data, like
"2020-02-01"
"2020-02-01 13:58:55"
- All date/time data sources are normally input as character. It requires parsing for computer to under it is date/time.
::ymd("2020-02-01")
lubridate::ymd_hms("2020-02-01 13:58:55") # UTC time zone by default
lubridate::ymd_hms("2020-02-01 13:58:55", tz="Asia/Taipei") lubridate
= lubridate::ymd(c("2020-02-01", "2020-04-01",
date "2020-06-01", "2020-09-01"))
= list()
data $Britain <-
datadata.frame(
date = date,
y = c(0, 50, 80, 100)
)$Spain <-
datadata.frame(
date = date,
y = c(0, 32, 53, 103)
)$Italy <-
datadata.frame(
date = date,
y = c(0, 50, 60, 99)
)
ggplot(data=dataAll) +
geom_line(
aes(
x=date,
y=y
) )
ggplot(data=dataAll) +
geom_line(
aes(
x=date,
y=y,
group=country
) )
3.2 Aesthetics inheritance
- In the past, we have done data inheritance (i.e. data in
ggplot()
) and both data/aesthetics inheritance (i.e, data and mapping inggplot()
). Actually you can do only aesthetics inheritance as well.
= 2 #input$sizeInput
sizeInput <- list()
plot $p1 <- {
plotggplot(
mapping=aes(
x=date,
y=y
+
))geom_line(
data=data$Britain,
color="#096fa1",
size = sizeInput
+
)geom_line(
data=data$Spain,
color="#ad8c97",
size = sizeInput
+
)geom_line(
data=data$Italy,
color = "#983d4d",
size = sizeInput
)
}$p1 plot
3.3 Sequence of layers
3.3.1 Line stroke
ggplot(
mapping=aes(
x=date,
y=y
+
))geom_line(
data=data$Britain,
color="#096fa1",
size = sizeInput
+
) geom_line( # the last geom will be on the top
data=data$Britain,
color="black",
size = sizeInput
)
= 0.6
prop
ggplot(
mapping=aes(
x=date,
y=y
+
))geom_line( # the last geom will be on the top
data=data$Britain,
color="black",
size = sizeInput
+
) geom_line(
data=data$Britain,
color="#096fa1",
size = sizeInput*prop
)
3.4 Create your first geom
<- function(data, sizeInput, prop) {
geom_lineWithStroke_error geom_line( # the last geom will be on the top
data=data,
color="black",
size = sizeInput
+
) geom_line(
data=data,
color="#096fa1",
size = sizeInput*prop
) }
class(plot$p1) # ggplot class
- a list of 9 that complete the definitions of a plot
<- geom_line( # the last geom will be on the top
gm data=data$Britain,
color="black",
size = sizeInput
) class(gm) # Layer class
an environment that defines only a layer of a specific geometric structure and its aesthetics.
part of a ggplot class object.
+
operator must have the preceding object a ggplot object.
geom_lineWithStroke_error(
data=data$Britain, sizeInput=2, prop=.6
)
The error comes from the function body. It uses
+
on two layer class objects. There is no ggplot object presented.ggplot()+...
will always return a ggplot object. So all of below are ggplot objects:ggplot()
,ggplot()+geom_point(...)
,ggplot()+geom_point(...)+geom_line(...)
3.4.1 Layer adding
Instead of using +
on each layers (i.e. adding geom one after the other), you can put all geom layers as a list, and use +
to add the list all at once.
Other than the conventional adding:
ggplot(
mapping=aes(
x=date,
y=y
+
))geom_line(
data=data$Britain,
color="black",
size = sizeInput
+
) geom_line( # the last geom will be on the top
data=data$Britain,
color="#096fa1",
size = sizeInput*prop
)
We can:
ggplot(
mapping=aes(
x=date,
y=y
+
)) list(
geom_line(
data=data$Britain,
color="black",
size = sizeInput
), geom_line( # the last geom will be on the top
data=data$Britain,
color="#096fa1",
size = sizeInput*prop
) )
3.4.2 New geom function
A geom function that delivers a mixture of multiple geoms must return the mixture as a list, avoiding using +
inside the function body.
<- function(data, sizeInput, prop) {
geom_lineWithStroke_prototype list(
geom_line(
data=data,
color="black",
size = sizeInput
), geom_line( # the last geom will be on the top
data=data,
color="#096fa1",
size = sizeInput*prop
)
) }
{ggplot(
mapping=aes(
x=date,
y=y
+
))geom_lineWithStroke_prototype(
data=data$Britain, sizeInput, prop
+
)geom_lineWithStroke_prototype(
data=data$Spain, sizeInput, prop
+
)geom_lineWithStroke_prototype(
data=data$Italy, sizeInput, prop
) }
3.4.3 dot-dot-dot
<- function(data, sizeInput, prop, color, stroke, size) {
geom_lineWithStroke_prototype2 list(
geom_line(
data=data,
color=stroke,
size = sizeInput
), geom_line( # the last geom will be on the top
data=data,
color=color,
size = sizeInput*prop
)
) }
{ggplot(
mapping=aes(
x=date,
y=y
+
))geom_lineWithStroke_prototype2(
data=data$Britain, sizeInput=sizeInput, prop=prop,
color="#096fa1",
stroke="white"
+
)geom_lineWithStroke_prototype2(
data=data$Spain, sizeInput=sizeInput, prop=prop,
color="#ad8c97",
stroke="white"
+
)geom_lineWithStroke_prototype2(
data=data$Italy, sizeInput=sizeInput, prop=prop,
color="#983d4d",
stroke="white"
) }
geom_lineWithStroke
is an extension to an existing geom_line
function. It would be better to make the input argument inline with geom_line
so as to keep other geom_line options, such as linetype.
help(geom_line)
<- function(
geom_lineWithStroke mapping = NULL,
data = NULL,
stat = "identity",
position = "identity",
na.rm = FALSE,
orientation = NA,
show.legend = NA,
inherit.aes = TRUE,
# set up default makes your function easy to use
stroke = "white",
prop = 0.9,
size = 2,
...){list(
geom_line(
data=data,
color=stroke,
size = size
),geom_line( # the last geom will be on the top
mapping = mapping,
data = data,
stat = stat,
position = position,
na.rm = na.rm,
orientation = orientation,
show.legend = show.legend,
inherit.aes = inherit.aes,
size = size*prop,
...)
) }
...
is a special argument for function. It means "whatever input whose input name is not specified in function arguments.
it can be passed directly into other functions who use
...
.it can be accessed via
list()
.
<- function(...){
mySum browser()
<- c(...)
argList sum(argList)
}mySum(2,3)
<- function(name, ...){
greeting browser()
<- list(...)
argList <- ""
extraGreeting if(length(argList)!=0){
<- paste(" Your", names(argList), " is ", argList)
extraGreeting
}
cat("Hi ", name, ". ", extraGreeting)
return(xx)
}greeting("John", age=33)
{ggplot(
mapping=aes(
x=date,
y=y
+
))geom_lineWithStroke(
data=data$Britain,
color="#096fa1"
+
)geom_lineWithStroke(
data=data$Spain,
color="#ad8c97"
+
)geom_lineWithStroke(
data=data$Italy,
color="#983d4d"
) }
{ggplot(
mapping=aes(
x=date,
y=y
+
))geom_lineWithStroke(
data=data$Britain,
color="#096fa1",
linetype=2
+
)geom_lineWithStroke(
data=data$Spain,
color="#ad8c97",
linetype=3
+
)geom_lineWithStroke(
data=data$Italy,
color="#983d4d",
stroke="black",
size=5
) }
3.5 Summary
Layers (of geoms) can be added on top of each other through
+
operator by either:ggplot object
+ geom1 + geom2
; orggplote object
+ list(geom1, geom2)
When create a new geom function that consists of multiple geoms, use
list(geom1, geom2)
as function return.When writing a function input argument names:
if in definition specifically WITHOUT default: it means something necessary. Users can not ignore.
if in definition specifically WITH default: it means something necessary, but there is a good choice of default that users will be happy with it most of the time.
...
: a flexible argument especially when our function body has a call to some other function that has...