Визуализация функции в plotly с помощью слайдеров
Пытаюсь сделать визуализацию влияния коэффициентов линейной функции на её график в задаче линейной регрессии на подобие того как это делается в 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 внутри функции но тогда вообще всё ломается.
Ответы (1 шт):
я отредактировал код, пометив изменения комментариями со стрелкой:
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"


