R: Gráficos

Parámetros generales

par

Se puede utilizar para

  • consultar los parámetros gráficos escribiendo par()

  • configurar los parámetros gráficos globales especificándolos como argumentos para par en formato etiqueta = valor, o pasándolos como una lista de valores etiquetados.

Para consultar la ayuda donde se describen todos sus argumentos se puede ejecutar ?par o pulsar sobre las pestañas de la ventana inferior derecha.

Algunos de los parámetros solo pueden llamarse desde par, pero otros también pueden ser usados con funciones gráficas.

Parámetro Significado
adj Justificación del texto (0:izquierda, 0.5:centrado, 1:derecha) cuando se usan las funciones text , mtex y title
ann Título y nombres en los ejes (TRUE)
bg Color del fondo (white). Algunas funciones, como plot, tienen un argumento con el mismo nombre pero distinto significado.
bty Tipo de cuadro dibujado sobre los gráficos ("o", "l", "7", "c", "u" o "]", similar a la letra mayúscula correspondiente, o "n" que lo suprime).
cex Ampliar el texto (cex.axis, cex.lab, cex.main, cex.sub) y los símbolos del trazado en relación con el valor predeterminado (1).

cin (inches)

cra (pixels)

cxy

csi (inches)

Ancho y alto de los caracteres

c(0.15, 0.20)

c(10.8, 14.4)

Ancho y alto como par("cin")/par("pin")

Alto de caracteres (0.2)

col Color por defecto (col.axis, col.lab, col.main, col.sub)
crt Rotar texto (múltiplos de 90)
family Nombre de la familia de fuentes para el texto: serif, sans, mono y fuentes Herhsey
fg Color para el primer plano de los gráficos (black)
fig Coordenadas de la región gráfica c(x1,x2,y1,y2)
fin Dimensiones de la región gráfica c(ancho, alto) en pulgadas
font

Entero con el tipo de fuente: 1(texto plano), 2(negrita), 3(cursiva) 4(negrita y cursiva)

font.axis, font.lab, font.main, font.sub

lab c(x,y,len): marcas en el eje x, en el eje y y longitud de las etiquetas
las Estilo de las etiquetas en relación a los ejes: 0(paralelas), 1(horizontales), 2(perpendiculares), 3(verticales)
lend Estilo del final de línea: 0(redondeada), 1(hachazo), 2(cuadrada)
lmitre Límite de inglete de línea
lty

Tipos de líneas: 0 (o "blank" invisible), 1 (o "solid" sólida), 2 (o "dashed" discontinua), 3 (o "dotted" punteada), 4 (o dotdash), 5( o "longdash"), 6 (o "twodash").

Para mayor personalización, se puede utilizar un string de 8 caracteres.

lwd Ancho de línea (1)

mai

mar

Vector con la forma c(bottom, left, top, right), que marca

el tamaño de los márgenes en pulgadas c(1.02, 0.82, 0.82, 0.42)

el número de líneas de margen c(5, 4, 4, 2) + 0.1

mex Factor de expansión

mfcol

mfrow

mfg

Representar una matriz de figuras c(nr,nr) que se irá completando por columnas(mfcol) o por filas(mfrow). Se puede indicar qué figura va en cada elemento de la matriz con mfg.

Puede ser interesante considerar alternativas como layout o split.screen.

mgp Vector tridimensional con las líneas de margen para el título, las etiquetas de los ejes y la línea del eje (c(3,1,0))
new No limpiar antes de representar un nuevo gráfico de alto nivel (FALSE)

oma

omd

omi

Vector c(bottom, left, top, right), con los márgenes externos en

líneas de texto

región dentro de los márgenes

inches

pch Símbolo para representar los puntos
pin Ancho y alto actual de los gráficos
plt Coordenadas de la región del gráfico como fracción de la región de la figura.
ps Tamaño de los puntos del texto (no de los símbolos)
pty Tipo de región gráfica: "m" (máxima) o "s" (cuadrada)
srt Rotación de string

tck

tcl

Longitud de las marcas en los ejes

fracción entre ancho y alto de la región gráfica

como fracción de la altura de línea

usr Vector con las coordenadas de la región gráfica c(x1, x2, x3, x4)

xaxp

yaxp

Vector c(x1, x2, n) o c(y1, y2, n) con los extremos y el número de marcas de los ejes

xaxs

yaxs

Estilo para el cálculo de los intervalos entre marcas: "r" (regular), "i" (interno), "s" (estándar), "e" (extendido) o "d" (directo)

xaxt

yaxt

Tipo de ejes: "s" (mostrar), "n" (suprimir)

xaxt

yaxt

Escala logarítmica (FALSE)

xpd

ypd

Recorte a FALSE (región del gráfico), TRUE (región de la figura) o NA (región del dispositivo)
ylbias Posición del texto en los márgenes

Al ejecutar par() se obtiene una lista con 72 objetos con los valores que asume inicialmente en una sesión de R cada uno de los parámetros. Cuando se modifica(n) alguno(s), todos los gráficos que se construyan de ahí en adelante estarán afectados por el cambio realizado. Por este motivo, puede ser interesante almacenar todas las opciones definidas por defecto (o en un determinado momento) en un objeto

para poder restaurarlas en cualquier momento posterior

Gráficos de alto nivel

plot

Esta función gráfica ofrece muchas variantes, dependiendo del tipo de objeto al que se aplique (un vector, dos vectores de igual longitud, un data.frame, una función e incluso otros objetos). Es lo que llamamos coerción: la salida depende de los valores que introduzcamos para los argumentos.

Seguramente el caso más simple corresponda a la representación de dos variables numéricas v1 e v2, que nos devolverá su diagrama de dispersión o de puntos.

Por ejemplo, simulamos valores distribuidos uniformemente para la variable v1 y para v2 una transformación lineal de v1 más un error aleatorio con distribución normal y los representamos con plot

# Generamos n valores distribuidos uniformemente entre 1 y 10
n=100
v1=runif(n,0,10)
# Generamos los valores de v2 como una transformación lineal
# de los valores de v1, más una componente aleatoria
v2=2*v1+rnorm(n)
plot(v1,v2)

Podemos personalizar el gráfico, modificando la forma de los puntos, asignando a pch1 el valor correspondiente al símbolo que queramos usar:

el tamaño de dichos símbolos, con cex (cuyo valor por defecto es 1),

y también su color. Para ello que se dispone de múltiples opciones, confirmando la enorme versatilidad de R. Por ejemplo con los parámetros col y bg, usando los números del 1 al 8 según la escala:

con la función colors() con el valor numérico del color correspondiente:

el nombre del color2

## [1] "white"         "aliceblue"     "antiquewhite"  "antiquewhite1"
## [5] "antiquewhite2"

el valor HEX del color, col = "#0000FF"3, o bien el valor RGB, haciendo uso de la función rgb, que toma la intensidad de colores rojo, verde y azul como argumentos. Su sintasxis es la siguiente:

rgb(red, green, blue, alpha, names=NULL, maxColorValue = 1)

De forma predeterminada, estos valores se encuentran entre 0 y 1, aunque se pueden modificar con el argumento maxColorValue para tener valores entre 0 y el valor que especifiquemos (maxColorValue = 255, es el estándar para la representación del color RGB). Esta función también permite cambiar la transparencia del color, con el argumento alpha, que toma valores desde 0 (completamente transparente) hasta 1 (opaco).

Por ejemplo, vamos a usar círculos rojos rellenos en gris, con un tamaño un tercio inferior a los de la gráfica anterior.:

plot(v1,v2,
     pch=21,col="red",bg="gray",cex=2/3)

También podemos añadir un título (main) y/o un subtítulo (sub) así como etiquetas a los ejes (xlab e ylab):

plot(v1,v2,pch=21,col="red",bg="gray",cex=2/3,
     main="Mi primer gráfico", 
     sub="Mejorable",
     xlab="x", ylab="y")

y darle formato al texto con family y font (en el siguiente ejemplo elegimos el tipo de letra Times New Roman4 y además lo destacamos en negrita):

plot(v1,v2,pch=21,col="red",bg="gray",cex=2/3,
     main="Mi primer gráfico", 
     sub="Mejorable",
     xlab="x", ylab="y",
     family="serif", font=2)

R facilita la creación de dibujos más elaborados, añadiendo a los gráficos de alto nivel gráficos de bajo nivel.

Por ejemplo, podríamos estar interesados en añadir la recta de regresión muestral (que ajusta por mínimos cuadrados nuestro conjunto de datos) e incluir su expresión:

