Matplotlib:使用颜色图显示过程围绕其均值的集中度
Matplotlib: use a colormap to show concentration of a process around its mean
我有一个 pandas DataFrame,其中包含给定过程的 100 个实现,在 10 个不同的日期观察(所有实现都从日期 0 的同一点开始)。
这样的 DataFrame 可以通过以下方式生成:
import pandas as pd
import numpy as np
nbDates = 10
nbPaths = 100
rnd = np.random.normal(loc=0, scale=1, size=nbPaths*nbDates).reshape(nbDates,nbPaths)
sim = dict()
sim[0] = [100.0] * nbPaths
for t in range(nbDates):
sim[t+1] = sim[t] + rnd[t]
sim = pd.DataFrame(sim)
现在我知道我可以像这样绘制 DataFrame 中包含的 100 条路径
sim.T.plot(legend=False)
并获得这样的图表:
但我实际上想做的是绘制每个日期过程的最小值和最大值,并用颜色图为两个极值之间的区域着色,以反映图中路径的集中度 (例如,当我们走向极端时,红色围绕平均值并逐渐变冷)。
我已经研究过使用颜色图来实现这一点,但我还没有成功。如果有人知道一个简单的方法来做到这一点,那将非常有帮助。
谢谢!
你可以这样做(虽然可能不是最优雅的方式)首先用 contourf
绘制你的 "concentration" 的等高线图,然后绘制你的最大值和最小值的线图,最后使用 fill_between
方法来掩盖等高线图不需要的部分。然而,执行此操作的正确方法是在等高线图中屏蔽数组,但我现在没有时间弄清楚(看看 numpy mask array options 并尝试一下)。您希望屏蔽数组以仅显示在最大值和最小值之间。
下面是一个使用 fill_between
而不是屏蔽数组的示例:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
## Your simulation code here ##
# Extract max, min, and mean values for each x coordinate
minimums = np.array(sim.min())
maximums = np.array(sim.max())
means = np.array(sim.mean())
x = np.array(sim.min().index)
y = np.arange(90,111)
X, Y = np.meshgrid(x, y)
# Insert your calculation for "concentration" in the line below
Z = (maximums[X] - minimums[X]) * Y // 100
# set up axes with matplotlib
fig, ax = plt.subplots()
# Plot contour, you'll want to change the levels
# depending on the range of values in your "concentration"
ax.contourf(X, Y, Z, levels=np.arange(0,20,.1), cmap=plt.get_cmap('jet'))
# Plot min, max, and mean
ax.plot(x, minimums, c='k')
ax.plot(x, maximums, c='k')
ax.plot(x, means, c='k', lw=2)
# Fill space outside min and max with white
ax.fill_between(x, maximums, 110, color='w')
ax.fill_between(x, 90, minimums, color='w')
这应该产生以下输出:
您可以选择自己的函数来计算 "concentration" 以获得您想要的填充图案。上面代码中的代码旨在展示如何让它依赖于绘图中的 X 和 Y 位置。祝你好运!
我有一个 pandas DataFrame,其中包含给定过程的 100 个实现,在 10 个不同的日期观察(所有实现都从日期 0 的同一点开始)。 这样的 DataFrame 可以通过以下方式生成:
import pandas as pd
import numpy as np
nbDates = 10
nbPaths = 100
rnd = np.random.normal(loc=0, scale=1, size=nbPaths*nbDates).reshape(nbDates,nbPaths)
sim = dict()
sim[0] = [100.0] * nbPaths
for t in range(nbDates):
sim[t+1] = sim[t] + rnd[t]
sim = pd.DataFrame(sim)
现在我知道我可以像这样绘制 DataFrame 中包含的 100 条路径
sim.T.plot(legend=False)
并获得这样的图表:
但我实际上想做的是绘制每个日期过程的最小值和最大值,并用颜色图为两个极值之间的区域着色,以反映图中路径的集中度 (例如,当我们走向极端时,红色围绕平均值并逐渐变冷)。
我已经研究过使用颜色图来实现这一点,但我还没有成功。如果有人知道一个简单的方法来做到这一点,那将非常有帮助。
谢谢!
你可以这样做(虽然可能不是最优雅的方式)首先用 contourf
绘制你的 "concentration" 的等高线图,然后绘制你的最大值和最小值的线图,最后使用 fill_between
方法来掩盖等高线图不需要的部分。然而,执行此操作的正确方法是在等高线图中屏蔽数组,但我现在没有时间弄清楚(看看 numpy mask array options 并尝试一下)。您希望屏蔽数组以仅显示在最大值和最小值之间。
下面是一个使用 fill_between
而不是屏蔽数组的示例:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
## Your simulation code here ##
# Extract max, min, and mean values for each x coordinate
minimums = np.array(sim.min())
maximums = np.array(sim.max())
means = np.array(sim.mean())
x = np.array(sim.min().index)
y = np.arange(90,111)
X, Y = np.meshgrid(x, y)
# Insert your calculation for "concentration" in the line below
Z = (maximums[X] - minimums[X]) * Y // 100
# set up axes with matplotlib
fig, ax = plt.subplots()
# Plot contour, you'll want to change the levels
# depending on the range of values in your "concentration"
ax.contourf(X, Y, Z, levels=np.arange(0,20,.1), cmap=plt.get_cmap('jet'))
# Plot min, max, and mean
ax.plot(x, minimums, c='k')
ax.plot(x, maximums, c='k')
ax.plot(x, means, c='k', lw=2)
# Fill space outside min and max with white
ax.fill_between(x, maximums, 110, color='w')
ax.fill_between(x, 90, minimums, color='w')
这应该产生以下输出:
您可以选择自己的函数来计算 "concentration" 以获得您想要的填充图案。上面代码中的代码旨在展示如何让它依赖于绘图中的 X 和 Y 位置。祝你好运!