Plotly(Python)子图:填充构面和共享图例

时间:2017-12-21 21:12:43

标签: python plotly

我正在尝试使用共享的x轴创建2个图,我遇到了2个问题:

  1. 我使用yaxisyaxis2标题和/或标记自定义布局后,y轴开始重叠
  2. 我希望这两个地块之间能够分享这些传说,但它们是重复的
  3. 以下是重现我遇到的问题的代码:

    from plotly.offline import init_notebook_mode, iplot
    init_notebook_mode(connected=True) # using jupyter
    import plotly.graph_objs as go
    from plotly import tools
    import numpy as np
    
     N = 100
    epoch_range = [i for i in range(N)]
    model_perf = {}
    for m in ['acc','loss']:
        for sub in ['train','validation']:
            if sub == 'train':
                history_target = m
            else:
                history_target = 'val_{}'.format(m)
            model_perf[history_target] = np.random.random(N)
    
    line_type = {
        'train': dict(
            color='grey',
            width=1,
            dash='dash'
        ),
        'validation': dict(
            color='blue',
            width=4
        )
    }
    
    fig = tools.make_subplots(rows=2, cols=1, shared_xaxes=True, shared_yaxes=False, specs = [[{'b':10000}], [{'b':10000}]])
    i = 0
    for m in ['acc','loss']:
    
        i += 1
    
        for sub in ['train','validation']:
    
            if sub == 'train':
                history_target = m
            else:
                history_target = 'val_{}'.format(m)
    
            fig.append_trace({
                'x': epoch_range,
                'y': model_perf[history_target],
                #'type': 'scatter',
                'name': sub,
                'legendgroup': m,
                'yaxis': dict(title=m),
                'line': line_type[sub],
                'showlegend': True
            }, i, 1)
    
    fig['layout'].update(
        height=600, 
        width=800, 
        xaxis = dict(title = 'Epoch'),
        yaxis = dict(title='Accuracy', tickformat=".0%"),
        yaxis2 = dict(title='Loss', tickformat=".0%"),
        title='Performance'
    )
    iplot(fig)  
    

    这是我得到的图像: Output

    如果您对如何解决这两个问题有任何建议,我很乐意听取您的意见。

    曼尼提前谢谢!

    修改

    按照Farbice的建议,我查看了来自create_facet_grid的{​​{1}}函数(顺便说一下,需要2.0.12+),我确实设法用更少的行重现相同的图像,但它给了我的灵活性较低 - 例如我不认为你可以使用这个功能绘制线条,它也有传说重复问题,但如果你正在寻找一个临时的,这可能是非常有效的。它需要长格式的数据,请参见下面的示例:

    plotly.figure_factory

    结果如下: create_facet_grid

2 个答案:

答案 0 :(得分:0)

根据我的经验,可视化工具更喜欢长格式的数据。 您可能希望将数据调整为具有以下列的表:

  • 历元
  • 变量:' acc'或者'损失'
  • 设置:'验证'或者' train'
  • value:给定epoch / variable / set的值

通过这样做,您可能会发现通过在变量'变量上使用构面来创建所需的图表更容易。使用'设置' -traces,其中x = epoch,y = value

如果您是编码解决方案,请提供一些数据。

希望这有用。

答案 1 :(得分:0)

经过多挖掘后,我找到了解决问题的方法。

首先,重叠的y轴问题是由布局更新中的yaxis参数引起的,必须更改为yaxis1

传奇中重复的第二个问题有点棘手,但this帖子帮助我解决了问题。我们的想法是每个跟踪都可以有一个与之关联的图例,因此如果您要绘制多个跟踪,您可能只想使用其中一个跟踪的图例(使用showlegend参数),但要确保一个图例控制多个子图的切换,您可以使用legendgroup参数。

以下是解决方案的完整代码:

from plotly.offline import init_notebook_mode, iplot
init_notebook_mode(connected=True) # using jupyter
import plotly.graph_objs as go
from plotly import tools
import numpy as np

N = 100
epoch_range = [i for i in range(N)]
model_perf = {}
for m in ['acc','loss']:
    for sub in ['train','validation']:
        if sub == 'train':
            history_target = m
        else:
            history_target = 'val_{}'.format(m)

        model_perf[history_target] = np.random.random(N)

line_type = {
    'train': dict(
        color='grey',
        width=1,
        dash='dash'
    ),
    'validation': dict(
        color='blue',
        width=4
    )
}

fig = tools.make_subplots(
    rows=2, 
    cols=1, 
    shared_xaxes=True, 
    shared_yaxes=False
)

i = 0
for m in ['acc','loss']:

    i += 1

    if m == 'acc':
        legend_display = True
    else:
        legend_display = False

    for sub in ['train','validation']:

        if sub == 'train':
            history_target = m
        else:
            history_target = 'val_{}'.format(m)

        fig.append_trace({
            'x': epoch_range,
            'y': model_perf[history_target],
            'name': sub,
            'legendgroup': sub, # toggle train / test group on all subplots
            'yaxis': dict(title=m),
            'line': line_type[sub],
            'showlegend': legend_display # this is now dependent on the trace
        }, i, 1)

fig['layout'].update(
    height=600, 
    width=800, 
    xaxis = dict(title = 'Epoch'),
    yaxis1 = dict(title='Accuracy', tickformat=".0%"),
    yaxis2 = dict(title='Loss', tickformat=".0%"),
    title='Performance'
)
iplot(fig)  

结果如下:

enter image description here