# Estimamos la recta de regresión muestral y la guardamos 
# en el objeto regresion, para poder utilizarla posteriormente
regresion<-lm(v2~v1)
# Representamos el conjunto de datos
plot(v1,v2,pch=21,col="red",bg="gray",cex=2/3,
     main="Mi primer gráfico", xlab="x", ylab="y",
     family="mono" , font=2)
# Añadimos la recta de regresión muestral
abline(regresion)
# Añadimos la expresión de la recta de regresión muestral
text(6,5,paste("y = ",round(coef(regresion)[2],2),
               "x +", round(coef(regresion)[1],2),"\n","r = ",round(cor(v1,v2),2)))

Si los puntos a representar aparecen repetidos, no podríamos apreciarlo en la nube de puntos.

sunflowerplot

Representa los puntos como girasoles con tantos pétalos como veces se repita el punto. De esta forma, la superposición se visualiza en lugar quedar oculta, como ocurría con plot.

Como ya hemos mencionado, la función plot devuelve distintos tipos de gráficos según los valores sobre los que la evaluemos. Por ejemplo, si convertimos la variable v1 en un factor (con as.factor(trunc(v1))) muestra un diagrama de barras:

v1f <- as.factor(trunc(v1))
plot(v1f)

Sin embargo, si la evaluamos sobre un único argumento numérico, lo representa como una secuencia o serie temporal:

plot(v1)

Además de la versatilidad que le aporta la coerción, es posible personalizarlo aún más, definiendo qué tipo de gráfico queremos que devuelva como salida, según el valor del argumento type:

"p" Puntos
"l" Líneas
"b" Ambos (puntos y líneas)
"c" Sólo la parte de las líneas de "b"
"o" Ambos (puntos y líneas) sobregraficados
"h" Líneas verticales
"s" Escalones (posterior)
"S" Escalones (previo)
"n" Invisible

que lucirían así:

Para modificar el tipo de líneas pasamos el valor adecuado al argumento lty, según el nombre o el código numérico:

Para mayor personalización, se puede especificar con una secuencia de números la longitud de la parte coloreada y vacía de la línea

plot(v1,type="b", 
     lty="52", pch=16, col="red3")

Otro de los argumentos que se puede pasar a plot es una función. Por ejemplo, podemos representar la función \(f(x)=x \sin^2(x)\) en el intervalo \([0,10]\), añadiendo además la expresión matemática 5 como título:

# Definimos la función
f <- function(x)
  x*sin(x)^2
# Representamos f(x) desde 0 hasta 10
plot(f,0,10, main=expression(f(x)==xsin(x)^2))

También podemos usar plot como función de bajo nivel (con add=TRUE), muy útil por ejemplo para añadir otra función \(g(x)=2x\sin^2(x)\) a la anterior:

# Definimos sendas funciones
f=function(x)
  x*sin(x)^2
g=function(x)
  2*x*sin(x)^2
# Las representamos desde 0 hasta 10
plot(f,0,10)
plot(g,0,10, add=TRUE, col="red")

El gráfico que aparece por defecto es claramente mejorable. Por ejemplo, podemos personalizar la región de dibujo (ya que la región utilizada para la representación se ha determinado a partir de la primera función), para ver las curvas completas, personalizamos el valor de ylim

# Definimos las funciones
f=function(x)
  x*sin(x)^2
g=function(x)
  2*x*sin(x)^2
# Las representamos desde 0 hasta 10
plot(f,0,10, ylim=c(0,16))
plot(g,0,10, add=TRUE, col="red")

Además, se puede añadir una leyenda para identificar las funciones y facilitar su lectura

# Definimos las funciones
f=function(x)
  x*sin(x)^2
g=function(x)
  2*x*sin(x)^2
# Las representamos desde 0 hasta 10
plot(f,0,10, ylim=c(0,16), lty=2)
plot(g,0,10, add=TRUE, col="red")
legend("topleft", c(expression(f(x)==x*sin(x)^2),expression(g(x)==2*x*sin(x)^2)), 
       col = c("black","red"), lty = c(2, 1), cex=0.75, 
       merge = TRUE, bg = "gray90")

Los gráficos son una herramienta muy potente para representar datos, cuyo principal objetivo suele ser mostrar de una manera visual y simple los posibles patrones presentes en ellos. Para conseguirlo debemos elegir el tipo adecuado, así como su formato. Una mala elección puede ocultar los patrones en vez de mostrarlos. Por ejemplo, supongamos que queremos representar la función \(\sin{i}\), para \(i=1, 2, ..., n\). Si lo hacemos utilizando puntos, con todas las opciones de forma por defecto

n <- 50
x <- 1:n
plot(x,sin(x))

no parece apreciarse ningún patrón. Sin embargo, si cambiamos su aspecto utilizando la misma escala para ambos ejes (asp=1)

n <- 50
x <- 1:n
plot(x,sin(x), asp=1)

el patrón existente sale a la luz. Otra opción podría ser representar líneas en vez de puntos:

n <- 50
x <- 1:n
plot(x,sin(x), type="l")

curve

Sirve para dibujar una curva en un intervalo dado. Su estructura es:

curve(expr, from = NULL, to = NULL, n = 101, add = FALSE,
      type = "l", xname = "x", xlab = xname, ylab = NULL,
      log = NULL, xlim = NULL, ...)

Con los argumentos:

  • expr: nombre de la función que se desea representar

  • from, to: valores mínimo y máximo del intervalo

  • n: número de puntos en los cuales se va a evaluar la función

  • add: valor lógico para indicar si se desea agregar la curva a un gráfico ya existente


hist

La forma habitual de representar un conjunto de datos numéricos para observar su distribución es con un histograma. Podemos crearlo con la función hist() a la que debemos aportar como argumento un vector numérico x. El resto de parámetros son opcionales (al tener asignados valores por defecto)6.

# Generamos un conjunto de datos con distribución normal 
x=rnorm(100)
# Representamos su distribución
hist(x)->salida

Además de crear el histograma, la función hist devuelve los puntos que determinan los intervalos, las frecuencias absolutas y relativas y la marca de clase (o punto medio de cada intervalo):

## $breaks
## [1] -2.0 -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5  2.0
## 
## $counts
## [1]  6  8 14 21 18 18 10  5
## 
## $density
## [1] 0.12 0.16 0.28 0.42 0.36 0.36 0.20 0.10
## 
## $mids
## [1] -1.75 -1.25 -0.75 -0.25  0.25  0.75  1.25  1.75
## 
## $xname
## [1] "x"
## 
## $equidist
## [1] TRUE
## 
## attr(,"class")
## [1] "histogram"

Podemos modificar fácilmente su estilo añadiendo parámetros gráficos (algunos de los cuales ya conocemos y otros son propios de esta función como el número de intervalos breaks o el tipo de frecuencias representadas absolutas o relativas con freq)

Cambiar el tipo de frecuencias (de absolutas a relativas), solo modifica la escala del eje vertical, pero no la forma del histograma:

# Generamos un conjunto de datos con distribución normal 
x=rnorm(100)
par(mfrow=c(1,2))
hist(x, freq=TRUE)
hist(x, freq=FALSE)

No ocurre lo mismo cuando forzamos el número de intervalos7 en los que agrupar los valores a representar:

par(mfrow=c(1,2))
hist(x, freq=FALSE, breaks=7,
     main="Histograma",ylab="Frecuencia relativa", col=rgb(0,0.5,0.5))
hist(x, freq=FALSE, breaks=20,
     main="Histograma",ylab="Frecuencia relativa", col=rgb(0,0.5,0.5))

De hecho, como la forma de los histogramas depende de los intervalos, suele ser muy útil representar su densidad, para poder observar la forma de la distribución de la manera más precisa posible:

hist(x, freq=FALSE, breaks=6,
     main="Histograma",ylab="Frecuencia relativa", col=rgb(0,0.75,0.75))
lines(density(x),lty="dotted",lwd=2)

Otra cuestión interesante puede ser comparar el histograma con una distribución teórica, superponiéndola a éste. En el ejemplo con el que estamos trabajando, vamos a comparar con la curva de la densidad normal estándar (que es de la que hemos simulado los valores de x):

hist(x, freq=FALSE, breaks=20,
     main="Histograma",ylab="Frecuencia relativa", col=rgb(0,0.90,0.90))
lines(density(x),lty="dotted",lwd=2)
curve(dnorm, lty="dotdash",lwd=3, add=TRUE)

Si la muestra fuese más grande, ambas distribuciones se parecerían mucho más:

# Generamos un conjunto de datos mucho más grande con distribución normal estándar
x=rnorm(10^6)
# Representamos el histograma de frecuencias relativas
hist(x, freq=FALSE, breaks=100, 
     main="Histograma",ylab="Frecuencia relativa")
# Añadimos la curva de la densidad normal estándar
curve(dnorm, add=TRUE, col="red", lwd=2)
lines(density(x),lty="dotted",lwd=2)

Como con cualquier otra función, podemos consultar todas sus opciones con ?hist().

qqnorm, qqplot y qqline

Los gráficos cuantil cuantil ayudan a explorar si un conjunto de datos (o muestra) y proviene de una población con cierta distribución.

qqnorm sirve explora la normalidad de una muestra, mientras que qqplot tiene un propósito más general (crea el gráfico cuantil cuantil para cualquier distribución).

Otra función útil es qqline, que sirve para agregar una línea de referencia al gráfico cuantil cuantil obtenido con qqnorm.

stem

Los diagramas de tallo y hojas son un tipo de representación clásica de la distribución de datos numéricos, similar a un histograma pero en formato de texto. Para construirlo, los datos se dividen en tallo (primer o primeros dígitos del número) y hoja (el resto de dígitos). En R se pueden crear con la función stem.

# Generamos un conjunto de datos con distribución normal estándar, no demasiado grande
x=rnorm(10^2)
# Representamos el diagrama de tallo y hojas
stem(x)
## 
##   The decimal point is at the |
## 
##   -2 | 5400
##   -1 | 85543211110
##   -0 | 999999888876665554444333222111111110000
##    0 | 0000111222233333455566679
##    1 | 011223345678889
##    2 | 23388
##    3 | 0

Se trata de un gráfico tosco, aunque tiene la ventaja de requerir muy pocos recursos y no se pierde la información contenida en los datos concretos.


boxplot

Los diagramas de caja y bigotes, son representaciones gráficas que permiten resumir las principales características de los datos (acerca de su simetría, dispersión, posición y presencia de valores atípicos). La caja comienza en el primer cuartil y termina en el tercero (por lo que contendrá el 50% de los datos centrales), con una línea dentro para marcar el valor de la mediana. A cada lado de la caja se dibuja un segmento con los datos más alejados, sin contar con los valores atípicos (que aparecen como círculos, caso de existir).

# La siguiente instrucción permite representar una matriz de gráficos
# En este caso, vamos a representar dos gráficos en una fila
par(mfrow=c(1,2))
x=rnorm(100)
# Primer boxplot
boxplot(x)
# Segundo boxplot (con los mismos datos, añadiendo un dato atípico)
boxplot(c(x,5))

Podemos representar los intervalos de confianza al 95% para la mediana, estableciendo el argumento notch como TRUE y mejorar la capacidad de hacer comparaciones forzando a que ambos tengan la misma escala vertical

par(mfrow=c(1,2))
boxplot(x,notch=TRUE, ylim=c(-5,5))
# Añadimos un dato atípico
boxplot(c(x,5),notch=TRUE, ylim=c(-5,5))

Este tipo de gráficos resulta especialmente útil para comparar comportamientos8.

# Generamos sendas secuencias de valores de tres distribuciones
# como si provinieran de distintos procesos A, B y C
xA=rnorm(100,1,2)
xB=rnorm(100,3,1/2)
xC=runif(100,0,6)
datos=data.frame(x=c(xA,xB,xC), Proceso=rep(c("A","B","C"), c(100,100,100)))
boxplot(x~Proceso, data=datos, notch=TRUE)

Una limitación de este tipo de gráficos es que no están diseñados para detectar multimodalidad, por lo que puede ser recomendable combinarlos con el histograma o la curva de densidad 9. Veamos cómo hacerlo con un ejemplo donde concatenamos dos muestras que provienen de distribuciones normales con distintos parámetros:

xA=rnorm(1000,1,1/2)
xB=rnorm(1000,5,2)
x=c(xA,xB)
# Histograma
hist(x,probability=TRUE, 
     main="", xlab="",ylab="",axes=FALSE,
     col=rgb(0.5,0,0.5, alpha=0.5),breaks=40)
# Eje
axis(1)
# Densidad
lines(density(x), col="red", lwd=2)
# Boxplot
par(new=TRUE)
boxplot(x, horizontal=TRUE, axes=FALSE,
        col=rgb(0,0,0.15, alpha=0.25))
text(9,1.25,paste("Media:",round(mean(x),2),
                  "\n", "Mediana", round(median(x),2),
                  "\n", "Desviación estándar", round(sd(x),2)),
     cex=0.75
     )

Otra alternativa para poner de manifiesto la distribución de los datos es agregar los puntos sobre los diagramas de caja. Podemos hacerlo con la función stripchart, especificando add=TRUE como argumento.

# Generamos sendas secuencias de valores de tres distribuciones
# como si provinieran de distintos procesos A, B y C
xA=rnorm(100,1,2)
xB=rnorm(100,3,1/2)
xC=runif(100,0,6)
datos=data.frame(x=c(xA,xB,xC), Proceso=rep(c("A","B","C"), c(100,100,100)))
boxplot(x~Proceso, data=datos)
stripchart(x~Proceso, data=datos, add=TRUE,
           vertical=TRUE, method="jitter", 
           pch=1, cex=1/2, col=2:4)


barplot y pie

Cuando una variable es cualitativa o numérica, con pocos valores diferentes, es habitual representarla con un gráfico de barras o de sectores.

# Leemos el conjunto resumido de microdatos del INE sobre uso de TICs
# Es necesario cambiar la ruta mostrada por la propia:
library(readr)
TIC <- read_csv("/Users/maribelparra/Desktop/CursoOviedo/TIC.csv")
## Rows: 15027 Columns: 7
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): Sexo, UsoInternet, Confianza
## dbl (4): Edad, Nivel, NCompras, ValorCompras
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
str(TIC)
## spc_tbl_ [15,027 × 7] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Edad        : num [1:15027] 98 71 51 81 76 76 72 59 71 83 ...
##  $ Sexo        : chr [1:15027] "Mujer" "Mujer" "Mujer" "Mujer" ...
##  $ Nivel       : num [1:15027] 1 1 7 1 1 1 1 3 1 1 ...
##  $ NCompras    : num [1:15027] NA NA NA NA NA NA NA NA NA NA ...
##  $ ValorCompras: num [1:15027] NA NA NA NA NA NA NA NA NA NA ...
##  $ UsoInternet : chr [1:15027] NA NA "Menos de 3 meses" NA ...
##  $ Confianza   : chr [1:15027] NA NA "Bastante" NA ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Edad = col_double(),
##   ..   Sexo = col_character(),
##   ..   Nivel = col_double(),
##   ..   NCompras = col_double(),
##   ..   ValorCompras = col_double(),
##   ..   UsoInternet = col_character(),
##   ..   Confianza = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>
head(TIC)

Podríamos hacernos muchas preguntas acerca de la información que contienen los datos. Por ejemplo, nos podría interesarnos conocer cómo es la muestra respecto a la edad y el sexo de las personas que respondieron la encuesta del INE. Para representar la edad, podemos usar un histograma, que ya hemos aprendido a hacer:

Para el sexo, al ser cualitativa necesitamos incorporar otros tipos de gráficos como el diagrama de barras o el de sectores

Podría ser interesante representar ambas variables en un mismo gráfico para determinar si la edad tiene la misma distribución entre hombres y mujeres:

Si lo que nos interesa es analizar cómo se comporta la muestra respecto a la confianza, al ser una variable cualitativa representamos un diagrama de barras o de sectores

Presenta las categorías por orden alphanumérico, que puede no ser una buena opción para entender un gráfico. Se puede podificar dicho orden:

Podemos incluir un segundo factor y representar un diagrama de barras apiladas de frecuencias absolutas:

x=table(TIC$Sexo, TIC$Confianza)
barplot(x,
        col=c("#CCFF99","#9999FF"))

Añadir una leyenda suele ayudarnos a entender mejor un gráfico

barplot(x,
        col=c("#CCFF99","#9999FF"))
legend("topright",legend=c("Hombre","Mujer"),
       fil=c("#CCFF99","#9999FF"), title="Sexo")

Si nos interesa representar frecuencias relativas en vez de frecuencias absolutas o recuentos, usaremos la función prop.table() pudiendo elegir si las calculamos por fila (1), por columna (2) o usando toda la tabla como grupo si no escribimos nada.

barplot(prop.table(x),
        col=c("#CCFF99","#9999FF"))

barplot(prop.table(x,margin=1),
        col=c("#CCFF99","#9999FF"))

barplot(prop.table(x,margin=2),
        col=c("#CCFF99","#9999FF"))


persp

Con esta función genérica, R nos facilita la tarea de dibujar gráficos en perspectiva de una superficie sobre el plano \(XY\).

x <- seq(-20, 20, length.out = 51)
y <- x
f<- function(x,y) 
{
  r=sqrt(x^2+y^2)
  sin(r)/r
}
z <- outer(x, y, f)
persp(x, y, z)

Es sencillo modificar la perspectiva, para apreciar mejor la forma de la superficie

persp(x, y, z, theta = 30, phi = 30)

o el aspecto

persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue")

Gráficos de bajo nivel

Para añadir elementos a representaciones gráficas ya creadas, que podría ser un gráfico vacío o transparente.

axis

Su utilidad es añadir ejes al gráfico actual personalizando elementos como la posición side: 1 (abajo), 2 (izquierda), 3 (arriba) o 4 (derecha)

axis(side, at = NULL, labels = TRUE, tick = TRUE, line = NA,
     pos = NA, outer = FALSE, font = NA, lty = "solid",
     lwd = 1, lwd.ticks = lwd, col = NULL, col.ticks = NULL,
     hadj = NA, padj = NA, gap.axis = NA, ...)

grid

Es una función muy útil para construir rejillas sobre un gráfico. Estas rejillas pueden servir como referencia para facilitar su interpretación o como guía para colocar otros elementos. Su sintaxis

axis(side, at = NULL, labels = TRUE, tick = TRUE, line = NA,
     pos = NA, outer = FALSE, font = NA, lty = "solid",
     lwd = 1, lwd.ticks = lwd, col = NULL, col.ticks = NULL,
     hadj = NA, padj = NA, gap.axis = NA, ...)

incluye los números de celdas a dibujar en cada eje, nx e ny, su color, tipo de línea y grosor.

Es recomendable agregar la rejilla a un gráfico antes de poner el contenido para que no interfiera.

text

Añade los textos proporcionados en labels en las posiciones indicadas en x e y

text(x, y = NULL, labels = seq_along(x$x), adj = NULL,
     pos = NULL, offset = 0.5, vfont = NULL,
     cex = 1, col = NULL, font = NULL, ...)

lines

Une los puntos proporcionados en x e y con líneas.

lines(x, y = NULL, type = "l", ...)

points

Representa una secuencia de puntos centrados en las coordenadas especificadas.

points(x, y = NULL, type = "p", ...)

abline

Esta función es muy útil para dibujar líneas rectas dadas por la ecuación \(y=a+bx\) donde \(a\) representa el término independiente y \(b\) la pendiente de la recta. La sintaxis de la función es:

abline(a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
       coef = NULL, untf = FALSE, ...)

Sus argumentos son:

  • a, b: recta horizontal \(y=a+bx\)

  • h: recta horizontal \(y=h\)

  • v: recta vertical \(x=v\)

  • coef: vector con dos elementos (término independiente y pendiente)

  • reg: objeto de clase lm resultante de haber usado la función lm

Añade una o más líneas rectas al gráfico actual. Se puede definir la recta con la constante a y la pendiente b, ambos valores en coef. Otra opción es proporcionar valores en h o v para trazar líneas horizontales o verticales, respectivamente.

arrows

Dibuja flechas entre pares de puntos definidos por las coordenadas del punto de inicio (x0, y0) y final (x1 e y1) con la longitud (en pulgadas) de los bordes de punta de la flecha que marque length

arrows(x0, y0, x1 = x0, y1 = y0, length = 0.25, angle = 30,
       code = 2, col = par("fg"), lty = par("lty"),
       lwd = par("lwd"), ...)

poligon

Dibuja polígonos con la siguiente sintaxis

polygon(x, y = NULL, density = NULL, angle = 45,
        border = NULL, col = NA, lty = par("lty"),
        ..., fillOddEven = FALSE)

y argumentos:

  • x, y: vectores con las coordenadas de vértices del polígono

  • density: nº de líneas por pulgada para rellenar el polígono

  • angle: ángulo de inclinación de la líneas de relleno

  • border: color para el borde del polígono ('transparent' sin borde)

  • col: color para el fondo del polígono

  • ...: otros parámetros gráficos

box

Permite agregar un cuadro personalizado alrededor del gráfico

Ejemplos adicionales

1: La disposición de las pepitas de un girasol sigue un modelo matemático cuyas coordenadas polares para la semilla \(n-\)ésima son: \[ \begin{array}{l} r=n\\ \theta=\frac{137.51 \pi}{180}r \end{array} \] Representar 1000 pepitas con círculos.

n <- 1000
r <- 1:n 
theta <- 137.51*pi*r/180
# pasamos a coordenadas cartesianas
x <- cos(theta)*r
y <- sin(theta)*r
plot(x,y,asp=1)

