在面积图中不显示零

问题描述 投票:0回答:3

对于上下文:我想绘制一个图来展示投资组合的演变,其中每项资产的价值都绘制在彼此之上。由于资产是买卖的,因此并非所有资产都应在整个曲线范围内显示。 下面的例子可以阐明这一点。前导零或尾随零表示该资产当时不在投资组合中。

import pandas as pd
import plotly.express as px
import numpy as np
data = {"Asset 1": [0, 1, 2, 3, 4, 5], "Asset 2": [0, 0, 2, 3, 2, 2], "Asset 3": [1, 1, 3, 0, 0, 0]}
df = pd.DataFrame(data)
fig = px.area(df)
fig.show()

结果如下图:

现在的问题是,在指定的时间(索引=4),资产3不再在投资组合中,因此它的价值为0。但是它仍然显示,更大的问题是它使得无法看到价值投资组合中的资产 2。

我尝试将零更改为

NaN
值以表明它们不存在,但这给出了完全相同的数字。

data2 = {"a": [np.nan, 1, 2, 3, 4, 5], "b": [np.nan, np.nan, 2, 3, 2, 2], "c": [1, 1, 3, np.nan, np.nan, np.nan]}
df2 = pd.DataFrame(data2)
fig2 = px.area(df2)
fig2.show()

python plotly stacked-area-chart area-chart
3个回答
1
投票

恐怕我无法构建一个优雅的解决方案。然而,这适用于您所说的大多数要求。工作原理:

  • 不要使用自动堆叠功能,而是自己一根一根画线。
  • 这意味着您必须对数据帧进行一些预处理 - 通过计算 A+B 列和 A+B+C 列的值。
  • plotly.express
    提供有限的自定义控制。不要使用
    plotly.express
    ,而使用
    plotly.graph_objects
    。它们具有相似的语法。
  • 放置“痕迹”(又称线条)的顺序很重要。渲染的最后一行被放置在顶部。在您的问题陈述中,线条是从最左边的列绘制到最右边的列,这就是为什么重叠会偏向右边的列。
  • 在绘图之前必须手动将 NaN 值填零。否则,考虑到您的样本数据包含一定数量的 NaN,填充区域会产生奇怪的形状。
import pandas as pd
import numpy as np

import plotly.graph_objects as go

data = {"a": [np.nan, 1, 2, 3, 4, 5], "b": [np.nan, np.nan, 2, 3, 2, 2], "c": [1, 1, 3, np.nan, np.nan, np.nan]}
df = pd.DataFrame(data)

# fill NAs with zeros before doing anything
df = df.fillna(0)

fig = go.Figure()

# add lines one by one. The order matters - last one lays on top along with its hoverinfo
fig.add_trace(go.Scatter(
    x=df.index, 
    y=df['a'], 
    mode='lines',
    fill='tonexty',  # fill the area under line to next y
))

fig.add_trace(go.Scatter(
    x=df.index, 
    y=df['a']+df['b'], # sum of 'a' and 'b'
    mode='lines', 
    fill='tonexty', # fill the area under line to next y
))

fig.add_trace(go.Scatter(
    x=df.index, 
    y=df['a']+df['b']+df['c'], # sum of 'a' and 'b' and 'c'
    mode='lines', 
    fill='tonexty', # fill the area under line to next y
))

# minor bug where an area below zero is shown
fig.update_layout(yaxis=dict(range=[0, max(df.sum(axis=1) * 1.05)]))
fig.show()

结果图如下所示:

代表

df['a']+df['b']+df['c']
值的绿线仍然位于顶部。但是,悬停标签现在显示的是
df['a']+df['b']+df['c']
的值,而不是任一资产。

事实上,我发现这些资产分配图没有边缘线更漂亮:

这可以通过为 3 个绘图对象中的每一个设置

mode='none'
来完成。

备注:

  • 我为正在阅读的人尝试过的另一种方法:将每个填充区域和线条视为两条单独的迹线。通过这样做,您将需要定义自定义颜色对(纯色及其半透明颜色)。这导致了一些有问题的结果。此外,参数中设置的堆栈组的跟踪斗争不能包含 NaN 值,NaN 值将被零填充或插值。这会在这个问题的背景下产生糟糕的情节。

0
投票

如果你设置hovermode = 'x',你可能会得到你想要的。 如果您有很多堆叠特征,最好将其设置为“x统一”,以避免 - 尽可能 - 图表过度拥挤。

您可以在这里查看:https://plotly.com/python/hover-text-and-formatting/

fig.update_layout(hovermode = 'x')
fig.update_layout(hovermode = 'x unified')

0
投票

该线程提供了一种不显示线条的方法,并且应该给出所需的效果:从绘图表达面积图中删除系列边框线

© www.soinside.com 2019 - 2024. All rights reserved.