【问题标题】:Discrete pyplot scatter colobar离散 pyplot 散点图
【发布时间】:2016-01-08 00:53:05
【问题描述】:

我正在创建一个带有颜色条的散点图

plt.scatter(X, Y, c=Z)
plt.colorbar()
plt.show()
plt.close()

其中 X 和 Y 是浮点数组,Z 是整数数组。 即使 Z 是一个整数数组(此处为 1-14),颜色栏也会显示浮点数。

如何显示离散的颜色条 1-14?

我发现一些东西试图回答类似的问题here,但我不理解答案(包含一些使 0 变灰的复杂性)足以应用它。

【问题讨论】:

    标签: python matplotlib ipython-notebook


    【解决方案1】:

    查看the second answer 到您的链接问题。如果您在调用 scatter 之前离散化您的颜色图,它将自动按照您的意愿工作:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    
    n = 14
    X = np.random.rand(20)
    Y = np.random.rand(20)
    Z = np.random.randint(low=0,high=n,size=X.shape)
    
    plt.figure()
    plt.scatter(X,Y,c=Z,cmap=cm.hot)
    plt.colorbar()
    
    plt.figure()
    plt.scatter(X,Y,c=Z,cmap=cm.get_cmap('hot',n))
    plt.colorbar()
    

    比较结果:

    请注意,默认颜色图是jet。但直到viridis 加入starting from version 2.0 作为新的(和美妙的)默认值。

    如果困扰您的是颜色条上的数字是浮点数,您可以在其中手动设置ticks,而不考虑颜色的离散化:

    plt.figure()
    plt.scatter(X,Y,c=Z,cmap=cm.jet)
    plt.colorbar(ticks=np.unique(Z))
    #or
    #plt.colorbar(ticks=range(Z.min(),Z.max()+1))
    

    结果:

    请注意,由于我使用了一些随机生成的点,Z 中并非每个数字都存在,因此unique 可能不是最好的方法(请参见上图中缺少的刻度)。这就是为什么我还添加了一个基于min/max 的解决方案。您可以根据自己的实际应用定制限制。

    【讨论】:

    • 这似乎是我正在寻找的,但是我在plt.scatter(X, Y, c = Z, cmap=cm.get_cmap('RdPu',n), s=100, vmin=np.min(Z), vmax=np.max(Z)) 的尝试会产生错误NameError: name 'cm' is not defined,即使使用import matplotlib.cm as cm
    • @astromonerd 这是最不寻常的。您是否尝试过再次将其关闭?:) 您使用的是 ipython 还是只是一个常规的 python 脚本?上面的代码在前者中对我来说很好。无论如何,如果import 没有抛出任何错误,那么你不应该得到那个错误。
    • @astromonerd 哦,我相信scatter 的默认行为是使用vmin=np.min(c),vmax=np.max(c),因此您可以节省一些打字时间:)
    • 我错误标记(并更正了)我正在使用 ipython-notebook (v 3.0.0)
    • 我重新启动了要导入标头的内核,现在它可以工作了。关闭并再次打开它以获得胜利。
    【解决方案2】:

    这是我的土地利用类型的离散颜色条,看起来像你的工作,因为 Z 值也是 1-14 的整数数组。

    我的方法

    创建从here手动学习的颜色图和颜色条标签

    我的代码

    cMap = ListedColormap(['white', '#8dd3c7','#ffffb3','#bebada',  \               
                           '#b2182b','#80b1d3','#fdb462','#b3de69','#6a3d9a',\
                           '#b2df8a', '#1f78b4', '#ccebc5','#ffed6f'])
    
    ## If you want to use the colormap from plt.cm..., you can use(take 'jet' for example) 
    cMap = plt.cm.get_cmap("jet",lut=13)  
    
    ### here you can change your data in    
    lulc = plt.pcolormesh(lulc,cmap = cMap,alpha = 0.7)   
    
    z_range = np.linspace(1,14,14)
    list = z_range.astype('S10')
    
    k = -0.05
    for i in range(0,13,1):
        k = k + 1/13.0
       ax.annotate(list[i],xycoords='axes fraction',xy=(1.12,k),fontsize = 14, \
                   fontstyle = 'italic',zorder =3)
    
    cbar = plt.colorbar(lulc,ticks = [ ])
    for label in cbar.ax.yaxis.get_ticklabels()[::-1]:
        label.set_visible(False)    
    

    我的结果


    (来源:tietuku.com

    希望它能有所帮助!

    【讨论】: