对于上下文:我想绘制一个图来展示投资组合的演变,其中每项资产的价值都绘制在彼此之上。由于资产是买卖的,因此并非所有资产都应在整个曲线范围内显示。 下面的例子可以阐明这一点。前导零或尾随零表示该资产当时不在投资组合中。
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()
恐怕我无法构建一个优雅的解决方案。然而,这适用于您所说的大多数要求。工作原理:
plotly.express
提供有限的自定义控制。不要使用 plotly.express
,而使用 plotly.graph_objects
。它们具有相似的语法。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'
来完成。
如果你设置hovermode = 'x',你可能会得到你想要的。 如果您有很多堆叠特征,最好将其设置为“x统一”,以避免 - 尽可能 - 图表过度拥挤。
您可以在这里查看:https://plotly.com/python/hover-text-and-formatting/
fig.update_layout(hovermode = 'x')
fig.update_layout(hovermode = 'x unified')
该线程提供了一种不显示线条的方法,并且应该给出所需的效果:从绘图表达面积图中删除系列边框线