提问人:Rokas Karabevičius 提问时间:1/31/2023 最后编辑:Rokas Karabevičius 更新时间:2/1/2023 访问量:90
Matplotlib - 使用 fill_between 重新创建在绘图中渲染的堆栈图网格线
Matplotlib - Recreating stackplot gridlines rendering in plot with fill_between
问:
我需要将堆栈图重新创建为带有 fill_between(无堆叠)的简单图。网格线渲染似乎不同,我不知道如何使它们看起来相同。代码如下:
import pandas as pd
import numpy as np
mpl.rcParams.update(mpl.rcParamsDefault)
plt.style.use("ggplot")
_styles = {
'axes.edgecolor': '#bcbcbc',
'axes.facecolor': 'white',
'grid.color': '#b2b2b2',
'grid.linestyle': '--',
}
plt.rcParams.update(_styles)
def plot_a_plot(x_axis, actual, predicted, size=(10,4)):
plt.figure(figsize=size)
p1 = plt.plot(x_axis, actual, alpha=0.5, label=actual.name, lw=0.5)
plt.fill_between(x_axis, actual.astype(np.float64), color='#F0A498', alpha=1, zorder=1)
p2 = plt.plot(x_axis, predicted, alpha=0.5, label=predicted.name, lw=0.5)
plt.fill_between(x_axis, predicted.astype(np.float64), color='C1', alpha=0.5, zorder=0)
plt.grid(True, zorder=10)
plt.title('Plot with fill_between')
plt.show()
def plot_a_stackplot(x_axis, actual, predicted, size=(10,4)):
y = np.vstack([actual.astype(float), predicted.astype(float)])
plt.figure(figsize=size)
plt.stackplot(x_axis, y, labels=[actual.name, predicted.name], alpha=0.5, edgecolors="face")
plt.title('Stackplot')
plt.show()
arr = np.random.rand(10)
data = {
"actual": arr,
"predicted": arr*2
}
df = pd.DataFrame(data)
x_axis = df.index
actual = df['actual']
predicted = df['predicted']
plot_a_plot(x_axis, actual, predicted)
plot_a_stackplot(x_axis, actual, predicted)
更改 zorder 似乎没有任何效果,我还玩过 alpha 级别等 - 似乎没有任何效果。堆栈图上的网格线看起来就像它应该看起来一样,而简单图上的网格线看起来很泥泞。
答:
0赞
Matt Pitkin
1/31/2023
#1
请尝试以下操作(我在此示例中未添加标签):
def plot_a_plot(x_axis, actual, predicted, size=(10, 4)):
fig, ax = plt.subplots(figsize=size)
ax.plot(x_axis, actual, lw=0.5, alpha=0.5)
ax.fill_between(
x_axis,
actual,
np.zeros_like(data["actual"]), # explicitly set the "bottom" to be zero (this is the default so isn't actually required here)
color='#F0A498',
alpha=0.5, # set alpha to 0.5
zorder=1
)
ax.plot(x_axis, predicted, lw=0.5, alpha=0.5)
ax.fill_between(
x_axis,
predicted,
actual, # explicitly set the "bottom" to be actual, so it doesn't cover actual
color='C1',
alpha=0.5,
zorder=0
)
ax.grid(zorder=10)
fig.show()
这基本上是正在做的事情(尽管它显然绘制了累积的“顶部”和“底部”)。stackplot
评论
0赞
Rokas Karabevičius
1/31/2023
我试过了 - 输出看起来和以前差不多。我意识到我没有在代码中添加样式参数,现在添加样式参数是为了准确再现手头的问题。我还找到了一种骇人听闻的方法来获得我想要的东西——通过在预测和实际之间取差,并使用堆栈图,它把所有东西都呈现得很漂亮,开箱即用。然而,令我烦恼的是,我找不到一种方法来用简单的情节来模仿相同的外观。
0赞
Matt Pitkin
1/31/2023
当我运行它时,它对我来说看起来还不错,但它可能是 Matploltib 版本差异(我使用的是最新的 3.6.3)或显示差异。
1赞
Tranbi
2/1/2023
#2
这似乎与值不符。在此演示中,始终选择 >=1。
如果您将函数更改为:zorder
0
def plot_a_plot(x_axis, actual, predicted, size=(10,4)):
plt.figure(figsize=size)
p1 = plt.plot(x_axis, actual, alpha=0.5, label=actual.name, lw=0.5)
plt.fill_between(x_axis, actual.astype(np.float64), color='#F0A498', alpha=1, zorder=2)
p2 = plt.plot(x_axis, predicted, alpha=0.5, label=predicted.name, lw=0.5)
plt.fill_between(x_axis, predicted.astype(np.float64), color='C1', alpha=0.5, zorder=1)
plt.grid(True, zorder=10)
plt.title('Plot with fill_between')
plt.show()
编辑:如果您希望底部区域(红色)看起来与堆栈图完全相同,则应使用正确的颜色。您可以通过以下方式找到颜色:
for color in plt.rcParams['axes.prop_cycle']:
print(color)
第一个是你要找的:(也可以)#E24A33
C0
从那里开始,第二个调用应在 和 之间填充,否则填充区域将重叠:fill_between
actual
predicted
def plot_a_plot(x_axis, actual, predicted, size=(10,4)):
plt.figure(figsize=size)
p1 = plt.plot(x_axis, actual, alpha=0.5, label=actual.name, lw=0.5)
plt.fill_between(x_axis, actual.astype(np.float64), color='#E24A33', alpha=0.5, zorder=2)
p2 = plt.plot(x_axis, predicted, alpha=0.5, label=predicted.name, lw=0.5)
plt.fill_between(x_axis, actual, predicted, color='C1', alpha=0.5, zorder=1)
plt.grid(True, zorder=10)
plt.title('Plot with fill_between')
plt.show()
评论
0赞
Rokas Karabevičius
2/1/2023
这似乎可以解决问题,至少对于蓝色地块来说是这样。尽管在红色图上添加网格仍然很棘手,因为减少 alpha 会改变阴影。假设我删除颜色参数,将 alpha 降至 0.5,它应该看起来像堆栈图,但事实并非如此。然而,这不是原始问题的一部分,所以答案是+1。谢谢。
0赞
Tranbi
2/1/2023
看看我编辑过的答案。如果您认为问题已解决,您也可以接受答案。
评论
plt.gca().set_axisbelow(False)
应该把网格放在上面。