基于线上方/下方的组着色背景

时间:2017-08-20 03:52:24

标签: python matplotlib plot regression

假设我有一个带有某种线条(最小二乘回归线,knn回归线等)的散点图,就像这样。 enter image description here 我想将阴影的上部区域变暗,并将阴影的下部区域变成蓝色,以指示我的线作为点的分类器。与我的模仿示例相似,此效果来自Elements of Statistical Learning (Hastie et al),(第2章,第13页)。

enter image description here

如何使用Matplotlib实现此效果?

我知道如何使用axhspanaxvspan(请参阅this answer)将绘图的矩形区域设置为不同颜色,但一直在努力根据区域设置不同的绘图颜色在之上和之下。

复制我当前模拟情节的代码

import numpy as np
import matplotlib.pyplot as plt

plt.style.use('seaborn-notebook')

np.random.seed(17)
grp1_x = np.random.normal(1, 1, 100)
grp1_y = np.random.normal(3, 1, 100)

grp2_x = np.random.normal(1.2, 1, 100)
grp2_y = np.random.normal(1.2, 1, 100)

########################################
## least squares plot

plt.scatter(grp1_x, grp1_y,
            lw         = 1,
            facecolors = 'none',
            edgecolors = 'firebrick')
plt.scatter(grp2_x, grp2_y,
            lw         = 1,
            facecolors = 'none',
            edgecolors = 'steelblue')
plt.tick_params(
    axis        = 'both',
    which       = 'both',
    bottom      = 'off',
    top         = 'off',
    labelbottom = 'off',
    right       = 'off',
    left        = 'off',
    labelleft   = 'off')

full_x = np.concatenate([grp1_x, grp2_x])
full_y = np.concatenate([grp1_y, grp2_y])
m, c = np.linalg.lstsq(np.vstack([full_x,
                                  np.ones(full_x.size)]).T,
                       full_y)[0]
plt.plot(full_x, m*full_x + c, color='black')
plt.show()

1 个答案:

答案 0 :(得分:4)

首先,我建议对x值进行排序,使线条看起来平滑。

x = np.sort(full_x)
plt.plot(x, m*x + c, color='black')

然后,您可以使用fill_between填充上方(下方)上方(下方)地块限制区域的区域。

xlim=np.array(plt.gca().get_xlim())
ylim=np.array(plt.gca().get_ylim())
plt.fill_between(xlim, y1=m*xlim + c, y2=[ylim[0],ylim[0]], 
                 color="#e0eaf3", zorder=0 )
plt.fill_between(xlim, y1=m*xlim + c, y2=[ylim[1],ylim[1]], 
                 color="#fae4e4", zorder=0 )
plt.margins(0)

enter image description here

或者为背景使用一些阴影线:

fb1 = plt.fill_between(xlim, y1=m*xlim + c, y2=[ylim[0],ylim[0]], 
                 facecolor="w", edgecolor="#e0eaf3", zorder=0 )
fb1.set_hatch("//")
fb2 = plt.fill_between(xlim, y1=m*xlim + c, y2=[ylim[1],ylim[1]], 
                  facecolor="w", edgecolor="#fae4e4", zorder=0 )
fb2.set_hatch("\\\\")

enter image description here