密谋:如何将跟踪添加到多类条形图中?

时间:2020-09-21 14:36:18

标签: python plotly plotly-python

我尝试将线添加到多类别条形图中,但未显示。是错误还是我错过了什么?

Offtopic:我可以格式化xaxis类别(刻度,而不是类别值)吗?因为tickformat自动引用了子类别。

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"))

1 个答案:

答案 0 :(得分:2)

这是设置中的错误或错误的说明。很明显,您的fig.add_traces(go.Scatter))可以执行 操作,因为它看起来像这样:

enter image description here

并且没有看起来像这样(注意y轴范围和图例):

enter image description here

问题似乎是多类别x轴。对于您的每条迹线,您都有以下x值:

([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)时,似乎正确地混淆了在何处确切显示位置。因此,您可以做的就是检索所有这些不同的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
)

这将产生以下情节:

enter image description here

我相信这个数字可以告诉您您想分享的故事。但是,如果我正确理解,您宁愿在[0, 1, 2]上方显示紫色线条,而不要在类别['Born','Died']上方显示。如果您能够切换x轴类别的显示顺序,则可能正是您所需要的。仔细查看以下完整的代码示例,发现时间我们可以讨论详细信息。

完整代码:

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()