Data Visualization

Proceso del Tidyverse

Proceso del Tidyverse

“Un simple gráfico ha brindado más información a la mente del analista de datos que cualquier otro dispositivo” John Tukey

La visualización de datos es una habilidad esencial para trabajar con datos, es una combinación de comprensión estadística y principios de diseño, así, la visualización de datos se trata de análisis de gráficos de datos y comunicación y percepción.

Para permitir una visualización de datos acorde a los principios de una gramática de gráficos, Hadley Wickham creó el paquete ggplot2.

Paquete ggplot2

El paquete ggplot2 es un sistema para crear gráficos declarativamente, basado en el libro The Grammar of Graphics de Leland Wilkinson (1999). Usted proporciona los datos, le dice a ggplot2 cómo asignar variables a la estética, qué primitivas gráficas usar y ggplot2 se ocupa de los detalles.

Puedes encontrar más información del paquete ggplot2 en ggplot2.tidyverse.org

Gramática de los gráficos

En ggplot2 hay un total de 7 capas que podemos agregar a un gráfico:

Gramática de los gráficos

Gramática de los gráficos

Data Layer

La capa de datos especifica los datos que se trazan.

Revisaremos lo que significan las capas con un conjunto de datos de ejemplo. Cargaremos el dataset fifa21.xlsx que contiene 18944 observaciones y 27 variables.

glimpse(fifa21)
## Rows: 18,944
## Columns: 27
## $ Nombre_Jugador           <chr> "L. Messi", "Cristiano Ronaldo", "J. Oblak", …
## $ Edad                     <dbl> 33, 35, 27, 31, 28, 29, 21, 28, 28, 27, 28, 2…
## $ Altura_cm                <dbl> 170.1, 187.2, 188.3, 184.4, 175.5, 181.6, 178…
## $ Peso_kg                  <dbl> 72.144, 83.166, 87.174, 80.160, 68.136, 72.10…
## $ Nacionalidad             <chr> "Argentina", "Portugal", "Slovenia", "Poland"…
## $ Club                     <chr> "FC Barcelona", "Juventus", "Atlético Madrid"…
## $ Liga                     <chr> "Spain Primera Division", "Italian Serie A", …
## $ overall                  <dbl> 93, 92, 91, 91, 91, 91, 90, 90, 90, 90, 90, 9…
## $ Valor                    <dbl> 67500000, 46000000, 75000000, 80000000, 90000…
## $ Sueldo                   <dbl> 560000, 220000, 125000, 240000, 270000, 37000…
## $ Pie_preferido            <chr> "Izquierdo", "Derecho", "Derecho", "Derecho",…
## $ Reputacion_Internacional <dbl> 5, 5, 3, 4, 5, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, …
## $ Pie_debil                <dbl> 4, 4, 3, 4, 5, 5, 4, 4, 3, 3, 4, 3, 3, 4, 3, …
## $ Movim_habiles            <dbl> 4, 5, 1, 4, 5, 4, 5, 1, 2, 1, 4, 4, 1, 4, 3, …
## $ Num_camiseta             <dbl> 10, 7, 13, 9, 10, 17, 7, 1, 4, 1, 10, 11, 1, …
## $ Ritmo                    <dbl> 85, 89, NA, 78, 91, 76, 96, NA, 76, NA, 94, 9…
## $ Disparo                  <dbl> 92, 93, NA, 91, 85, 86, 86, NA, 60, NA, 85, 8…
## $ Pases                    <dbl> 91, 81, NA, 78, 86, 93, 78, NA, 71, NA, 80, 8…
## $ Regates                  <dbl> 95, 89, NA, 85, 94, 88, 91, NA, 71, NA, 90, 9…
## $ Defensa                  <dbl> 38, 35, NA, 43, 36, 64, 39, NA, 91, NA, 44, 4…
## $ Fisico                   <dbl> 65, 77, NA, 82, 59, 78, 76, NA, 86, NA, 76, 7…
## $ Portero_mano             <dbl> NA, NA, 92, NA, NA, NA, NA, 85, NA, 88, NA, N…
## $ Portero_patada           <dbl> NA, NA, 78, NA, NA, NA, NA, 88, NA, 85, NA, N…
## $ Portero_reflejos         <dbl> NA, NA, 90, NA, NA, NA, NA, 90, NA, 89, NA, N…
## $ Portero_velocidad        <dbl> NA, NA, 52, NA, NA, NA, NA, 45, NA, 51, NA, N…
## $ Portero_posicionamiento  <dbl> NA, NA, 90, NA, NA, NA, NA, 88, NA, 91, NA, N…
## $ Posicion_Jug             <chr> "Mediocampo", "Delantero", "Portero", "Delant…

Cuando graficamos la primera capa, lo que tenemos es un cuadrado en blanco:

ggplot(data=fifa21)

Aesthetics Layer

El siguiente elemento gramatical es la capa estética, o aes para abreviar. Esta capa especifica cómo queremos mapear nuestros datos en las escalas de la gráfica.

La capa estética asigna variables en nuestros datos a escalas en nuestra visualización gráfica, como las coordenadas \(x\) e \(y\). En ggplot2 la capa estética se especifica mediante la función aes().

Vamos a crear un gráfico de la relación entre la edad y el peso de los jugadores de fifa21, colocándolos en los ejes \(x\) e \(y\) respectivamente. Aquí podemos notar que pasamos de un cuadro en blanco a un gráfico con la variable y las escalas de Edad mapeadas en el eje \(x\) y Peso_kg en el eje \(y\).

ggplot(fifa21, aes(Edad, Peso_kg))

Geometrics Layer

El siguiente elemento esencial para la visualización de datos es la capa de geometrías. Solo para demostrarle que está creando objetos gráficos R, asignemos el gráfico anterior con capas de datos y estética solo a un objeto R llamado p:

p <- ggplot(fifa21, aes(Edad, Peso_kg))

Ahora digamos que queremos agregar los puntos de datos sin procesar individuales para crear un diagrama de dispersión. Esta es una capa geométrica y el tipo de geometría que queremos agregar son puntos, entonces utilizamos geom_jitter() que es muy parecido a un gráfico de puntos geom_point().

Hay una notación especial que es similar al operador ‘pipe’ visto antes, el signo +.

p + geom_jitter()

Si nos fijamos en el diagrama de dispersión, no se diferencian grupos, se ve un solo grupo grande, pero si quisiéramos conocer la misma relación distribuida por la posición del jugador existen diferentes maneras en que podemos visualizar o separar esta estructura de agrupación grande.

Facets Layer

La capa de facetas permite crear subtramas dentro del mismo objeto gráfico. Las tres capas anteriores son las capas esenciales. La capa de facetas no es esencial, sin embargo, dados sus datos, puede encontrar que le ayuda a explorar o comunicar sus datos de mejor manera.

Vamos a crear facetas de nuestro diagrama de dispersión por la posición del jugador Posicion_Jug:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug))

Statistics Layer

La capa de estadísticas le permite trazar valores estadísticos calculados a partir de los datos. Hasta ahora solo hemos trazado los valores de datos sin procesar. Sin embargo, podemos estar interesados en trazar algunas estadísticas o valores calculados, como una línea de regresión, medias, barras de error estándar, etc.

Agreguemos una línea de regresión al diagrama de dispersión. Primero sin la capa de facets y luego con la capa de facets.

Utilizando la capa facets:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug)) +
    stat_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula 'y ~ x'

Sin utilizar la capa facets:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    stat_smooth(method = "lm", se = FALSE)
## `geom_smooth()` using formula 'y ~ x'

Coordinates Layer

La capa de coordenadas le permite ajustar las coordenadas \(x\) e \(y\)

Puede ajustar los valores mínimo y máximo, así como las marcas principales. Esto es más útil cuando tiene gráficos separados (sin facets) y desea trazarlos en la misma escala para la comparación.

Este es en realidad un principio de diseño muy importante en la visualización de datos. Si desea comparar dos gráficos separados, entonces deben estar en la misma escala!!!

A continuación le incluiremos coordenadas diferentes y lo llamaremos Gráfico 2:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    stat_smooth(method = "lm", se = FALSE) +
    coord_cartesian(xlim = c(10, 70), ylim = c(20, 140))
## `geom_smooth()` using formula 'y ~ x'

Si efectuamos la comparación entre un gráfico con coordenadas (Gráfico 2) y un gráfico sin especificar las coordenadas (Gráfico 1):

Comparación de las coordenadas en un gráfico (Coordenates Layer)

Comparación de las coordenadas en un gráfico (Coordenates Layer)

Themes Layer

La capa de temas hace referencia a toda la tinta o maquillaje que no sea de datos. Puede cambiar las etiquetas del eje \(x\) o \(y\), agregar un título de trama, modificar un título de leyenda, agregar texto en cualquier parte de la trama, cambiar el color de fondo, las líneas de eje, las líneas de la trama, etc.

Hay tres tipos de elementos dentro de la capa de temas: texto, línea y rectángulo. Juntos, estos tres elementos pueden controlar toda la estética no relacionada con los datos en el gráfico.

Estos 3 elementos pueden ser controlados con la siguiente jerarquía:

Subelementos representados por jerarquías

Subelementos representados por jerarquías

Por ejemplo, puede ver que puede controlar el diseño del texto para el título de la trama y el título de la leyenda con theme(title = element_text()), theme(plot.title = element_text(), legend.title = element_text()).

  • Cualquier elemento de texto se puede modificar con element_text().

  • Cualquier elemento de línea se puede modificar con element_line().

  • Cualquier elemento rect se puede modificar con element_rect().

Por ejemplo, cambiemos algunos elementos temáticos a nuestra trama con facets. Cambiemos las etiquetas de valor del eje \(x\) a fuente roja y aumentemos el tamaño:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug)) +
    stat_smooth(method = "lm", se = FALSE) +
    theme(axis.text.x = element_text(color = "red", size = 14))
## `geom_smooth()` using formula 'y ~ x'

Ahora cambiemos las etiquetas de valor de ambos ejes a fuente roja y aumentemos el tamaño:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug)) +
    stat_smooth(method = "lm", se = FALSE) +
    theme(axis.text = element_text(color = "red", size = 14))
## `geom_smooth()` using formula 'y ~ x'

Es una buena idea tener un tema consistente en todos sus gráficos. Por lo tanto, es posible que desee crear un objeto de tema que pueda agregar a todos sus gráficos.

a_theme <- theme(axis.text.x = element_text(color = "red", size = 14),
                 panel.grid = element_blank(),
                 panel.background = element_rect(fill = "pink"))

Ahora pruebo mi nuevo tema en mi gráfico:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug)) +
    stat_smooth(method = "lm", se = FALSE) +
    a_theme
## `geom_smooth()` using formula 'y ~ x'

Temas integrados

También existen temas integrados:

ggplot(fifa21, aes(Edad, Peso_kg)) +
    geom_jitter() +
    facet_wrap(vars(Posicion_Jug)) +
    stat_smooth(method = "lm", se = FALSE) +
    theme_minimal()
## `geom_smooth()` using formula 'y ~ x'

Visualización univarida de variables numéricas

Nos vamos a introducir a las geometrías que existen y cuándo puedo utilizar algunas de ellas. Empezamos cuando quiero visualizar una variable y esta es continua:

Geometrías para una variable continua

Geometrías para una variable continua

Gráfico de densidad

Empecemos a explorar la variable numérica continua Peso_kg:

fifa21 %>% 
    ggplot(aes(x=Peso_kg)) +
    geom_density()

Histogramas

fifa21 %>% 
    ggplot(aes(x=Peso_kg)) +
    geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Si en el histograma deseo cambiar las frecuencias absolutas por relativas, es decir expresar en porcentajes, debo cargar el paquete scales:

library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
fifa21 %>% 
    ggplot(aes(x=Peso_kg)) +
    geom_histogram(aes(y = stat(count) / sum(count))) +
    labs(title= 'Frecuencia de los pesos de los jugadores', 
         x= 'Peso de jugadores',
         y= 'Frecuencia') +
    scale_y_continuous(labels = percent_format())
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Si deseamos unir el histograma con un gráfico de densidad:

fifa21 %>% 
    ggplot(aes(x=Peso_kg)) +
    geom_histogram(aes(y = ..density..)) +
    geom_density(color='orange', linetype='dashed', size=2) +
    labs(title= 'Frecuencia de los pesos de los jugadores', 
         x= 'Peso de jugadores',
         y= 'Frecuencia') +
    scale_y_continuous(labels = percent_format())
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Gráfico de violín

Otra forma de ver la distribución de datos es el gráfico de violín:

fifa21 %>%
    ggplot(aes(x= "", y= Edad)) +
    geom_violin(fill = "steelblue") +
    labs(title= 'Gráfico de violín para la Edad', y= "Edad")

Otra forma de ver el gráfico:

fifa21 %>%
    ggplot(aes(x= "", y= Edad)) +
    geom_violin(fill = "steelblue") +
    coord_flip() +
    labs(title= 'Gráfico de violín para la Edad', y= "Edad")

Estadísticas descriptivas

Gráfico de cajas

El gráfico de cajas permite visualizar los quartiles de nuestra variable:

ggplot(data = fifa21, aes(x = "", y = Edad)) +
    geom_boxplot(fill = "steelblue") +
    coord_flip() +
    labs(title= 'Gráfico de cajas para Edad de jugadores', 
    y= "Edades")

A nuestro boxplot le podemos agregar layers como jitter que grafica la posición de cada observación y nos permite ver dónde se concentran:

ggplot(data = fifa21, aes(x = "", y = Edad)) +
    geom_jitter(alpha = 0.05, color = "gray") +
    geom_boxplot(fill = "steelblue") +
    coord_flip() +
    labs(title= 'Gráfico de cajas para Edad de jugadores', 
         y= "Edades")

Finalmente, podríamos además de visualizar los cuartiles con los boxplot se podría visualizar otros estadísticos:

ggplot(data = fifa21, aes(x = "", y = Edad)) +
    geom_boxplot(fill = "steelblue") +
    stat_summary(fun=mean, geom="point", shape=18, size=3, color="orange") +
    coord_flip() + 
    labs(title= 'Gráfico de cajas para Edad de jugadores', 
         y= "Edades")

Podemos combinar los gráficos anteriores de tal manera que se tenga un mejor entendimiento de nuestra variable, así:

g1 <- fifa21 %>% 
    ggplot(aes(x=Edad)) +
    geom_histogram(aes(y = ..density..), bins = 30) +   # bins=30 deja de mostrar el mensaje de advertencia
    labs(title= 'Frecuencia de las edades de los jugadores', 
         x= 'Edad de jugadores',
         y= 'Porcentaje') +
    scale_y_continuous(labels = percent_format())

g2 <- fifa21 %>% ggplot(aes(x = "", y = Edad)) +
    geom_boxplot() +
    stat_summary(fun=mean, geom="point", shape=18, size=3, color="orange") +
    coord_flip() +
    labs(x= '',
         y= '')

library(cowplot)
plot_grid(g1, g2, ncol = 1, rel_heights = c(7, 1), align = 'v')

Ejercicio propuesto: Combina dos gráficos diferentes a los del ejemplo.

Análisis exploratorio de variables categóricas

Gráfico de barras

Gráfico de barras simple:

fifa21 %>% ggplot(aes(x= Posicion_Jug)) +
    geom_bar( ) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Podemos mejorar el gráfico aumentando la frecuencia con geom_text():

fifa21 %>% ggplot(aes(x= Posicion_Jug)) +
    geom_bar( ) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 500 ) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Sin embargo una recomendación cuándo se habla de gráficos de barras para variables nominales (no ordinales) es que se ordene las clases, una opción es usar el paquete forcats (que viene en el tidyverse). Nótese que se aumenta el label en el eje x:

fifa21 %>% ggplot(aes(x= forcats::fct_infreq(Posicion_Jug))) +
    geom_bar( ) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 500 ) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

También podemos prsentar las barras de forma horizontal con coord_flip():

fifa21 %>% ggplot(aes(x= forcats::fct_infreq(Posicion_Jug))) +
    geom_bar( ) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 700) +
    coord_flip() +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")        

Podemos ordenar tanto barras como etiquetas de forma vertical:

fifa21 %>% ggplot(aes(x= forcats::fct_infreq(Posicion_Jug))) +
    geom_bar( ) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 700) +
    theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")  

Si queremos darle un poco de color también se podría hacer:

fifa21 %>% ggplot(aes(x= forcats::fct_infreq(Posicion_Jug))) +
    geom_bar(aes(fill=Posicion_Jug)) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 700) +
    theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Podemos eliminar la leyenda con legend.position:

fifa21 %>% ggplot(aes(x= forcats::fct_infreq(Posicion_Jug))) +
    geom_bar(aes(fill=Posicion_Jug)) +
    geom_text( aes(label= stat(count)), stat='count', nudge_y= 700) +
    theme(legend.position = "none") +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Gráfico Lollipop

Otro gráfico, quiza más elegante es el conocido como Lollipop, el cual permite centrar la visión del usuario netamente en la cantidad total antes que en la barra per sé:

fifa21 %>% 
    group_by(Posicion_Jug) %>% 
    summarise(Frec=n()) %>% 
    ggplot(aes(x= reorder(Posicion_Jug, -Frec), y= Frec)) +
    geom_segment( aes(xend=Posicion_Jug, y=0, yend=Frec)) +
    geom_point( size=5) +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Con un poco de color y de forma horizontal:

fifa21 %>% 
    group_by(Posicion_Jug) %>% 
    summarise(Frec=n()) %>% 
    ggplot(aes(x= reorder(Posicion_Jug, -Frec), y= Frec)) +
    geom_segment( aes(xend=Posicion_Jug, y=0, yend=Frec)) +
    geom_point( size=5, color="steelblue") +
    coord_flip() +
    labs(title= 'Cantidad de jugadores por posiciones', 
         x= "Posiciones en el campo",
         y= "Cantidad")

Ejercicio propuesto: Replica el siguiente gráfico.

Gráfico de Pastel

Se utiliza para explorar variables categóricas:

fifa21 %>%
    filter(Liga=="Spain Primera Division" & str_detect(Posicion_Jug, "Portero")) %>%
    group_by(Nacionalidad) %>%
    summarise( Frec= n()) %>%
    mutate(Prop= Frec/ sum(Frec) ) %>%       # por porcentajes
    ggplot(aes(x="", y=Prop, fill= Nacionalidad)) +
    geom_bar(stat="identity", width=1, color="white") +
    coord_polar("y", start=0) +
    theme_void()

Si agregamos porcentajes y etiquetas:

fifa21 %>%
    filter(Liga=="Spain Primera Division" & str_detect(Posicion_Jug, "Portero")) %>%
    group_by(Nacionalidad) %>%
    summarise( Frec= n()) %>%
    arrange(-Frec) %>% 
    mutate(Prop= Frec/sum(Frec)*100,
           PosLab=cumsum(Prop)-0.5*Prop) %>%       # por porcentajes
    ggplot(aes(x="", y=Prop, fill= reorder(Nacionalidad, Frec))) +
    geom_bar(stat="identity", width=1, color="white") +
    coord_polar("y", start=0) +
    theme_void() +
    theme(plot.title = element_text(hjust = 0.5)) +
    geom_text(aes(y = PosLab, label = paste(Prop, "%", sep = " ")), color = "white", size=4) +
    labs(title = "Proporción de las nacionalidades de los porteros", fill="Países")

Explorar variables numéricas

El objetivo de explorar dos variables numéricas es mostrar las interacciones o relaciones que existen entre ellas, por ejemplo ver cómo el ingreso promedio de una persona varía según la edad, o en nuestro caso explorar si la edad del jugador influye en el sueldo percibido?

Podemos usar un boxplot o gráfico de cajas para realizar la comparación por edades:

fifa21 %>% 
    ggplot(aes(x= Sueldo/1000, y = Edad)) +
    geom_boxplot( aes(group= cut_width(Sueldo, 50000)), outlier.alpha = 0.05, fill= "pink1") +
    labs(title= 'Booxplot Sueldo por Edad', 
         x="Sueldo (en miles de euros)",
         y= "Edad")+
    scale_y_continuous(breaks = seq(from= 0, to=50, by=10), limits = c(10, 50)) +
    scale_x_continuous(breaks = seq(from= 0, to=400, by=50), limits = c(0, 400))
## Warning: Removed 1 rows containing missing values (stat_boxplot).
## Warning: Removed 1 rows containing non-finite values (stat_boxplot).

Análisis de varias variables categóricas

fifa21 %>% 
    ggplot(aes(x= Pie_preferido)) +
    geom_bar( ) + facet_wrap(vars(Posicion_Jug)) +
    labs(title= 'Grafico de barras de Posicion del Jugador vs Pie Favorito', y= "Cantidad")

Análisis de más de 3 variables

Podemos realizar la comparación de varias variables en un gráfico de dispersión, por ejemplo en el siguiente gráfico se comparan 4 variables que son Rendimiento (eje \(x\)), Edad (eje \(y\)), Sueldo (tamaño de los puntos) y Club (color de los puntos).

Comunicando con gráficos

A veces hay muchas muestras, y cuando queremos agregar etiquetas al gráfico, es probable que ocurra el problema del ocultamiento de etiquetas.

El paquete auxiliar ggrepel de ggplot2 es un experto que se especializa en cubrir problemas. Con resultados visuales legibles por humanos, los análisis de muchos datos como en el campo de la biología son fácilmente identificables más convenientes y eficientes.

ggrepel https://github.com/slowkow/ggrepel Es un paquete de código abierto publicado en github.

Si deseamos reacrear el mismo gráfico anterior, debemos realizar un preselección de nuestros a utilizar, dado que el gráfico muestra información sobre los Clubes de FC Barcelona, Paris Saint-Germain, Manchester City, FC Bayern München y Real Madrid, y además selecciona los jugadores mejores pagados de cada uno de estos equipos.

library(ggrepel)
mejores_equipos <- fifa21 %>% 
    filter(Club=="FC Barcelona" | Club=="Paris Saint-Germain" |
           Club=="Manchester City" | Club=="FC Bayern München"|
           Club=="Real Madrid")
mejor_pagado <- mejores_equipos %>%
    group_by(Club) %>%
    filter(row_number(desc(Sueldo)) == 1)

Luego el data frame mejores_equipos será la data para mi gráfico:

windowsFonts("Arial" = windowsFont("Arial"))

mejores_equipos %>% 
    ggplot(aes(y = Edad, x = overall, size = Sueldo/1000)) +
    geom_point(aes(color = Club), alpha=0.7) +
    geom_point(data = mejor_pagado, alpha= 0.7, shape = 21, color = "white", stroke = 2) +
    scale_size(breaks = floor(seq(1, 500, length.out = 5)),
               limits = c(0, 570),
               range = c(2, 20),
               labels = function(x) {
                   paste0("€", x, "K")}) +
    scale_color_manual(values = c(
        "#e6b5c6",
        "#7842ed",
        "#203b9c",
        "#9b253d",
        "#e31e75",
        "#704e8f",
        "#af4beb",
        "#3ee5d6")) +
    scale_y_continuous(breaks = seq(16, 36, by = 4), limits = c(16, 36)) +
    scale_x_continuous(breaks = seq(55, 95, by = 5), limits = c(55, 95)) +
    ggrepel::geom_label_repel(data = mejor_pagado, aes(label = Nombre_Jugador), size=5, max.overlaps = Inf, segment.color = "white", segment.size = 0.7, box.padding = 3) +
    guides(color = guide_legend(override.aes = list(size = 8)),    #override.aes lista que especifica parámetros estéticos de las clave de las leyendas
           fill = guide_legend(override.aes = list(size = 8)),
           size = guide_legend(order = 5)) +
    theme(plot.title = element_text(family = "Arial",
                                    face = "bold",
                                    size = 20),
          plot.subtitle = element_text(size = 18),
          plot.background = element_rect(fill = "mediumpurple4"),
          text = element_text(family = "Arial",
                              colour = "white",
                              size = 13),
          axis.text = element_text(color = "white"),
          axis.ticks = element_line(color = "white"),
          panel.background = element_rect(fill = "mediumpurple4"),
          panel.grid.major = element_line(colour = "dimgrey"),
          panel.grid.minor = element_blank(),
          legend.box.background = element_blank(),
          legend.background = element_blank(),
          legend.key = element_rect(fill = "mediumpurple4",
                                    color = "mediumpurple4")) +  
    labs(title = "EDAD vs RENDIMIENTO DE LOS FUTBOLISTAS",
         subtitle = "La influencia de la edad en el rendimiento de los futbolistas en FIFA 21",
         caption = "Datos de kaggle.com",
         x = "R E N D I M I E N T O",
         y = "E D A D",
         size = "SALARIO",
         colour = "CLUBES DE FÚTBOL")

Para guardar los gráficos que genero:

ggsave("grafico1.JPEG", width = 18, height = 8)
ggsave("grafico1.PNG", width = 18, height = 8)

Gráficos animados

Utilizaremos los paquetes gganimate y plotly.

library(gganimate)
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout

Generamos un gráfico animado con plotly:

p <- fifa21 %>% ggplot(aes(x = overall)) +
    geom_density(fill= "#E69F00") +
    labs(title= 'Densidad para Rendimiento', y= "Cantidad", x= "Tiempo")
ggplotly(p)

También podemos utilizar un gráfico elaborado previamente:

t <- mejores_equipos %>% 
    ggplot(aes(y = Edad, x = overall, size = Sueldo/1000)) +
    geom_point(aes(color = Club), alpha=0.7) +
    geom_point(data = mejor_pagado, alpha= 0.7, shape = 21, color = "white", stroke = 2) +
    scale_size(breaks = floor(seq(1, 500, length.out = 5)),
               limits = c(0, 570),
               range = c(2, 20),
               labels = function(x) {
                   paste0("€", x, "K")}) +
    scale_color_manual(values = c(
        "#e6b5c6",
        "#7842ed",
        "#203b9c",
        "#9b253d",
        "#e31e75",
        "#704e8f",
        "#af4beb",
        "#3ee5d6")) +
    scale_y_continuous(breaks = seq(16, 36, by = 4), limits = c(16, 36)) +
    scale_x_continuous(breaks = seq(55, 95, by = 5), limits = c(55, 95)) +
    ggrepel::geom_label_repel(data = mejor_pagado, aes(label = Nombre_Jugador), size=5, max.overlaps = Inf, segment.color = "white", segment.size = 0.7, box.padding = 3) +
    guides(color = guide_legend(override.aes = list(size = 8)),    #override.aes lista que especifica parámetros estéticos de las clave de las leyendas
           fill = guide_legend(override.aes = list(size = 8)),
           size = guide_legend(order = 5)) +
    theme(plot.title = element_text(family = "Arial",
                                    face = "bold",
                                    size = 20),
          plot.subtitle = element_text(size = 18),
          plot.background = element_rect(fill = "mediumpurple4"),
          text = element_text(family = "Arial",
                              colour = "white",
                              size = 13),
          axis.text = element_text(color = "white"),
          axis.ticks = element_line(color = "white"),
          panel.background = element_rect(fill = "mediumpurple4"),
          panel.grid.major = element_line(colour = "dimgrey"),
          panel.grid.minor = element_blank(),
          legend.box.background = element_blank(),
          legend.background = element_blank(),
          legend.key = element_rect(fill = "mediumpurple4",
                                    color = "mediumpurple4")) +  
    labs(title = "EDAD vs RENDIMIENTO DE LOS FUTBOLISTAS",
         subtitle = "La influencia de la edad en el rendimiento de los futbolistas en FIFA 21",
         caption = "Datos de kaggle.com",
         x = "R E N D I M I E N T O",
         y = "E D A D",
         size = "SALARIO",
         colour = "CLUBES DE FÚTBOL")

ggplotly(t)
## Warning in geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]): geom_GeomLabelRepel() has yet to be implemented in plotly.
##   If you'd like to see this geom implemented,
##   Please open an issue with your example code at
##   https://github.com/ropensci/plotly/issues

plotly tiene su propia forma de generar gráficos desde cero:

fifa21 %>% filter(Club=="Real Madrid") %>%
    highlight_key(~Nombre_Jugador) %>%
    plot_ly(
        x = ~Sueldo, y = ~Edad, text = ~Nombre_Jugador, mode = "markers+text",
        textposition = "top", hoverinfo = "x+y"
    ) %>%
    highlight(on = "plotly_hover", off = "plotly_doubleclick")
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter

También podemos usar gganimate para gráficos animados:

animado <- fifa21 %>% 
    filter(Liga=="Spain Primera Division") %>% 
    group_by(Club) %>% 
    summarise(media_edad=mean(Edad)) %>% 
    ggplot(aes(x= Club, y= media_edad)) +
    geom_segment( aes(xend=Club, y=0, yend=media_edad), color="gray") +
    geom_text(aes(label=round(media_edad,2)), nudge_y = 2, color="gray2") +
    geom_point(size=5, color="pink") +
    coord_flip() +
    labs(title= 'Edad media de los jugadores: {current_frame}', 
         x= "Clubes de la Liga Española",
         y= "Edad") +
    transition_manual(media_edad)

animate(animado, renderer = gifski_renderer())
## nframes and fps adjusted to match transition