Plotly:如何向多类别条形图添加跟踪?
Plotly: How to add trace to multicategory bar chart?
我尝试向多类别条形图添加一条线,但未显示。是错误还是我遗漏了什么?
题外话:我可以格式化 xaxis 类别(刻度,而不是类别值)吗?,因为刻度格式自动引用子类别。
import pandas as pd
import plotly.graph_objects as go
df = pd.DataFrame({
"tick": [0, 0, 1, 1, 1, 2, 2, 2],
"value": [12, -6, 9, -14, -10, 9, -10, 5],
"category": ['Born', 'Died', 'Born', 'Died', 'Died', 'Born', 'Died', 'Born'],
"type": ["Penguin", "Lion", "Penguin", "Lion", "Apes", "Penguin", "Lion", "Apes"]
})
fig = go.Figure()
for t in df.type.unique():
plot_df = df[df.type == t]
fig.add_trace(go.Bar(
x=[plot_df.tick, plot_df.category],
y=abs(plot_df.value),
name=t,
))
total_df = df.groupby(['tick']).sum()
fig.add_trace(
go.Scatter(
x=df.tick.unique(),
y=total_df.value,
name="Born - Died",
mode='lines+markers',
)
)
fig.update_layout({
'barmode': 'stack',
'xaxis': {
'title_text': "Tick",
'dtick': 'M1',
'tickformat': "%m.%Y",
'tickangle': -90,
},
'yaxis': {
'title_text': "Value",
},
})
fig.write_html(str("./out2.html"))
这是您设置中的错误或 mis-specification。很明显,您的 fig.add_traces(go.Scatter))
做了 某事 因为它看起来像这样:
而 没有 它看起来像这样(注意 y-axis 范围和图例):
问题似乎是多类别 x-axis。对于你的每条痕迹,你都有以下 x-values:
([0, 1, 2], ['Born', 'Born', 'Born'])
([0, 1, 2], ['Died', 'Died', 'Died'])
([1, 2], ['Died', 'Born'])
[0 1 2]
因此,当您尝试 fig.add_traces(go.Scatter(x=df.tick.unique()))
其中 df.tick.unique()
是 array([0, 1, 2], dtype=int64)
时,plotly 似乎理所当然地混淆了究竟应该在哪里显示什么。因此,您可以做的是检索所有这些不同的 x-values 并尝试使用最适合您的需求:
xadj = [[*d['x']] for d in fig.data]
然后:
fig.add_trace(
go.Scatter(
#x=df.tick.unique().tolist(),
#x=total_df.index,
x=xadj[1],
y=total_df.value.tolist(),
name="Born - Died",
mode='lines+markers',
),secondary_y=True
)
这将产生这个情节:
我相信这个数字讲述了您想分享的故事。但是,如果我理解正确的话,您宁愿将紫色线显示在 [0, 1, 2]
的中心,而不是在类别 ['Born'、'Died'] 上方。如果您能够切换 x-axis 类别的显示顺序,这可能正是您所需要的。仔细看看下面完整的代码示例,有时间我们再详细谈。
完整代码:
import pandas as pd
import plotly.graph_objects as go
df = pd.DataFrame({
"tick": [0, 0, 1, 1, 1, 2, 2, 2],
"value": [12, -6, 9, -14, -10, 9, -10, 5],
"category": ['Born', 'Died', 'Born', 'Died', 'Died', 'Born', 'Died', 'Born'],
"type": ["Penguin", "Lion", "Penguin", "Lion", "Apes", "Penguin", "Lion", "Apes"]
})
from plotly.subplots import make_subplots
# set figure twith multiple y axes
fig = make_subplots(specs=[[{"secondary_y": True}]])
for t in df.type.unique():
plot_df = df[df.type == t]
fig.add_trace(go.Bar(
x=[plot_df.tick, plot_df.category],
#x=[plot_df.category, plot_df.tick],
y=abs(plot_df.value),
name=t,
))
total_df = df.groupby(['tick']).sum()
# xadj =[]
# for d in fig.data:
# xadj.append([*d['x']])
xadj = [[*d['x']] for d in fig.data]
fig.add_trace(
go.Scatter(
#x=df.tick.unique().tolist(),
#x=total_df.index,
x=xadj[1],
y=total_df.value.tolist(),
name="Born - Died",
mode='lines+markers',
),secondary_y=True
)
fig.update_layout({
'barmode': 'stack',
'xaxis': {
'title_text': "Tick",
'dtick': 'M1',
'tickformat': "%m.%Y",
'tickangle': -90,
},
'yaxis': {
'title_text': "Value",
},
})
#fig.write_html(str("./out2.html"))
fig.show()
我尝试向多类别条形图添加一条线,但未显示。是错误还是我遗漏了什么?
题外话:我可以格式化 xaxis 类别(刻度,而不是类别值)吗?,因为刻度格式自动引用子类别。
import pandas as pd
import plotly.graph_objects as go
df = pd.DataFrame({
"tick": [0, 0, 1, 1, 1, 2, 2, 2],
"value": [12, -6, 9, -14, -10, 9, -10, 5],
"category": ['Born', 'Died', 'Born', 'Died', 'Died', 'Born', 'Died', 'Born'],
"type": ["Penguin", "Lion", "Penguin", "Lion", "Apes", "Penguin", "Lion", "Apes"]
})
fig = go.Figure()
for t in df.type.unique():
plot_df = df[df.type == t]
fig.add_trace(go.Bar(
x=[plot_df.tick, plot_df.category],
y=abs(plot_df.value),
name=t,
))
total_df = df.groupby(['tick']).sum()
fig.add_trace(
go.Scatter(
x=df.tick.unique(),
y=total_df.value,
name="Born - Died",
mode='lines+markers',
)
)
fig.update_layout({
'barmode': 'stack',
'xaxis': {
'title_text': "Tick",
'dtick': 'M1',
'tickformat': "%m.%Y",
'tickangle': -90,
},
'yaxis': {
'title_text': "Value",
},
})
fig.write_html(str("./out2.html"))
这是您设置中的错误或 mis-specification。很明显,您的 fig.add_traces(go.Scatter))
做了 某事 因为它看起来像这样:
而 没有 它看起来像这样(注意 y-axis 范围和图例):
问题似乎是多类别 x-axis。对于你的每条痕迹,你都有以下 x-values:
([0, 1, 2], ['Born', 'Born', 'Born'])
([0, 1, 2], ['Died', 'Died', 'Died'])
([1, 2], ['Died', 'Born'])
[0 1 2]
因此,当您尝试 fig.add_traces(go.Scatter(x=df.tick.unique()))
其中 df.tick.unique()
是 array([0, 1, 2], dtype=int64)
时,plotly 似乎理所当然地混淆了究竟应该在哪里显示什么。因此,您可以做的是检索所有这些不同的 x-values 并尝试使用最适合您的需求:
xadj = [[*d['x']] for d in fig.data]
然后:
fig.add_trace(
go.Scatter(
#x=df.tick.unique().tolist(),
#x=total_df.index,
x=xadj[1],
y=total_df.value.tolist(),
name="Born - Died",
mode='lines+markers',
),secondary_y=True
)
这将产生这个情节:
我相信这个数字讲述了您想分享的故事。但是,如果我理解正确的话,您宁愿将紫色线显示在 [0, 1, 2]
的中心,而不是在类别 ['Born'、'Died'] 上方。如果您能够切换 x-axis 类别的显示顺序,这可能正是您所需要的。仔细看看下面完整的代码示例,有时间我们再详细谈。
完整代码:
import pandas as pd
import plotly.graph_objects as go
df = pd.DataFrame({
"tick": [0, 0, 1, 1, 1, 2, 2, 2],
"value": [12, -6, 9, -14, -10, 9, -10, 5],
"category": ['Born', 'Died', 'Born', 'Died', 'Died', 'Born', 'Died', 'Born'],
"type": ["Penguin", "Lion", "Penguin", "Lion", "Apes", "Penguin", "Lion", "Apes"]
})
from plotly.subplots import make_subplots
# set figure twith multiple y axes
fig = make_subplots(specs=[[{"secondary_y": True}]])
for t in df.type.unique():
plot_df = df[df.type == t]
fig.add_trace(go.Bar(
x=[plot_df.tick, plot_df.category],
#x=[plot_df.category, plot_df.tick],
y=abs(plot_df.value),
name=t,
))
total_df = df.groupby(['tick']).sum()
# xadj =[]
# for d in fig.data:
# xadj.append([*d['x']])
xadj = [[*d['x']] for d in fig.data]
fig.add_trace(
go.Scatter(
#x=df.tick.unique().tolist(),
#x=total_df.index,
x=xadj[1],
y=total_df.value.tolist(),
name="Born - Died",
mode='lines+markers',
),secondary_y=True
)
fig.update_layout({
'barmode': 'stack',
'xaxis': {
'title_text': "Tick",
'dtick': 'M1',
'tickformat': "%m.%Y",
'tickangle': -90,
},
'yaxis': {
'title_text': "Value",
},
})
#fig.write_html(str("./out2.html"))
fig.show()