Aprendiendo Plotly - Gráfico de líneas


Los gráficos de líneas son herramientas visuales poderosas para representar tendencias y cambios a lo largo del tiempo. Se utilizan comúnmente en:

  • Análisis de Datos Temporales: Los gráficos de líneas son ideales para mostrar cambios a lo largo del tiempo, como ventas mensuales, fluctuaciones climáticas o el crecimiento de usuarios en una aplicación.
  • Seguimiento de Rendimiento: Ayudan a visualizar el rendimiento de acciones, inversiones o indicadores clave en los negocios, permitiendo identificar patrones y tendencias.
  • Comparación de Múltiples Variables: Pueden representar varias líneas en un solo gráfico, lo que facilita la comparación de diferentes series de datos, como ingresos de diferentes productos en un mismo período.
  • Proyecciones y Previsiones: Los gráficos de líneas pueden usarse para proyectar tendencias futuras basadas en datos históricos, ayudando en la toma de decisiones y planificación.
  • Evolución de Métricas: Son útiles para visualizar cómo han cambiado métricas clave a lo largo del tiempo, como el crecimiento de seguidores en redes sociales o la evolución de tasas de éxito en proyectos.
  • Cambios en Comportamientos: Se usan para entender cambios en comportamientos de usuarios, por ejemplo, seguimiento de clics en un sitio web o la evolución de hábitos de compra.
  • Investigación Científica: Son esenciales para mostrar relaciones entre variables en estudios científicos, como la relación entre temperatura y rendimiento de cultivos.
  • Educación: Son herramientas didácticas valiosas para explicar conceptos como la velocidad de cambio en matemáticas o para ilustrar procesos históricos y evolución de fenómenos.

En resumen, los gráficos de líneas son versátiles y se emplean en diversos campos para mostrar cómo los datos cambian a lo largo del tiempo, permitiendo identificar patrones y tomar decisiones informadas. 

Gráficos de líneas con Plotly

Plotly es una biblioteca de visualización interactiva que permite crear gráficos y visualizaciones atractivas en Python, R y otros lenguajes. Ofrece capacidades interactivas como zoom, selección y animación, lo que facilita la exploración y comunicación de datos de manera efectiva. En este caso voy a compartir el código para que puedas crear gráficos de líneas con las opciones más comunes y útiles para tener unos dashboards más funcionales. Los códigos los podrás probar en Jupyter Notebook o Google Colab.

Primero debes tener instalado Plotly

pip install plotly

Primero para el ejemplo importaremos las librerías y cargaremos un set de datos:


import plotly.express as px
import pandas as pd

# Fuente de datos
dfDatos = pd.read_csv('https://raw.githubusercontent.com/gcastano/datasets/main/gapminder_data.csv')

#Agrupamos los datos totales
dfDatosChartTotales=dfDatos.groupby(['year'],as_index=False).agg({'lifeExpectancy':'mean','population':'sum', 'mean_house_income':'mean','median_age_year':'mean'})

#Convetimos el dato Año a formato fecha
dfDatosChartTotales['year'] =pd.to_datetime(dfDatosChartTotales['year'].astype(str) +'-12-31')

#Agrupamos los datos por continente
dfDatosChartContinente=dfDatos.groupby(['year','continent'],as_index=False).agg({'lifeExpectancy':'mean','population':'sum', 'mean_house_income':'mean','median_age_year':'mean'})
El siguiente video podrás ver en funcionamiento el código que comparto en este post:



Puedes copiar este libro de Google Colab para que puedas experimentar por tu cuenta y también visitar la documentación oficial de Plotly si deseas ver muchos otros parámetros que puedes usar.


Gráfico de líneas simple con Plotly - Una sola línea

En el siguiente código podrás ver un gráfico con algunos de los parámetros más comunes, cada línea tiene su comentario para que entiendas para qué es cada parámetro


# Crear gráfico línea
fig = px.line(data_frame= dfDatosChartTotales, #Dataframe con los datos
              x='year', #Campo para el eje X
              y='lifeExpectancy', #Campo para el eje Y (Numérico)
              title='Life Expectancy at birth vs Year', #Título general del gráfico
              width=1000, #Ancho del gráfico, no de cada gráfico mostrado
              height=600, #Alto total del gráfico, no de cada gráfico mostrado
              text ='lifeExpectancy',  # Texto que se desea ver sobre cada punto de datos
              hover_data=['population'], #Datos adicionales a mostrar cuando se pasa el mouse sobre el punto de datos
              labels={'year':'Año','lifeExpectancy':'Expectativa de vida','population':'Población'}, # Personalización de los nombres de las series
              markers=True, #Mostramos marcadores
              custom_data=['mean_house_income','population'] #Datos adicionales que se desean usar en otros componentes
              )

# Mostrar gráfico
fig.show()

Por defecto el título del gráfico, parámetro title aparece a la izquierda, con el siguiente código se puede centrar:


# Centramos el título
fig.update_layout(title_x=0.5)

Cuando activas el parámetro text, los datos aparecerán sobre cada punto de datos, con este código puedes mover el texto un poco hacie arriba y darle un formato el número:


# Opciones para mostrar el texto
fig.update_traces(textposition='top center') #Posición en la que se desea el texto puesto en el parámetro text
fig.update_traces(texttemplate= '%{text:.3f}') #Formato en el que se desea desplegar el texto puesto en el parámetro text
Es importante que uses el parámetro text con cuidado ya que cuando se tienen demasiados puntos de datos el gráfico no es muy legible

En caso de que desees cambiar el color del fondo del gráfico o del área entre los ejes puedes usar este código:


# Opciones de colores para el fondo del gráfico
fig.update_layout(paper_bgcolor='#7895CB') #Color base de todo el gráfico
fig.update_layout(plot_bgcolor='#C5DFF8') #Color dentro del gráfico

Si en lugar de líneas contínuas requieres una con guiones o puntos, puedes usar este código y personalizarlo:


# Opciones para las líneas
fig.update_traces(patch={"line": {"width": 4, "dash": 'dot'}}) #Mostrar líneas con puntos
fig.update_traces(patch={"line": {"width": 4, "dash": 'dash'}}) #Mostrar líneas con guiones

Con este código puedes adicionar una línea horizontal a tu gráfico, esto puede ser útil para dejar visibles límites de datos:


#Línea horizontal
fig.add_hline(y=60, #Punto del eje Y donde se desea la línea
              line_width=3, #Ancho de la línea
              line_dash="dash", #Punteada, sólida o con guiones
              line_color="green", #Color de la línea
              annotation_text="60 años", #Texto asociado a la línea
              annotation_position="top left" #Positión del texto asociado a la línea
              )

Si requieres una línea vertical puedes personalizar este código, las líneas son importantes cuando se quiere dejar visible algún evento importante en una línea de tiempo:


#Línea Vertical
fig.add_vline(x=2000, #Punto del eje X donde se desea la línea
              line_width=3, #Ancho de la línea
              line_dash="dash", #Punteada, sólida o con guiones
              line_color="green", #Color de la línea
              annotation_text="Año 2000", #Texto asociado a la línea
              annotation_position="top left" #Positión del texto asociado a la línea
              )

Si en lugar de un puntos espécífico deseas dejar visibles rangos, puedes usar rectángulos:


#Rectángulo vertical
fig.add_vrect(x0='2020-01-01', x1='2021-12-31',line_width=3, line_dash="solid", line_color="red",fillcolor='blue',opacity=0.2,annotation_text="Pandemia Covid 19", annotation_position="top left")


#Rectángulo horizontal
fig.add_hrect(y0=80, y1=100, line_width=0, fillcolor="green", opacity=0.2,annotation_text="80 a 90 años", annotation_position="top left")

Con este código puedes marcar punos específicos de la serie y poner una anotación:


# Adición de una anotación para un punto determinado
fig.add_annotation(x=2012, y=71.3,
            text="Fin del mundo según los Mayas",
            showarrow=True,
            arrowhead=1)

Este código muestra un ejemplo de cómo personalizar el popup que aparece cuando se pasa el mouse sobre un set de datos, es importante que tengas presente que los datos customdata toman los campos que se debieron de dar en el parámetro custom_data del primer código:


# Plantilla de información del popup
hovertemp = "Year:  %{x} 
" hovertemp += "Life Expectancy: %{y:.1f}
" hovertemp += "gdpPercap: $%{customdata[0]:,.1f}
" hovertemp += "Población: %{customdata[1]:,.0f}
" fig.update_traces(hovertemplate=hovertemp)

Este código permite que el popup de datos se muestre cuando se pasa el mouse sobre el gráfico no solo en el punto específico de la serie, puedes expermientar con el que más te sirva:


fig.update_layout(hovermode="x")
fig.update_layout(hovermode="x unified")

Este código permite quitar la leyenda del gráfico:


fig.update_layout(showlegend=True) #Determina si se muestra o no la leyenda

Si estás mostrando series de tiempo grande, este código muestra un selector de rango en la parte inferior del gráfico para que se pueda elegir un rango:


#Controles selector de rango simple
# fig.update_xaxes(rangeslider_visible=True)

Esta variación del slider anterior es mucho más completa ya que presenta botones con rangos de tiempo preseleccionados:


