Я разместил этот вопрос как проблему в репозитории plotly .
Вот ответ, который я получил.
@ empet - спасибо <3 </p>
Когда ваши fig.data содержат только одну трассировку, предполагается, что каждый кадр обновляет эту трассировку, и эта трасса больше не отображается во время анимации. Вот почему вы должны определить:
fig = go.Figure(
data=[
go.Scatter(
y=y,
x=x,
mode="lines",
ine_shape='spline'
)
]*2
)
, т.е. дважды включить одну и ту же трассировку в fig.data. В то же время измените определение кадра следующим образом:
frame = go.Frame(data=[scatter], traces=[1])
traces = [1]
информирует в заговоре. js, что каждый кадр обновляет трассу fig.data[1]
, тогда как fig.data[0]
не изменяется в течение animation.
Вот полный пример того, как сделать анимацию на основе сюжета.
import math
import numpy as np
import plotly.graph_objects as go
import plotly.io as pio
import plotly.offline as pyo
class Plot:
def __init__(
self,
image_width: int = 1200,
image_height: int = 900
) -> None:
self.IMAGE_WIDTH = image_width
self.IMAGE_HEIGHT = image_height
pyo.init_notebook_mode(connected=False)
pio.renderers.default = 'notebook'
def population(self, filename: str = 'population'):
x_spline = np.linspace(
start=0,
stop=20,
num=100,
endpoint=True
)
y_spline = np.array([math.sin(x_i) for x_i in x_spline])
x_min = np.min(x_spline)
x_max = np.max(x_spline)
y_min = np.min(y_spline)
y_max = np.max(y_spline)
spline = go.Scatter(
y=y_spline,
x=x_spline,
mode="lines",
line_shape='spline'
)
fig = go.Figure(
data=[spline] * 2
)
frames = []
for i in range(50):
x = np.random.random_sample(size=5)
x *= x_max
y = np.array([math.sin(x_i) for x_i in x])
scatter = go.Scatter(
x=x,
y=y,
mode='markers',
marker=dict(
color='Green',
size=12,
line=dict(
color='Red',
width=2
)
),
)
frame = go.Frame(data=[scatter], traces=[1])
frames.append(frame)
fig.frames = frames
fig.layout = go.Layout(
xaxis=dict(
range=[x_min, x_max],
autorange=False
),
yaxis=dict(
range=[y_min, y_max],
autorange=False
),
title="Start Title",
updatemenus=[
dict(
type="buttons",
buttons=[
dict(
label="Play",
method="animate",
args=[None]
)
]
)
]
)
fig.update_layout(
xaxis_title='x',
yaxis_title='y',
title='Fitness landscape',
# autosize=True
)
pyo.iplot(
fig,
filename=filename,
image_width=self.IMAGE_WIDTH,
image_height=self.IMAGE_HEIGHT
)
plot = Plot()
plot.population()