Plotly(Python)子图:填充面和共享图例
我正在尝试创建两个共享x轴的绘图,但有两个问题: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
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
。