es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo hacer un simple diagrama de Sankey de múltiples niveles con Plotly?

Tengo un DataFrame como este que estoy tratando de describir con un diagrama Sankey:

import pandas as pd

pd.DataFrame({
    'animal': ['perro', 'gato', 'gato', 'perro', 'gato'],
    'sexo': ['macho', 'hembra', 'hembra', 'macho', 'macho'],
    'estado': ['salvaje', 'domesticado', 'domesticado', 'salvaje', 'domesticado'],
    'cantidad': [8, 10, 11, 14, 6]
})

animal sexo estado cantidad
0 perro macho salvaje 8
1 gato hembra domesticado 10
2 gato hembra domesticado 11
3 perro macho salvaje 14
4 gato macho domesticado 6

Estoy tratando de seguir los pasos en la documentación pero no puedo hacer que funcione: no entiendo a qué rama pertenece cada uno. Aquí está el código de ejemplo:

import plotly.graph_objects as go

fig = go.Figure(data=[go.Sankey(
    node = dict(
      pad = 15,
      thickness = 20,
      line = dict(color = "black", width = 0.5),
      label = ["A1", "A2", "B1", "B2", "C1", "C2"],
      color = "blue"
    ),
    link = dict(
      source = [0, 1, 0, 2, 3, 3], 
      target = [2, 3, 3, 4, 4, 5],
      value = [8, 4, 2, 8, 4, 2]
  ))])

fig.update_layout(title_text="Diagrama Sankey Básico", font_size=10)
fig.show()

Esto es lo que estoy tratando de lograr:
Diagrama Sankey

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Primero, necesitamos convertir el DataFrame dado en un formato que se pueda utilizar para trazar un diagrama de Sankey utilizando Plotly. Necesitamos enumerar todos los posibles caminos desde un nodo hasta otro y asignar un valor a cada uno de estos caminos.

    Aquí está el código para convertir el DataFrame dado en un formato que se puede trazar como un diagrama de Sankey:

    import pandas as pd
    
    df = pd.DataFrame({
        'animal': ['dog', 'cat', 'cat', 'dog', 'cat'],
        'sex': ['male', 'female', 'female', 'male', 'male'],
        'status': ['wild', 'domesticated', 'domesticated', 'wild', 'domesticated'],
        'count': [8, 10, 11, 14, 6]
    })
    
    # Crea un diccionario para almacenar los nodos únicos
    nodes = {}
    
    # Crea una lista para almacenar todos los enlaces (nodos de origen y destino) y sus valores correspondientes
    links = []
    
    # Recorre cada fila del DataFrame y agrega nodos y enlaces según sea necesario
    for _, row in df.iterrows():
        source = row['animal']
        target = row['sex']
        target2 = row['status']
        value = row['count']
    
        # Agrega el nodo de origen al diccionario si no existe
        if source not in nodes:
            nodes[source] = len(nodes)
    
        # Agrega el primer nodo de destino al diccionario si no existe
        if target not in nodes:
            nodes[target] = len(nodes)
    
        # Agrega el segundo nodo de destino al diccionario si no existe
        if target2 not in nodes:
            nodes[target2] = len(nodes)
    
        # Agrega el enlace (nodo de origen y primer nodo de destino) y su valor a la lista de enlaces
        links.append({
            'source': nodes[source],
            'target': nodes[target],
            'value': value
        })
    
        # Agrega el enlace (primer nodo de destino y segundo nodo de destino) y su valor a la lista de enlaces
        links.append({
            'source': nodes[target],
            'target': nodes[target2],
            'value': value
        })
    

    Ahora que tenemos los nodos y enlaces requeridos para trazar el diagrama de Sankey, podemos usar la función go.Sankey() de Plotly para crear el diagrama.

    Aquí está el código para generar el diagrama de Sankey requerido:

    import plotly.graph_objects as go
    
    # Crea una lista de colores para usar en los nodos
    color_list = ['blue', 'red', 'green', 'yellow']
    
    # Crea una lista de etiquetas para los nodos
    node_labels = list(nodes.keys())
    
    # Crea una lista de colores para cada nodo basada en la lista de colores
    node_colors = [color_list[nodes[node] % len(color_list)] for node in node_labels]
    
    # Crea el diagrama de Sankey
    fig = go.Figure(data=[go.Sankey(
        node = dict(
          pad = 20,
          thickness = 20,
          line = dict(color = 'black', width = 0.5),
          label = node_labels,
          color = node_colors
        ),
        link = dict(
          source = [link['source'] for link in links],
          target = [link['target'] for link in links],
          value = [link['value'] for link in links]
      ))])
    
    # Actualiza el diseño del diagrama de Sankey
    fig.update_layout(title_text='Estado del animal', font_size=10)
    
    # Muestra el diagrama de Sankey
    fig.show()
    

    Esto debería generar el diagrama de Sankey requerido como se muestra en la imagen proporcionada.

Comments are closed.