Tutorial - Nadal 2021

Toni Rodon

Universitat Pompeu Fabra
– www.tonirodon.cat

En molts països és comú enviar o donar un targetó per a celebrar un esdeveniment. Aniversaris, comiats, naixements… i, lògicament, targetons de nadal! Si, enlloc de comprar la postal de nadal, voleu fer-la amb R (quelcom que de ben segur a molts de vosaltres us ha passat pel cap), aquí teniu un breu tutorial que us guia en com plantejar-ho.

El tutorial genera quatre figures i una postal. És qüestió de cada usuari decidir quina imatge vol triar per enviar a amics, coneguts, familiars i saludats.

Arbre de nadal

Començarem fent un arbre de nadal. Aquesta part està basada en el codi que trobareu aquí.

# L'espai on dibuixarem l'arbre
plot(1:10,1:10,xlim=c(-5,5),ylim=c(0,10),type="n",xlab="",ylab="",xaxt="n",yaxt="n")
# Les banques i fulles
rect(-1,0,1,2,col="tan3",border="tan4",lwd=3)
polygon(c(-5,0,5),c(2,4,2),col="palegreen3",border="palegreen4",lwd=3)
polygon(c(-4,0,4),c(3.5,5.5,3.5),col="palegreen4",border="palegreen3",lwd=3)
polygon(c(-3,0,3),c(5,6.5,5),col="palegreen3",border="palegreen4",lwd=3)
polygon(c(-2,0,2),c(6.25,7.5,6.25),col="palegreen4",border="palegreen3",lwd=3)

#Afegir decoracions
points(x=runif(4,-5,5),y=rep(2,4),col=sample(c("blue","red"),size=4,replace=T),cex=3,pch=19)
points(x=runif(4,-4,4),y=rep(3.5,4),col=sample(c("blue","red"),size=4,replace=T),cex=3,pch=19)
points(x=runif(4,-3,3),y=rep(5,4),col=sample(c("blue","red"),size=4,replace=T),cex=3,pch=19)
points(x=runif(4,-2,2),y=rep(6.25,4),col=sample(c("blue","red"),size=4,replace=T),cex=3,pch=19)
points(0,7.5,pch=8,cex=5,col="gold",lwd=3)

#Afegir alguns regals i posar el títol
xPres = runif(10,-4.5,4.5)
xWidth = runif(10,0.1,0.5)
xHeight=runif(10,0,1)
for(i in 1:10){
  rect(xPres[i]-xWidth[i],0,xPres[i]+xWidth[i],xHeight[i],col=sample(c("blue","red"),size=1))
  rect(xPres[i]-0.2*xWidth[i],0,xPres[i]+0.2*xWidth[i],xHeight[i],col=sample(c("gold","grey87"),size=1))
}
mytitle = "Bon nadal"
mysubtitle = "I bon any nou!"
mtext(side=3, line=2,  cex=1.8, mytitle)
mtext(side=3, line=1, cex=1.4, mysubtitle)

my_plot <- recordPlot()        # Ho gravem en un objecte per exportar

Un cop fet, l’exportarem en format png.

png("arbre_nadal.png")
my_plot
dev.off()
## quartz_off_screen 
##                 2

Arbre de nadal amb ggplot

Si sou fans de ggplot, podeu aprofitar les seves potencialitats per fer un arbre de nadal (aquest i el següent arbre estan inspirats en això d’aquí).

library("ggplot2")

#Generem punts aleatoris

x1 <- runif(100000, -1, 1)
y1 <- runif(100000, -1, 1.6)

# equació pel cor de l'arbre
which1 <- x1^2+(y1-(x1^2)^(1/4))^2<=1
x1 <- x1[which1]
y1 <- y1[which1]

# segon nivell
x2 <- 1.5*x1 -1
y2 <- 1.5*y1 

# tercer nivell
x3 <- 2*x1 -2
y3 <- 2*y1


dt <- data.frame(c(x1,x2,x3),c(y1,y2,y3))
colnames(dt) <- c("x", "y")
dt$y <- dt$y - 0.25
dt <- dt[dt$x>-2 & dt$x<1 & dt$y>-2.25 & dt$y<0,]
dt <- data.frame(c(dt$x,dt$x), c(dt$y, -dt$y))
colnames(dt) <- c("x", "y")

