Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Plotly(Python)子图:填充面和共享图例_Python_Plotly - Fatal编程技术网

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

Plotly(Python)子图:填充面和共享图例,python,plotly,Python,Plotly,我正在尝试创建两个共享x轴的绘图,但有两个问题: 当我使用yaxis和yaxis2标题和/或记号自定义布局时,y轴开始重叠 我希望在两个绘图之间共享图例,但它们是重复的 下面是重现我遇到的问题的代码: from plotly.offline import init_notebook_mode, iplot init_notebook_mode(connected=True) # using jupyter import plotly.graph_objs as go from plotly im

我正在尝试创建两个共享x轴的绘图,但有两个问题:

  • 当我使用
    yaxis
    yaxis2
    标题和/或记号自定义布局时,y轴开始重叠
  • 我希望在两个绘图之间共享图例,但它们是重复的
  • 下面是重现我遇到的问题的代码:

    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)  
    
    这是我得到的图像:

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

    曼尼,先谢谢你

    编辑:

    按照Farbice的建议,我从plotly.figure\u factory(顺便说一句,它需要plotly 2.0.12+)中查看了
    创建面网格
    函数,我确实设法用更少的线条复制了相同的图像,但它给了我更少的灵活性——例如,我认为您不能使用此功能绘制线条,而且它也存在图例复制问题,但如果您正在寻找一个特别的viz,这可能会非常有效。它需要长格式的数据,请参见以下示例:

    # converting into the long format
    import pandas as pd
    perf_df = (
        pd.DataFrame({
            'accuracy_train': model_perf['acc'],
            'accuracy_validation': model_perf['val_acc'],
            'loss_train': model_perf['loss'],
            'loss_validation': model_perf['val_loss']
        })
        .stack()
        .reset_index()
        .rename(columns={
            'level_0': 'epoch',
            'level_1': 'variable',
            0: 'value'
        })
    )
    
    perf_df = pd.concat(
        [
            perf_df,
            perf_df['variable']
            .str
            .extractall(r'(?P<metric>^.*)_(?P<set>.*$)')
            .reset_index()[['metric','set']]   
        ], axis=1
    ).drop(['variable'], axis=1)
    
    perf_df.head() # result
    
    epoch  value     metric     set
    0      0.434349  accuracy   train
    0      0.374607  accuracy   validation
    0      0.864698  loss       train
    0      0.007445  loss       validation
    1      0.553727  accuracy   train
    
    # plot it
    fig = ff.create_facet_grid(
        perf_df,
        x='epoch',
        y='value',
        facet_row='metric',
        color_name='set',
        scales='free_y',
        ggplot2=True
    )
    
    fig['layout'].update(
        height=800, 
        width=1000, 
        yaxis1 = dict(tickformat=".0%"),
        yaxis2 = dict(tickformat=".0%"),
        title='Performance'
    )
    
    iplot(fig)
    
    #转换为长格式
    作为pd进口熊猫
    性能参数=(
    数据帧({
    “精度列车”:型号性能['acc'],
    “准确性验证”:模型性能['val\u acc'],
    “损失列车”:型号性能[“损失”],
    “损失验证”:模型性能['val\u损失']
    })
    .stack()
    .reset_index()
    .重命名(列)={
    “0级”:“历元”,
    “级别1”:“变量”,
    0:“值”
    })
    )
    性能df=pd.concat(
    [
    性能测向,
    性能df[“变量”]
    .str
    .extractall(r'(?P^.*)(?P.*))
    .reset_index()[['metric','set']]
    ],轴=1
    ).drop(['variable'],轴=1)
    性能df.head()#结果
    历元值度量集
    0.4349精度系列
    0.374607精度验证
    0.864698损失列车
    0.007445损失验证
    1 0.553727精度列车
    #策划它
    图=ff.创建面网格(
    性能测向,
    x='epoch',
    y='value',
    facet_row='metric',
    颜色_name='set',
    刻度为“自由度”,
    ggplot2=真
    )
    图[‘布局’]更新(
    高度=800,
    宽度=1000,
    yaxis1=dict(tickformat=“.0%”),
    yaxis2=dict(tickformat=“.0%”),
    title='Performance'
    )
    iplot(图)
    
    结果如下:
    根据我的经验,可视化工具更喜欢长格式的数据。 您可能希望将数据调整为具有以下列的表:

    • 纪元
    • 变量:“acc”或“损失”
    • 设置:“验证”或“培训”
    • 值:给定历元/变量/集合的值
    通过这样做,您可能会发现在“变量”和“集合”上使用刻面更容易创建所需的图形-轨迹具有x=历元,y=值

    如果您想要一个编码的解决方案,请提供一些数据


    希望这有帮助。

    在做了更多的挖掘之后,我找到了两个问题的解决方案

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

    《传奇》中复制的第二个问题有点棘手,但《邮报》帮我解决了这个问题。其思想是,每个轨迹都可以有一个与其关联的图例,因此,如果要打印多个轨迹,则可能只希望使用其中一个轨迹的图例(使用
    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)  
    
    结果如下:


    感谢您的建议,我习惯于使用ggplot,它确实更喜欢您描述的格式的数据,但是,plotly似乎对数据的底层结构漠不关心,该结构源自声明的跟踪,因此如果您对如何使用任何数据格式修复我描述的问题有任何建议,那么我想了解更多。Cheerri也开始使用ggplot,但现在我使用python而不是R,plotly的create_facet_grid函数的作用与此选项中ggplot的作用类似。可能确实有另一种解决方案,但他们总是告诉我:“首先让它工作,然后让它更好”。目前,这是我唯一能想到的。谢谢,我将尝试创建网格,并让您知道它是如何运行的!实际上,如果希望x轴标题显示在底部刻面下,请在布局更新块中将
    xaxis
    替换为
    xaxis1