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.

Regressión de Python de Plotly en espacio ternario

Estoy tratando de dibujar una línea de regresión en plotly python en un espacio ternario, pero no parece haber una opción como “trendline = ‘loess'” para scatter ternaries. ¿Hay otra manera de lograr el mismo resultado para ternaries? Código de una publicación anterior que crea una línea de splines pero no una regresión.

import numpy as np
import plotly.graph_objects as go

a = np.array([0.15, 0.15, 0.17, 0.2 , 0.21, 0.24, 0.26, 0.27, 0.27, 0.29, 0.32, 0.35, 0.39, 0.4 , 0.4 , 0.41, 0.47, 0.48, 0.51, 0.52, 0.54, 0.56, 0.59, 0.62, 0.63, 0.65, 0.69, 0.73, 0.74])
b = np.array([0.14, 0.15, 0.1 , 0.17, 0.17, 0.18, 0.05, 0.16, 0.17, 0.04, 0.03, 0.14, 0.13, 0.13, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.15, 0.16, 0.18, 0.2 , 0.21, 0.22, 0.24, 0.25, 0.25])
c = np.array([0.71, 0.7 , 0.73, 0.63, 0.62, 0.58, 0.69, 0.57, 0.56, 0.67, 0.65, 0.51, 0.48, 0.47, 0.46, 0.45, 0.4 , 0.39, 0.35, 0.34, 0.31, 0.28, 0.23, 0.18, 0.16, 0.13, 0.07, 0.02, 0.01])

fig = go.Figure()

curve_portion = np.where((b < 0.15) & (c > 0.6))
curve_other_portion = np.where(~((b < 0.15) & (c > 0.6)))

def add_plot_spline_portions(fig, indices_groupings):
    for indices in indices_groupings:
        fig.add_trace(go.Scatterternary({
            'mode': 'lines',
            'connectgaps': True,
            'a': a[indices],
            'b': b[indices],
            'c': c[indices],
            'line': {'color': 'black', 'shape': 'spline', 'smoothing': 1},
            'marker': {'size': 2, 'line': {'width': 0.1}}
            })
            )

add_plot_spline_portions(fig, [curve_portion, curve_other_portion])
fig.show(renderer='png')

jagged spline rather than regression

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no hay una opción incorporada en Plotly para dibujar líneas de tendencia de regresión en gráficos ternarios. Sin embargo, aún puedes obtener un resultado similar calculando manualmente la línea de regresión y agregándola como una nueva traza encima del gráfico de dispersión. Aquí tienes un ejemplo de código:

    import numpy as np
    import plotly.graph_objects as go
    
    # Datos
    a = np.array([0.15, 0.15, 0.17, 0.2 , 0.21, 0.24, 0.26, 0.27, 0.27, 0.29, 0.32, 0.35, 0.39, 0.4 , 0.4 , 0.41, 0.47, 0.48, 0.51, 0.52, 0.54, 0.56, 0.59, 0.62, 0.63, 0.65, 0.69, 0.73, 0.74])
    b = np.array([0.14, 0.15, 0.1 , 0.17, 0.17, 0.18, 0.05, 0.16, 0.17, 0.04, 0.03, 0.14, 0.13, 0.13, 0.14, 0.14, 0.13, 0.13, 0.14, 0.14, 0.15, 0.16, 0.18, 0.2 , 0.21, 0.22, 0.24, 0.25, 0.25])
    c = np.array([0.71, 0.7 , 0.73, 0.63, 0.62, 0.58, 0.69, 0.57, 0.56, 0.67, 0.65, 0.51, 0.48, 0.47, 0.46, 0.45, 0.4 , 0.39, 0.35, 0.34, 0.31, 0.28, 0.23, 0.18, 0.16, 0.13, 0.07, 0.02, 0.01])
    
    # Gráfico de dispersión
    fig = go.Figure()
    fig.add_trace(go.Scatterternary({
        'mode': 'markers',
        'a': a,
        'b': b,
        'c': c,
        'marker': {'size': 5},
    }))
    
    # Línea de regresión
    x = np.vstack([a, b, c]).T
    coef = np.linalg.lstsq(np.hstack([x, np.ones((len(x), 1))]), a, rcond=None)[0]
    line_a = np.linspace(np.min(a), np.max(a), 10)
    line_b = np.linspace(np.min(b), np.max(b), 10)
    line_c = np.linspace(np.min(c), np.max(c), 10)
    line_x, line_y, line_z = np.meshgrid(line_a, line_b, line_c)
    line_xyz = np.vstack([line_x.flatten(), line_y.flatten(), line_z.flatten()]).T
    line_a_pred = np.dot(line_xyz, coef[:-1]) + coef[-1]
    line_a_pred_grid = line_a_pred.reshape(line_x.shape)
    fig.add_trace(go.Surface({
        'x': line_x,
        'y': line_y,
        'z': line_z,
        'surfacecolor': line_a_pred_grid,
        'cmin': np.min(line_a_pred),
        'cmax': np.max(line_a_pred),
        'colorscale': 'Viridis',
        'opacity': 0.8,
    }))
    
    fig.show()
    

    El código primero crea un gráfico de dispersión ternario utilizando los mismos datos que antes. Luego, calcula los coeficientes de un modelo de regresión lineal (en este caso, y=a) usando np.linalg.lstsq. Luego, los coeficientes se utilizan para predecir los valores y para una rejilla regular de coordenadas x, y y z que abarcan todo el rango de datos de entrada. Los valores y predichos se almacenan en un arreglo tridimensional y se representan como una superficie utilizando el objeto go.Surface de Plotly. El gráfico resultante debería mostrar una superficie que se aproxime a la ubicación de la línea de tendencia de regresión, aunque puede que no sea tan suave o precisa como un modelo de regresión completo.

Comments are closed.