#soca

p1 <- runif(1000, -0.5, 0.5)
p2 <- runif(1000, -2.5, -2)

soca <- data.frame(p1,p2)

colors <- c('green', 'green2', 'green4', 'darkgreen')
colors2 <- rep(colors,length.out=dim(dt)[1])

bolesnadal <- data.frame(c(-1.8, -1.7, -1.1, -0.6, 0, 0.3), c(-1,0.7,-0.9,0.1,-0.3,0.3))
colnames(bolesnadal) <- c("x", "y")

cadena <- data.frame(data.frame(x1 = -0.5, x2 = 1, y1 = 21.0, y2 = 15.0))

estrella <- data.frame(c(0), c(0.7))
colnames(estrella)<- c("x", "y")

ggplot(data=NULL) + geom_point(data=dt, aes(x = y, y=x), col=colors2) + 
  geom_point(data=bolesnadal, aes(x=y, y=x), size=10, col='blue') +
  geom_point (data=soca, aes(x=p1, y=p2), col='brown') + 
  geom_point(data=estrella, aes(x=x, y=y),size=10,shape=24, col="yellow", fill='yellow') +
  geom_point(data=estrella, aes(x=x ,y=y),size=10,shape=25, col="yellow", fill='yellow') +
  geom_curve(aes(x=-1,xend=1.2,y=-0.65,yend=-1.2), col='red',size=2, curvature = 0.3) + 
  geom_curve(aes(x=1.2, y=-1.2, xend=-1.2, yend=-1.5), size=2, col="red", curvature = -0.3) +
  geom_curve(aes(x=-1,xend=0.8,y=-0.65,yend=-0.5), col='red',size=2, curvature = 0.3) +
  geom_curve(aes(x=-0.8,xend=0.8,y=-0.2,yend=-0.5), col='red',size=2, curvature = 0.2) +
  geom_curve(aes(x=-0.8,xend=0.9,y=-0.2,yend=0.15), col='red',size=2, curvature = 0.3) +
  geom_curve(aes(x=-0.65,xend=0.9,y=0.35,yend=0.15), col='red',size=2, curvature = 0.3) +
  theme(axis.line=element_blank(),axis.text.x=element_blank(),
        axis.text.y=element_blank(),axis.ticks=element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),legend.position="none",
        panel.background=element_blank(),panel.border=element_blank(),panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),plot.background=element_blank()) +
  ggtitle("Bon nadal!")

ggsave("arbreggplot.png") #El gravem
## Saving 6 x 6 in image

Arbre de nadal animat

Potser sou de crear felicitacions de nadal animades i enviar-los en format gifs. També ho podeu fer! El codi que teniu a continuació triga una mica. Paciència.

library("ggplot2")
library("gganimate")
library("svglite")
library("dplyr")
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
HEIGTH <- 100

gen_data_v <- function(n_points, n_states) {
  
  
  id <- rep(1:n_points, each = n_states)
  time <- rep(1:n_states, times = n_points)
  
  velocity <- abs(rnorm(n_points, 1, 0.5))
  
  y1 <- runif(n_points, 0, HEIGTH)
  
  y <- as.vector(crossprod(t(0:(n_states-1)), -velocity) + 
                   matrix(rep(y1, n_states), byrow = TRUE, n_states, n_points))
  y <- y %% HEIGTH
  
  x1 <- matrix(runif(n_points, 0, HEIGTH), 1, n_points)
  for(i in 2:n_states) {
    x1 <- rbind(x1, x1[i-1,] + rnorm(n_points, 0, 0.4))
  }
  
  x <- (as.vector(x1) %% HEIGTH) - 50
  
  data.frame(id, x, y, time)
} 

dat <- gen_data_v(10000, 100)

x <- ggplot(data = dat, aes(x = x, y = y, color = id)) +
  geom_point(data = dat %>% filter(y < HEIGTH - 3*x & y < HEIGTH + 3 * x), size = 2) +
  geom_point(x=0, y=100, color = "#ffc20c", shape = 8, size = 10) +
  scale_color_gradient(low = "#addd8e", high = "#11673A", guide = FALSE) +
  theme_void() +
  coord_fixed() +
  transition_time(time) +
  ease_aes('linear') 

y <- animate(x, renderer = magick_renderer(),width = 600, height = 1000)
y