【问题标题】:How to modify the colormap of a scatter plot after it was drawn如何在绘制后修改散点图的颜色图
【发布时间】:2019-05-19 19:02:28
【问题描述】:

例如,您可以使用scatter(X, Y, c=..., cmap="rainbow") 将颜色图分配给散点图,但是以后有没有办法修改颜色图?

我知道我们可以通过set_color()set_alpha() 更改透明度和颜色,但我没有找到颜色映射的等价物。一种解决方法是保存散点图的数据,将其擦除,然后再次使用新参数scatter(),但这会很昂贵。这是一个问题,因为这个问题的目标是能够实时更改c 参数,以便旧点“冷却”到更深的颜色。

感谢您的宝贵时间。


编辑以添加更多信息:我希望能够在使用单一颜色的散点图和具有可变颜色图和标准化的散点图之间来回切换。例如,在scatter(X, Y, color="#FF0000")scatter(X, Y, c=age, cmap="rainbow") 之间,带有一个变量age = [i for i,x in enumerate(X)]

【问题讨论】:

  • 还有.set_cmap
  • 谢谢!我查看了scatter() 的文档,但没有考虑ScalarMappables。我假设使用set_cmap(None) 会使曲线使用其初始颜色?
  • 如果你有一个定义了c 参数的散点图,你一定需要一个颜色图。如果要使所有点变黑,可以将数组设置为所有相同的值(如果黑色在所选颜色图中),或者使用仅包含黑色的颜色图(默认值中没有,所以你需要通过ListedColormap 创建)。如果您想修改您的问题以询问实际问题,这里肯定会提供更多帮助。

标签: python-3.x matplotlib


【解决方案1】:

正如@ImportanceOfBeingErnest 所指出的,使用set_cmap() 似乎相当简单:

x = np.linspace(0,10,10)
y = x**2
c = np.linspace(-10,10,10)
cmap = "seismic"
norm = matplotlib.colors.Normalize(vmin=min(c),vmax=max(c))



from matplotlib.widgets import RadioButtons

fig, ax = plt.subplots()

scat = plt.scatter(x,y,c=c,cmap=cmap,norm=norm)
plt.colorbar()
scat.update_scalarmappable()
scat.set_facecolors('k')

plt.subplots_adjust(left=0.3)

axcolor = 'lightgoldenrodyellow'
rax = plt.axes([0.05, 0.7, 0.15, 0.15], facecolor=axcolor)
radio = RadioButtons(rax, ('no-cmap','cmap'))

def colorfunc(label):
    if label=="cmap":
        scat.set_cmap(cmap)
        scat.set_norm(norm)
    elif label=="no-cmap":
        scat.set_facecolors('k')
    else:
        raise KeyError("invalid label")
    plt.draw()
radio.on_clicked(colorfunc)

【讨论】:

  • 您好,感谢您的帮助。在这两者之间,我添加了一些关于我的问题的精确度。例如,我的初始绘图没有c 参数,而只有固定颜色,所以我缺少某种set_c()
  • 如果可能的话,我认为您最好使用颜色图创建散点图,然后立即将颜色更改为黑色。我已经修改了我的答案来说明这个案例
  • 抱歉回复缓慢,我正在尝试了解如何使我的代码适应您的解决方案或@ImportanceOfBeingErnest 的解决方案。有趣的是如何使用scat.set_facecolors('k') 而不必关心通过scat.set_cmap(None) 删除颜色图。你介意解释一下scat.update_scalarmappable() 的作用吗?
  • 查看@ImportanceOfBeingErnest 对我的回答的评论stackoverflow.com/a/53631526/1356000
【解决方案2】:

您实际上可以更改值,而不是更改颜色图。如果您为颜色图设置了under 颜色,则可以将值更改为低于标准的任何值并使其以该颜色显示。

当按下 n 时,以下会将值设置为比最小值小一。按下 m 后,它们会被设置回原来的值。

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(42)

a = np.random.randint(10,30, size=20)
x = np.random.rand(20)
y = np.random.rand(20)

cmap = plt.get_cmap("rainbow")
cmap.set_under("black")

fig, ax = plt.subplots()
ax.set_title("Press n and m keys to change colors")
sc = ax.scatter(x,y, c=a, cmap=cmap)

def change(evt):
    if evt.key in list("nm"):
        if evt.key == "n":
            sc.set_array(np.ones_like(a)*a.min()-1)
        if evt.key == "m":
            sc.set_array(a)
        fig.canvas.draw_idle()


fig.canvas.mpl_connect("key_press_event", change)

plt.show()

如果您确实需要从没有定义其数组的散点图开始,您可以如下所示进行。

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(42)

a = np.random.randint(10,30, size=20)
x = np.random.rand(20)
y = np.random.rand(20)

cmap = plt.get_cmap("rainbow")
cmap.set_under("black")
norm = plt.Normalize(a.min(), a.max())

fig, ax = plt.subplots()
ax.set_title("Press n and m keys to change colors")
sc = ax.scatter(x,y, color="black")

def change(evt):
    if evt.key in list("nm"):
        sc.set_cmap(cmap)
        sc.set_norm(norm)
        if evt.key == "n":
            sc.set_array(np.ones_like(a)*a.min()-1)
        if evt.key == "m":
            sc.set_array(a)
        fig.canvas.draw_idle()
        

fig.canvas.mpl_connect("key_press_event", change)

plt.show()

【讨论】:

  • 谢谢。因此,当您尝试达到标准化范围之外的颜色时,会使用底色。有趣的。您的回复和@Diziet Asahi 似乎暗示我们总是必须指定cmapc,即使我们稍后会忽略它们。我希望有一种方法可以避免这种情况,在肯定的情况下,我可以添加一个独立的方法来更改现有曲线的颜色图,在否定的情况下,我必须这样做,并在各处修改其他代码位以提供初始颜色图。
  • 好吧,正如另一个答案所示,您可以绕过数组并直接设置facecolors。我在答案中添加了一个选项,您从一个没有定义数组的散点开始。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 2023-02-18
  • 2021-12-13
  • 2010-11-26
相关资源
最近更新 更多