簡體   English   中英

使用 matplotlib cmap 在子圖之間填充

[英]Fill between subplots with matplotlib cmap

我在同一張圖上有 2 條線圖,是從熊貓數據框繪制的。

我想在它們之間填充各種漸變/顏色圖。

我知道我可以用 cmap 做到這一點,只是它對我不起作用(見下面的代碼)。

我發現的一般示例是在 x 軸和線之間填充,我不想要那個,而且我對可能的最簡單解決方案感興趣,因為我是這方面的初學者並且很復雜,盡管也許更好的代碼只會讓它更老實說更混亂。

填充為純藍色的代碼:

import matplotlib.pyplot as plt
import pandas as pd

ax = plt.gca()

df0.plot(kind='line', x='something', y='other', color='orange', ax=ax, legend=False, figsize=(20,10))
df1.plot(kind='line', x='something', y='other2', color='c', ax=ax, legend=False, figsize=(20,10))

ax.fill_between(x=df0['daysInAYear'], y1=df0['other'], y2 = df1['other2'], alpha=0.2, cmap=plt.cm.get_cmap("winter"))
plt.show()

編輯/更新:數據示例 other 總是 >= other2

other  other2  something (same for both)
15.6    -16.0      1
13.9    -26.7      2
13.3    -26.7      3
10.6    -26.1      4
12.8    -15.0      5

最終圖示例: 例子

我希望填充從頂部的橙色變為底部的藍色

編輯

為了回應編輯的問題,這里有一種替代方法,它垂直漸變但不使用imshow

import matplotlib.pyplot as plt
from  matplotlib import colors, patches
import numpy as np
import pandas as pd

n = 100
nc = 100

x = np.linspace(0, np.pi*5, n)
y1 = [-50.0]
y2 = [50.0]
for ii in range(1, n):
    y1.append(y1[ii-1] + (np.random.random()-0.3)*3)
    y2.append(y2[ii-1] + (np.random.random()-0.5)*3)
y1 = np.array(y1)
y2 = np.array(y2)
z = np.linspace(0, 10, nc)
normalize = colors.Normalize(vmin=z.min(), vmax=z.max())
cmap = plt.cm.get_cmap('winter')

fig, ax = plt.subplots(1)
for ii in range(len(df['x'].values)-1):
    y = np.linspace(y1[ii], y2[ii], nc)
    yn = np.linspace(y1[ii+1], y2[ii+1], nc)
    for kk in range(nc - 1):
        p = patches.Polygon([[x[ii], y[kk]], 
                             [x[ii+1], yn[kk]], 
                             [x[ii+1], yn[kk+1]], 
                             [x[ii], y[kk+1]]], color=cmap(normalize(z[kk])))
        ax.add_patch(p)

plt.plot(x, y1, 'k-', lw=1)
plt.plot(x, y2, 'k-', lw=1)
plt.show()

在此處輸入圖片說明

這里的想法與我原來的答案相似,除了梯形被分成nc塊,每塊都單獨着色。 這具有針對變化的y1[ii]y2[ii]距離正確縮放的優點,如本比較所示,

在此處輸入圖片說明

它,然而,有被許多缺點,遠遠低於imshow或水平梯度方法和存在無法處理“交叉”正確。

上面比較中生成第二張圖片的代碼:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches
from matplotlib.path import Path

x = np.linspace(0, 10, n)
y1 = [-50.0]
y2 = [50.0]
for ii in range(1, n):
    y1.append(y1[ii-1] + (np.random.random()-0.2)*3)
    y2.append(y2[ii-1] + (np.random.random()-0.5)*3)
y1 = np.array(y1)
y2 = np.array(y2)

verts = np.vstack([np.stack([x, y1], 1), np.stack([np.flip(x), np.flip(y2)], 1)])
path = Path(verts)

patch = patches.PathPatch(path, facecolor='k', lw=2, alpha=0.0)
plt.gca().add_patch(patch)

plt.imshow(np.arange(10).reshape(10,-1), cmap=plt.cm.winter, interpolation="bicubic",
             origin='upper', extent=[0,10,-60,60], aspect='auto', clip_path=patch, 
             clip_on=True)
plt.show()

原來的

這有點駭人聽聞,部分基於此問題中的答案。 它似乎工作得相當好,但在沿x軸密度較高的情況下效果最佳。 這個想法是為每個對應於x[x[ii], x[ii+1]]梯形分別調用fill_between 這是一個使用一些生成數據的完整示例

import matplotlib.pyplot as plt
from  matplotlib import colors
import numpy as np
import pandas as pd

n = 1000

X = np.linspace(0, np.pi*5, n)
Y1 = np.sin(X)
Y2 = np.cos(X)
Z = np.linspace(0, 10, n)
normalize = colors.Normalize(vmin=Z.min(), vmax=Z.max())
cmap = plt.cm.get_cmap('winter')

df = pd.DataFrame({'x': X, 'y1': Y1, 'y2': Y2, 'z': Z})
x = df['x'].values
y1 = df['y1'].values
y2 = df['y2'].values
z = df['z'].values

for ii in range(len(df['x'].values)-1):
    plt.fill_between([x[ii], x[ii+1]], [y1[ii], y1[ii+1]], 
                     [y2[ii], y2[ii+1]], color=cmap(normalize(z[ii])))

plt.plot(x, y1, 'k-', x, y2, 'k-')
plt.show()

在此處輸入圖片說明

這可以推廣到二維顏色網格,但需要進行非平凡的修改

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM