Визуализация функции в plotly с помощью слайдеров

Рейтинг: 1Ответов: 1Опубликовано: 30.01.2023

Пытаюсь сделать визуализацию влияния коэффициентов линейной функции на её график в задаче линейной регрессии на подобие того как это делается в desmos введите сюда описание изображения

Для этого использую следующий код в plotly составленный из кусков чужого кода

import pandas as pd                      
import numpy as np
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=False)
# Create figure
fig = go.Figure(go.Scatter(x=data.Population, y=data.Profit, mode='markers', name='Population&Profit'))

# Add traces, one for each slider step
for step in np.arange(0, 2, 0.1):
    x=np.linspace(3, 23, 100)
    fig.add_trace(
        go.Scatter(
            x=x,
            y=step*np.linspace(-4,23,100)+step))


# Create and add slider
steps = []
for i in range(len(fig.data)):
    step = dict(
        method="update",
        args=[{"visible": [False] * len(fig.data)},
              {"title": "Slider switched to step: " + str(i)}],  # layout attribute
    )
    step["args"][0]["visible"][i] = True  # Toggle i'th trace to "visible"
    steps.append(step)

sliders = [dict(
    active=10,
    currentvalue={"prefix": "Frequency: "},
    pad={"t": 50},
    steps=steps
)]

fig.update_layout(
    sliders=sliders
)

fig.show()

результат в итоге вот такойвведите сюда описание изображения

при передвижении слайдера отрисовывается только новая линия, пробовал добавить отрисовку точек внутрь функции с add_trace, но это не помогло. Также данная функция по ощущениям не работает как в desmos + хотелось бы всё же реализовать так-же слайдеры и для k и для b.

Если поменять код следующим образом добавив трейс для точек:

for step in np.arange(0, 2, 0.1):
    x=np.linspace(3, 23, 100)
    y=step*np.linspace(-4,23,100)+step
    fig.add_trace(
        go.Scatter(x=data.Population, 
            y=data.Profit, 
            mode='markers', 
            name='Population&Profit')
    )
    fig.add_trace(
        go.Scatter(
            x=x,
            y=y)
    )

то результат будет выглядить вот так: введите сюда описание изображения

А при изменении позиции слайдера соответственно отрисовываются сначала точки, а потом линия, и последняя перекрывает точки. Если поменять порядок определения, то наоборот точки перекроют линии, то есть нет эффекта наложения.

Пробовал и определять fig внутри функции но тогда вообще всё ломается.

Ответы

▲ 3Принят

я отредактировал код, пометив изменения комментариями со стрелкой:

import pandas as pd                      
import numpy as np
import plotly.offline as py
import plotly.graph_objs as go
py.init_notebook_mode(connected=False)
data = pd.read_csv('ex1data1.csv', sep=",", header=None)
data.columns = ["Population", "Profit"]  # устанавливаем заголовки
#print(data.head())
#print(data.info())
# Create figure
fig = go.Figure(go.Scatter(x=data.Population, y=data.Profit, mode='markers', name='Population&Profit'))

# Add traces, one for each slider step
for step in np.arange(0, 2, 0.1):
#    x=np.linspace(3, 23, 100)
    x=np.linspace(data.Population.min(), data.Population.max(), 100)    #<--- (1)
    fig.add_trace(
        go.Scatter(
            x=x,
#            y=step*np.linspace(-4,23,100)+step,
            y  = step*np.linspace(data.Profit.min(),data.Profit.max(),100)+step,  #<--- (2)
#            visible='legendonly'
            visible=True if step==1 else False
        )
    )

    
# Create and add slider
steps = []
for i in range(1, len(fig.data)): #<--- (3)
    step = dict(
        method="update",
        args=[{"visible": [False] * len(fig.data)},
              {"title": "Slider switched to step: " + str(i)}],  # layout attribute
    )
    step["args"][0]["visible"][0] = True  # <--- (4)
    step["args"][0]["visible"][i] = True  # Toggle i'th trace to "visible"
    steps.append(step)

    
sliders = [dict(
    active=10,
    currentvalue={"prefix": "Frequency: "},
    pad={"t": 50},
    steps=steps
)]

fig.update_layout(
    sliders=sliders,
    autosize=False,   #<--- 5
)

fig.show()
  • 1 и 2 - чтобы график не "скакал", желательно давать точные значения
  • 3 - range нужно брать не с 0 в данном случае, иначе при слайдере на нуле первая прямая не будет отрисовываться.
  • 4 - при каждой отрисовке фигуры нужно всегда отрисовывать точки исходных данных
  • 5 - отключил автосайз, опять же, чтобы график меньше прыгал

вот начальная картинка при запуске кода (теперь не выводятся все трейсы сразу, а только выбранный):

введите сюда описание изображения

вот, для примера, картинка при слайдере на "2"

введите сюда описание изображения