2: Supongamos que se lanzan dos dados: uno negro y otro verde. Vamos a representar cómo varía la estimación de la probabilidad de que el dado negro tenga un valor mayor que el verde.

n=1000
negro <- sample(6, size = n, replace = TRUE)
verde <- sample(6, size = n, replace = TRUE)
p <- cumsum(negro>verde)/(1:n)
plot(p, type = "l", col = "blue3", 
    xlab = "Número de experimentos",
    ylab = "Probabilidad",
    main = "Convergencia de la simulación"
)
grid()
abline(h = 15/36, col = "red3", lwd = 2)

3: Simular puntos dentro de la región \([-4,4]\times[0,1/2]\) y colorear de forma diferente si están por debajo o por encima de la densidad normal estándar.

plot(dnorm, -4, 4, main="Campana de Gauss", 
     xlab="x", ylab="Densidad de la normal", 
     col="red3", lwd=3)
points(x=c(-4,4), y=c(0,0), type="l") # dibuja eje X
# simulamos n puntos al azar en el recuadro
n=1000
x = runif(n=1000, min=-4, max=4) 
y = runif(n=1000, min=0, max=1/2) 
# valoramos de qué color será cada punto
color=ifelse(y<dnorm(x), "red3", "gray")
points(x, y, col=color, pch=20) # representamos cada punto con su color

4: Vamos a obtener ejemplos de los diferentes modelos de gráficos que se generan dependiendo del tipo de datos que le pasemos como argumento:

par(mfrow = c(2, 3)) # Matriz de gráficos 2x3
# Generamos datos de distintos tipos
n=100
x <- rnorm (n)
y <- rnorm (n)
xt <- ts(matrix(x, nrow = n, ncol = 1),
         start = c(2013, 1), frequency = 12)
fechas <- seq(as.Date("2013/1/1"), by = "month", length = n)
factor <- factor(trunc(x))
f <- function(x) x^2
u=runif(n)
tabla=data.frame(v1=u, 
                 v2=u+rnorm(n,0,0.1), 
                 v3=u^2+rnorm(n,0,1/2))
plot(x, y, main = "Gráfico de dispersión")
plot(factor, main = "Diagrama de barras")
plot(factor, x, main = "Diagrama de cajas y bigotes")
plot(xt, main = "Serie temporal",type="l")
plot(fechas, x, main = "Gráfico basado en fechas")
plot(f, -5, 5, main = "Función")

par(mfrow = c(1, 1))
plot(tabla, main = "Matriz de correlaciones")

par(mfrow = c(1, 1))

  1. El valor de pch, en realidad puede ser cualquier símbolo.↩︎

  2. Para conocer el nombre de todos los colores disponibles se puede ejecutar la instrucción colors().↩︎

  3. Por ejemplo, col=1, col="white", col="#FFFFFF" son equivalentes.↩︎

  4. Es necesario que el tipo de letra elegido esté instalada en nuestro ordenador, porque en otro caso no tendría efecto. Las fuentes integradas son sans (Arial), serif (Times New Roman), mono (Courier) y symbol (Standard Symbols L). Es posible añadir otras con los paquetes extrafonty showtext.↩︎

  5. El resultado de demo(plotmath) incluye varias tablas que muestran las funciones disponibles para escribir expresiones matemáticas y el resultado.↩︎

  6. ```{r} hist(x, breaks = “Sturges”, freq = NULL, probability = !freq, include.lowest = TRUE, right = TRUE, fuzz = 1e-7, density = NULL, angle = 45, col = “lightgray”, border = NULL, main = paste(“Histogram of” , xname), xlim = range(breaks), ylim = NULL, xlab = xname, ylab, axes = TRUE, plot = TRUE, labels = FALSE, nclass = NULL, warn.unused = TRUE, …)

    ```↩︎

  7. Los posibles valores de breaks son un vector con los puntos de corte (o función que los calcule), un valor numérico (en cuyo caso R lo redondea al valor más próximo que permita construir intervalos sencillos) o el nombre del algoritmo que los calcule ("Sturges", "Scott", "Freedman-Diaconis").↩︎

  8. Si los intervalos de confianza de dos diagramas no se solapan, significa que hay una fuerte evidencia estadística de que las medianas son diferentes.↩︎

  9. Una opción mejor son los diagramas de violín, que veremos más adelante en el curso.↩︎