我以前见过以某种形式提出过这个问题,但从未完全回答过,所以我会试试运气。
在具有多条痕迹的图中,我试图填充我选择的两条特定线之间的区域。 使用 matplotlib.pyplot 实现的预期效果如下所示:
青色和橙色区域填充在各自的趋势之间,并向上/向下填充到红线。黑线与那些填充区域无关,但无论如何都应该沿着红线绘制。
我尝试使用 Plotly 的 fill: 'tonexty' 来实现这一点,但这效果不佳,因为由于数据的随机性,最近的 Y 有时是黑线而不是红线。
我可以使用 pyplot 的 fill_ Between 函数来实现这一点:
plt.fill_between(x, y1, y2)
它可以用作:
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
series1 = pd.Series(np.random.randn(100), index=pd.date_range('1/1/2000', periods=100))
series2 = series1 + np.random.randn(len(series1))
positive_contribution = series2 + 0.5
negative_contribution = series2 - 0.5
plt.plot(series1, color='black')
plt.plot(series2, color='red')
plt.fill_between(series2.index, series2, negative_contribution, color='cyan', alpha=0.2)
plt.fill_between(series2.index, series2, positive_contribution, color='orange', alpha=0.2)
我很想听到这个问题的解决方案/解决方法。
实现此目的的一种方法是按正确的顺序添加迹线。我注意到的一件重要的事情是,
"tonexty"
实际上填充了当前跟踪和之前添加到“跟踪存储”中的跟踪之间的空间。
因此,第一个选项是从上到下或从下到上添加跟踪(我选择从下到上,这部分是从 plotly 文档中提取的):
# the cyan trace, without color filling
fig.add_trace(
go.Scatter(
x=series2.index,
y=negative_contribution,
fill=None,
mode="lines",
line_color="cyan",
)
)
# the red trace, with cyan color filling up to the previously added trace
fig.add_trace(
go.Scatter(
x=series2.index,
y=series2,
fill="tonexty",
fillcolor="cyan",
mode="lines",
line_color="red",
)
)
# the orange trace, with orange color filling to the previously added trace (the red one).
fig.add_trace(
go.Scatter(
x=series2.index,
y=positive_contribution,
fill="tonexty", # fill area between trace0 and trace1
mode="lines",
line_color="orange",
)
)
# add the black trace.
fig.add_trace(
go.Scatter(
x=series1.index,
y=series1,
fill=None,
mode="lines",
line_color="black",
)
)
此解决方案的一个问题是青色填充图例将与红色迹线合并,这可能会造成混淆。
另一个解决方案是始终在
tonexty
迹线之前添加要填充的迹线。您应该使用透明颜色,对除最后添加的迹线之外的任何迹线使用 showlegend=False
(如果需要重复添加迹线):
# add a transparent red trace not visible on legend.
fig.add_trace(
go.Scatter(
x=series2.index,
y=series2,
fill=None,
mode="lines",
line_color="rgba(0,0,0,0)",
showlegend=False,
)
)
# add orange trace
fig.add_trace(
go.Scatter(
x=series2.index,
y=positive_contribution,
fill="tonexty",
mode="lines",
line_color="orange",
)
)
# re add the red trace, but visible this time, as this is the last one
fig.add_trace(
go.Scatter(
x=series2.index,
y=series2,
fill=None,
mode="lines",
line_color="red",
)
)
# add the cyan trace
fig.add_trace(
go.Scatter(
x=series2.index,
y=negative_contribution,
fill="tonexty",
mode="lines",
line_color="cyan",
)
)
# finally add the black trace
fig.add_trace(
go.Scatter(
x=series1.index,
y=series1,
fill=None,
mode="lines",
line_color="black",
)
)
它更可控,但是,多次添加相同的轨迹可能会增加虚假的交互效果。