根据轮廓颜色对颜色点进行标记

5

有没有一种方法可以根据contour函数使用的颜色映射为点着色?我知道我可以指定一个颜色映射,但是contour函数可能会对数据进行一些缩放和/或归一化处理。

下面是一个示例:

import numpy as np
import scipy.stats as ss

def plot_2d_probsurface(data, resolution=20, ax = None, xlim=None, ylim=None):
    # create a function to calcualte the density at a particular location
    kde = ss.gaussian_kde(data.T)

    # calculate the limits if there are no values passed in
    # passed in values are useful if calling this function
    # systematically with different sets of data whose limits
    # aren't consistent
    if xlim is None:
        xlim = (min(data[:,0]), max(data[:,0]))

    if ylim is None:
        ylim = (min(data[:,1]), max(data[:,1]))

    # create some tick marks that will be used to create a grid
    xs = np.linspace(xlim[0], xlim[1], resolution)
    ys = np.linspace(ylim[0], ylim[1], resolution)

    # wrap the KDE function and vectorize it so that we can call it on
    # the entire grid at once
    def calc_prob(x,y):
        return kde([x,y])[0]
    calc_prob = vectorize(calc_prob)

    # check if we've received a plotting surface
    if ax is None:
        fig = plt.figure(figsize=(6,6))
        ax = fig.add_subplot(1,1,1)

    # create the grid and calculate the density at each point
    X,Y = np.meshgrid(xs, ys)
    Z = calc_prob(X,Y) 

    # the values according to which the points should be colored
    point_values = kde(data.T)

    # plot the contour
    cont = ax.contour(X,Y,Z)
    #print cont
    ax.plot(data[:,0], data[:,1], 'o')

    return (None, None)

data_x = np.random.random((50,2))
cont = plot_2d_probsurface(data_x)

在下图中,密度最高的点将被着为棕色,接下来是橙色、黄色等。应该被标色的值已经在point_values中了。现在只需要将其转换成颜色,并传递给plot函数。但是如何像在contour图中那样对它们进行缩放呢?
1个回答

5
看起来很简单,只需将 plot 更改为 scatter 并将点值作为 c=point_values 参数传递即可:
import numpy as np
import scipy.stats as ss

def plot_2d_probsurface(data, resolution=20, ax = None, xlim=None, ylim=None):
    # create a function to calcualte the density at a particular location
    kde = ss.gaussian_kde(data.T)

    # calculate the limits if there are no values passed in
    # passed in values are useful if calling this function
    # systematically with different sets of data whose limits
    # aren't consistent
    if xlim is None:
        xlim = (min(data[:,0]), max(data[:,0]))

    if ylim is None:
        ylim = (min(data[:,1]), max(data[:,1]))

    # create some tick marks that will be used to create a grid
    xs = np.linspace(xlim[0], xlim[1], resolution)
    ys = np.linspace(ylim[0], ylim[1], resolution)

    # wrap the KDE function and vectorize it so that we can call it on
    # the entire grid at once
    def calc_prob(x,y):
        return kde([x,y])[0]
    calc_prob = vectorize(calc_prob)

    # check if we've received a plotting surface
    if ax is None:
        fig = plt.figure(figsize=(6,6))
        ax = fig.add_subplot(1,1,1)

    # create the grid and calculate the density at each point
    X,Y = np.meshgrid(xs, ys)
    Z = calc_prob(X,Y) 

    # plot the contour
    cont = ax.contour(X,Y,Z)
    point_values = kde(data.T)
    print point_values
    #print cont
    ax.scatter(data[:,0], data[:,1], c=point_values)

    return (None, None)

data_x = np.random.random((50,2))
cont = plot_2d_probsurface(data_x)

通过这个结果:

enter image description here


2
恭喜你自己解决了问题!顺便提一下:颜色不会完全匹配。轮廓的颜色被缩放到最小和最大轮廓,而散点图的颜色被缩放到数据的最小值和最大值。一个快速的解决方法是做类似于 cont = ax.contour(...) 然后 ax.scatter(x, y, c=z, cmap=cont.cmap, norm=cont.norm)。这将给出一个连续的,而不是离散的(如 contourf 所使用的)颜色映射,但缩放将是相同的。(如果你真的需要一个离散的颜色映射,请使用 plt.get_cmap("name", N)。) - Joe Kington
谢谢!这正是我所询问的。如果您想将其作为答案来表述,我会接受它,因为它是对我所提出问题更正确和精确的回答 :) - juniper-

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接