在图形交互式args中访问形状参数

时间:2017-02-23 04:19:10

标签: python-2.7 plotly

我试图将一个交互式形状(圆圈)添加到一组子图中(为简单起见,下面我只使用一个空图来创建一个简单的可重现的示例)。

以下代码的预期行为是使用下拉菜单在两个不同的圆圈之间切换。

struct NoIntermediate {};

template<typename R, typename I = NoIntermediate>
struct ParserCallbackSwitch
{
    using type = std::function<bool(const std::string &, R&, I&)>;
};

template<typename R> 
struct ParserCallbackSwitch<R, NoIntermediate>
{
    using type = std::function<bool(const std::string &, R&)>;
};

template<typename R, typename I = NoIntermediate>
class OtherClass
{
   public:
   typedef ParserCallbackSwitch<R, I>::type ParserType;
}

我认为我的错误是我以错误的方式引用了import plotly.plotly as py import plotly.graph_objs as go from plotly import tools # Create empty plot to put shapes into scatter = go.Scatter() fig = tools.make_subplots(cols=1) fig.append_trace(scatter, 1, 1) # Create two different shapes to select from fig['layout']['shapes'].append( { 'type': 'circle', 'xref': 'x', 'yref': 'y', 'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1, 'visible':True }) fig['layout']['shapes'].append( { 'type': 'circle', 'xref': 'x', 'yref': 'y', 'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5, 'visible':False }) # This doesn't work fig['layout']['updatemenus'] = [{ x:-0.05, y:0.8, buttons=[ {args:['layout.shapes.visible', [True, False]], label:'1', method:'restyle'}, {args:['layout.shapes.visible', [False, True]], label:'2', method:'restyle'} ] }] py.plot(fig, filename='shape_select') 参数,而visible应该替换为其他内容。

那么,在这种情况下如何正确引用形状参数?

2 个答案:

答案 0 :(得分:1)

要么我找到明显的解决方案太愚蠢了,但这对我来说似乎就像一个错误或未指明的行为。

最后8个下拉项目可靠地工作。前8个具有一些未指定的行为,具体取决于它们被单击的顺序,并且可能会相互干扰..

建议的解决方案使用参数解包来动态创建形状的字典,并为每个形状设置visible

import plotly

shape1 = {
            'type': 'circle',
            'xref': 'x', 'yref': 'y',
            'x0': 0, 'y0': 0, 'x1': 1, 'y1': 1,
            'line': {'color': 'rgb(0, 0, 255)'}
        }
shape2 = {
            'type': 'circle',
            'xref': 'x', 'yref': 'y',
            'x0': 0, 'y0': 0, 'x1': 0.5, 'y1': 0.5,
            'line': {'color': 'rgb(255, 0, 255)'}
        }

trace0 = plotly.graph_objs.Scatter(
    x= [0.2, 0.2, 0.3, 0.4, 0.2],
    y= [0.2, 0.5, 0.8, 0.3, 0.2]
)

data = plotly.graph_objs.Data([trace0])
layout = plotly.graph_objs.Layout(shapes=[shape1, shape2])
fig = plotly.graph_objs.Figure(data=data, layout=layout)
fig['layout']['shapes'].append(dict(visible=True, **shape1))
fig['layout']['shapes'].append(dict(visible=True, **shape2))


fig['layout']['updatemenus'] = [dict(
        x=-0.05, y=0.8,
        buttons=[
            dict(args=['shapes.visible', [False, True]], label='Hide big - does not work', method='relayout'),
            dict(args=['shapes.visible', [True, False]], label='Hide small - does not work', method='relayout'),
            dict(args=['shapes[0].visible', False], label='Hide big - might work', method='relayout'),
            dict(args=['shapes[1].visible', False], label='Hide small - might work', method='relayout'),
            dict(args=['shapes[0].visible', True], label='Show big', method='relayout'),
            dict(args=['shapes[1].visible', True], label='Show small', method='relayout'),
            dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=True, **shape2)]], label='Show all', method='relayout'),
            dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=False, **shape2)]], label='Hide all', method='relayout'),
            dict(args=['shapes', [dict(visible=True, **shape1), dict(visible=False, **shape2)]], label='Show big, hide small', method='relayout'),
            dict(args=['shapes', [dict(visible=False, **shape1), dict(visible=True, **shape2)]], label='Hide big, show small', method='relayout')
        ]
    )]

plotly.offline.plot(fig, filename='shape_select.html')

答案 1 :(得分:0)

这个更紧凑的解决方案也适用:

fig['layout']['updatemenus'] = [dict(
    x=-0.05, y=0.8,
        dict(args=[{'shapes[0].visible': True, 'shapes[1].visible': False}], label='First circle', method='relayout'),
        dict(args=[{'shapes[0].visible': False, 'shapes[1].visible': True}], label='First circle', method='relayout'),
    ]
)]