python - Shading background based on groups above/below a line -
suppose have scatterplot kind of line (least squares regression line, knn regression line, etc.) through it, this. want shade upper region of plot reddish, , lower region of plot blueish, give indication of how line doing classifier points. similar mimic example effect plot elements of statistical learning (hastie et al), (chapter 2, page 13).
how can achieve effect matplotlib?
i know how set rectangular regions of plot different colors axhspan
, axvspan
(see this answer), have been struggling set different plot colors based on regions above , below line.
code replicate current mock plot
import numpy np import matplotlib.pyplot 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', = '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()
first recommend sorting x
values, such line looks smooth.
x = np.sort(full_x) plt.plot(x, m*x + c, color='black')
then can use fill_between
fill region above (below) line (from) upper (lower) plot limits.
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)
or use hatching background:
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("\\\\")
Comments
Post a Comment