【问题标题】:How to select specific number of colors to show in color bar from a big list ? - Matplotlib如何从大列表中选择特定数量的颜色以显示在颜色栏中? - Matplotlib
【发布时间】:2021-03-04 21:30:24
【问题描述】:

我绘制了一些包含 70 个类的数据,所以当我构建颜色条时,很难区分每个图例,如下所示:

我使用的代码是:

formation_colors = # 70 colors
formation_labels = # 70 labels
data = # the section of the entire dataset which only has 13  labels


data = data.sort_values(by='DEPTH_MD')
ztop=data.DEPTH_MD.min(); zbot=data.DEPTH_MD.max() 

cmap_formations = colors.ListedColormap(formation_colors[0:len(formation_colors)], 'indexed')
cluster_f = np.repeat(np.expand_dims(data['Formations'].values,1), 100, 1)

fig = plt.figure(figsize=(2,10))
ax = fig.add_subplot()
im_f = ax.imshow(cluster_f, interpolation='none', aspect='auto', cmap = cmap_formations, vmin=0, vmax=69)   
ax.set_xlabel('FORMATION')
ax.set_xticklabels(['']);

divider_f = make_axes_locatable(ax)
cax_f = divider_f.append_axes("right", size="20%", pad=0.05)
cbar_f = plt.colorbar(im_f, cax = cax_f,)

cbar_f.set_ticks(range(0,len(formation_labels))); cbar_f.set_ticklabels(formation_labels)

到目前为止,如果我只是改变:

   1. cmap_formations = colors.ListedColormap(formation_colors[0:len(formation_colors)], 'indexed') 
   2. cbar_f.set_ticks(range(0,len(formation_labels))); cbar_f.set_ticklabels(formation_labels)

到:

cmap_formations = colors.ListedColormap(formation_colors[0:len(data['FORMATION'].unique())], 'indexed') 

cbar_f.set_ticks(range(0,len(data['FORMATION'].unique()))); cbar_f.set_ticklabels(data['FORMATION'].unique())

我明白了,cbar 中的相应颜色,但是情节不再正确,而且图例也不符合标准

非常感谢您知道如何执行此操作。

【问题讨论】:

    标签: python-3.x pandas matplotlib colorbar imshow


    【解决方案1】:

    虽然问题中没有明确提及,但我想data['FORMATION'] 包含从069formation_colorsformation_labels 列表中的索引

    主要问题是data['FORMATION'] 需要重新编号为新索引(编号为0 直到12)到新的唯一颜色列表中。 np.unique(..., return_inverse=True) 返回唯一编号列表和值的重新编号。

    为了能够重新索引颜色和标签列表,将它们转换为 numpy 数组会有所帮助。

    为使代码更易于调试,以下测试使用颜色列表和标签列表之间的简单关系。

    from matplotlib import pyplot as plt
    from matplotlib import colors
    from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
    import numpy as np
    import pandas as pd
    
    formation_colors = np.random.choice(list(colors.CSS4_COLORS), 70, replace=False)  # 70 random color names
    formation_labels = ['lbl_' + c for c in formation_colors]  # 70 labels
    formation_colors = np.asarray(formation_colors)
    formation_labels = np.asarray(formation_labels)
    
    f = np.random.randint(0, 70, 13)
    d = np.sort(np.random.randint(0, 5300, 13))
    data = pd.DataFrame({'FORMATION': np.repeat(f, np.diff(np.append(0, d))),
                         'DEPTH_MD': np.arange(d[-1])})
    data = data.sort_values(by='DEPTH_MD')
    
    ztop = data['DEPTH_MD'].min()
    zbot = data['DEPTH_MD'].max()
    
    unique_values, formation_new_values = np.unique(data['FORMATION'], return_inverse=True)
    cmap_formations = colors.ListedColormap(formation_colors[unique_values], 'indexed')
    cluster_f = formation_new_values.reshape(-1, 1)
    
    fig = plt.figure(figsize=(3, 10))
    ax = fig.add_subplot()
    im_f = ax.imshow(cluster_f, extent=[0, 1, zbot, ztop],
                     interpolation='none', aspect='auto', cmap=cmap_formations, vmin=0, vmax=len(unique_values)-1)
    ax.set_xlabel('FORMATION')
    ax.set_xticks([])
    
    divider_f = make_axes_locatable(ax)
    cax_f = divider_f.append_axes("right", size="20%", pad=0.05)
    cbar_f = plt.colorbar(im_f, cax=cax_f)
    
    cbar_f.set_ticks(np.linspace(0, len(unique_values)-1, 2*len(unique_values)+1)[1::2])
    cbar_f.set_ticklabels(formation_labels[unique_values])
    
    plt.subplots_adjust(left=0.2, right=0.5)
    plt.show()
    

    这是一个对比图:

    【讨论】:

    • 太棒了!谢谢@JohanC。
    猜你喜欢
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 2020-09-29
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多