#Controles selectores de rango cuando el eje es con fecha
fig.update_xaxes(
            rangeslider_visible=True,
            rangeselector=dict(
                buttons=list(
                    [
                        dict(step="day", stepmode="backward", label="1 semana", count=7),
                        dict(step="month", stepmode="backward", label="1 mes", count=1),
                        dict(step="month", stepmode="backward", label="3 meses", count=3),
                        dict(step="month", stepmode="backward", label="6 meses", count=6),
                        dict(label="Todos", step="all"),
                    ]
                )
            ),
        )


Gráfico de líneas con eje secundario en Plotly

Algunas veces puedes necesitar graficar un comparativo de 2 series de datos que manejan una escala diferente, por ejemplo una línea muestra productos fabricados y otra los productos rechazados; en la primera puede tener un valor en miles y en la otra en decenas o cientos. Si se ponen juntas en un mismo eje Y, probablemente veas los valores pequeños muy abajo, perdiendo la oportunidad de la comparación. Este código es un ejemplo de cómo en Plotly puedes poner 2 series de datos con sus 2 ejes Y correspondientes. En el ejemplo compararemos la proyección de población que es en una escala de millones con la expectativa de vida que es de máximo 100 años.


# 2 Eje secundario

import plotly.express as px
import pandas as pd
from plotly.subplots import make_subplots

# Fuente de datos
dfDatos = pd.read_csv('https://raw.githubusercontent.com/gcastano/datasets/main/gapminder_data.csv')

#Agrupamos los datos totales
dfDatosChartTotales=dfDatos.groupby(['year'],as_index=False).agg({'lifeExpectancy':'mean','population':'sum', 'mean_house_income':'mean','median_age_year':'mean'})

#Se crea un subplot y se define que va a tener un eje secundario
subfig = make_subplots(specs=[[{"secondary_y": True}]])

#Se crea el primer gráfico que usará el eje Y de la izquierda
fig1 = px.line(data_frame= dfDatosChartTotales, #Dataframe con los datos
              x='year', #Campo para el eje X
              y='lifeExpectancy', #Campo para el eje Y (Numérico)
              )

#Se crea el segundo gráfico que usará el eje de la derecha
fig2 = px.line(data_frame= dfDatosChartTotales, #Dataframe con los datos
              x='year', #Campo para el eje X
              y='population', #Campo para el eje Y (Numérico)
              )

# Especificamos que el segundo gráfico usará el eje de la derecha
fig2.update_traces(yaxis="y2")

# Adicionamos los 2 gráficos al subplot
subfig.add_traces(fig1.data + fig2.data)

# Definimos los títulos de los ejes
subfig.layout.xaxis.title="Año"
# Título del eje Y de la izquierda
subfig.layout.yaxis.title="Expectativa de vida (Años)"
# Título del eje Y de la derecha
subfig.layout.yaxis2.title="Población"

# Cambiamos los colores de las líneas, sin esto todas las líneas tendrán el mismo color
subfig.for_each_trace(lambda t: t.update(line=dict(color=t.marker.color)))

subfig.show()

Gráfico de líneas de múltiples series con Plotly - Varias líneas

A veces requieres comparar varias series de datos y para esto Plotly te ofrece diferentes opciones. Desde diferenciar series por colores hasta manejar tablas de gráficos o subplots para cada campo que requieras.
Los parámetros facet_ permiten generar gráficos por cada fila o columna dependiendo de diferentes campos. Puedes combinar por ejemplo crear matrices de gráficos cuyas columnas estén relacionadas a un campo categórico y las columas a otro

import plotly.express as px
import pandas as pd

# Fuente de datos
dfDatos = pd.read_csv('https://raw.githubusercontent.com/gcastano/datasets/main/gapminder_data.csv')

#Agrupamos los datos por continente
dfDatosChartContinente=dfDatos.groupby(['year','continent'],as_index=False).agg({'lifeExpectancy':'mean','population':'sum', 'mean_house_income':'mean','median_age_year':'mean'})

# Crear gráfico line
fig = px.line(data_frame= dfDatosChartContinente, #Dataframe con los datos
              x='year', #Campo para el eje X
              y='lifeExpectancy', #Campo para el eje Y (Numérico)
              title='Life Expectancy at birth vs Year', #Título general del gráfico
              color='continent', # Campo con el que se desea que cambie el color de cada serie
              height=1000, #Alto total del gráfico, no de cada gráfico mostrado
              facet_col='continent', #Campo para dividir gráficos por columnas
              facet_col_wrap=2, # Cuando se pone facet_col facet_col_wrap define cuántos gráficos por fila se tendran
              facet_col_spacing= 0.01, # Espacio entre las columnas definidas como fracciones del ancho del gráfico para que se ajusten dinámicamente
              facet_row='continent', #Campo para dividir gráficos por filas
              facet_row_spacing=0.04, # Espaciado entre las fillas de gráficos cuando se define facet_row

              )

fig.update_layout(hovermode="x unified")

# Mostrar gráfico
fig.show()

Publicar un comentario

0 Comentarios