Plot.ly. Using slider control with multiple plots

寵の児 提交于 2019-12-08 08:22:57

问题


I'd like to add the slider control to my plotly graph (pic) to control all elements simultaneously.

I can easily add slider control to graph with only one line. In this case I put a list of plots (in form of dicts) into data variable:

plotly.graph_objs.Figure (data = [plot1,plot2], layout = layout)

And it's work quite good.


But in order to plot multiple lines on the same graph, I have to put list of lists with plots into data variable ( have I ? ):

plotly.graph_objs.Figure (data = [[plot1.1, plot2.1], [plot1.2, plot2.2]], layout = layout)

But plot.ly still expects the list of dicts.

Entry should subclass dict.


Are there any way to control multiple elements simultaneously using one slider control?

import plotly
import plotly.plotly as py
import numpy as np

plotly.offline.init_notebook_mode()

exp = 2.71

N = 3

x_start = -N
x_end = N
dx = 0.1

y_start = -N
y_end = N
dy = 0.1


x_axis = np.arange(x_start, x_end, dx)
y_axis = np.arange(y_start, y_end, dy)


def pit(offset, x):
    pit1 = []
    for position in x:
        pit1.append(1 - exp**(-36 * (position - offset)**2))
    return pit1


def v_x(x):
    vx = exp**(-x**2)
    return vx


def v_y(x):
    vy = 0.5 * exp**(-x**2)
    return vy


def density(vx, vy):
    den = []
    for v1 in vx:
        row = []
        for v2 in vy:
            row.append(v1 * v2)
        den.append(row)
    return den


vx = v_x(x_axis)
vy = v_y(y_axis)

den = density(vx, vy)


def contour(step=None):
    return dict(
        type='contour',
        z=den,
        colorscale=[[0, 'rgb(255,255,255)'], [1, 'rgb(49,163,84)']],
        x=x_axis,
        y=y_axis,
    )


def vy_projection(step):
    return dict(
        visible=True,
        type='scatter',
        name=str(step),
        marker=dict(color='rgb(255,0,0)'),
        yaxis='y2',
        x=x_axis,
        y=vx * pit(step, x_axis)
    )


def vx_projection(step):
    return dict(
        visible=True,
        type='scatter',
        name=str(step),
        marker=dict(color='rgb(255,0,255)'),
        xaxis='x2',
        x=vy,
        y=y_axis
    )


trace1 = [
    [vy_projection(step), vx_projection(step)]
    for step in np.arange(-3, 3, 0.5)]

for plot in trace1[-1]:
    plot['visible'] = True

steps = []
for i in range(len(trace1)):
    step = dict(
        method='restyle',
        args=['visible', [False] * len(trace1)],
    )
    step['args'][1][i] = True
    steps.append(step)

sliders = [dict(
    active=10,
    currentvalue={"prefix": "Step: "},
    pad={"t": len(trace1)},
    steps=steps
)]

layout = dict(
    autosize=False,
    width=500,
    height=500,
    sliders=sliders,
    xaxis=dict(
        range=[-3, 3],
    ),
    xaxis2=dict(
        domain=[0.9, 1],
        showgrid=False,
        zeroline=False,
    ),
    yaxis=dict(
        range=[-3, 3],
    ),
    yaxis2=dict(
        domain=[0.9, 1],
        showgrid=False,
        zeroline=False,
    )

)
data = trace1[0]
fig = go.Figure(data=data, layout=layout)

# plotly.offline.plot(fig, filename='manipulate.html')
plotly.offline.iplot(fig)

回答1:


Here is minimal working example of using a slider control to manipulate multiple traces.

import plotly

plotly.offline.init_notebook_mode()

trace1 = dict(
    type='scatter',
    x=[0, 1],
    y=[0, 0.5]
)
trace2 = dict(
    type='scatter',
    x=[0, 1],
    y=[0, -0.5]
)

trace3 = dict(
    type='scatter',
    x=[0, 1],
    y=[0, 1]
)
trace4 = dict(
    type='scatter',
    x=[0, 1],
    y=[0, -1]
)

steps = [None, None]
steps[0] = dict(
    method='restyle',
    args=[
        'visible', [False, True]
    ],
)
steps[1] = dict(
    method='restyle',
    args=[
        'visible', [True, False]
    ],
)

sliders = dict(
    steps=steps
)

layout = dict(
    sliders=[sliders],
    xaxis=dict(
        range=[0, 1],
    ),
    yaxis=dict(
        range=[-1, 1],
    ),
)

data = plotly.graph_objs.Data([trace1, trace2, trace3, trace4])
fig = plotly.graph_objs.Figure(data=data, layout=layout)

# plotly.offline.plot(fig, filename='manipulate.html')
plotly.offline.iplot(fig)



回答2:


This isn't working if you add the traces with addTraces method: https://codepen.io/anon/pen/ydMLyK

const defTraces = [{
  x: [1, 2, 3],
  y: [2, 1, 3],
  visible: true,
  line: {color: 'red'}
}, {
  x: [1, 2, 3],
  y: [3, 2, 4],
  visible: true,
  line: {color: 'green'}
}, {
  x: [1, 2, 3],
  y: [4, 3, 5],
  visible: true,
  line: {color: 'blue'}
},
{
  x: [1, 2, 3],
  y: [2, 1, 3],
  visible: true,
  line: {color: 'red'},
  xaxis: 'x2',
}, {
  x: [1, 2, 3],
  y: [3, 2, 4],
  visible: true,
  line: {color: 'green'},
  xaxis: 'x2',
}, {
  x: [1, 2, 3],
  y: [4, 3, 5],
  visible: true,
  line: {color: 'blue'},
  xaxis: 'x2',
}];

const layout = {
  xaxis: {
    range: [0, 4],
  },
  yaxis: {
    range: [0, 8],
  },
  grid: {
    rows: 1,
    columns: 2,
  },
  sliders: [{
    pad: {
      t: 30
    },
    currentvalue: {
      visible: false,
    },
    steps: [{
      label: 'red',
      method: 'restyle',
      args: ['visible', [true, false, false, true, false, false]]
    }, {
      label: 'green',
      method: 'restyle',
      args: ['visible', [false, true, false, false, true, false]]
    }, {
      label: 'blue',
      method: 'restyle',
      args: ['visible', [false, false, true, false, false, true]]
    }]
  }]
};

const traces = [];
Plotly.newPlot(graph, traces, layout);
Plotly.addTraces(graph, defTraces);
//Plotly.newPlot(graph, defTraces, layout);
graph.on('plotly_sliderchange', (event) => {
  console.log(event.slider.steps[0].args);
})


来源:https://stackoverflow.com/questions/47554585/plot-ly-using-slider-control-with-multiple-plots

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!