Search code examples
pythonpandasnumpymatplotlibk-means

assigning a unique color to the plot of clusters in python


I have a dataframe that is divided into 27 clusters. in order to graph all these clusters in only a plot, I use the following for loop:

list_of_clusters= list(set(klabels))
    
fig=plt.figure(figsize=(13,9),frameon=True,facecolor='lightgrey', edgecolor='black')
    ax = fig.add_subplot(1,1,1)
    plt.axis()
    plt.xlim([-2.5, 0.2])
    plt.ylim([-0.7, 3.3])
    plt.xlabel("log PhiZ")
    plt.ylabel("log RQI")
    
    for i in list_of_clusters:
        
        plt.scatter(
        logphizlogrqi[klabels == i, 0], logphizlogrqi[klabels == i, 1],
        s=10, cmap='hsv',
        marker='8',
        label=i+1
        )
    
    
    
    ax.yaxis.tick_right()
    ax.yaxis.set_ticks_position('both')
    plt.legend(scatterpoints=1, loc='center left',bbox_to_anchor=(-0.4, 0.5))
    plt.grid()
    plt.show()

but the resulting graph uses each color more than once as you can see in the plot below:

Ideally, the graph I'm looking for should look like the following (although the colors are close to each other, they are used only once):

I'd really appreciate it if you could help me fixing my problem


Solution

  • so I came up with this method and it worked fine:

    from matplotlib import colors as mcolors
    import random
    
    list_of_clusters= list(set(klabels))
    
    colors = list(mcolors.CSS4_COLORS.keys())
    random.shuffle(colors)
    
    fig=plt.figure(figsize=(13,9),frameon=True,facecolor='lightgrey', edgecolor='black')
    ax = fig.add_subplot(1,1,1)
    plt.axis()
    plt.xlim([-2.5, 0.2])
    plt.ylim([-0.7, 3.3])
    plt.xlabel("log PhiZ")
    plt.ylabel("log RQI")
    
    for i in list_of_clusters:
        plt.scatter(
        logphizlogrqi[klabels == i, 0], logphizlogrqi[klabels == i, 1],
        s=10,
        marker='8',
        label=i+1,
        color=colors[i]
        )
    
    ax.yaxis.tick_right()
    ax.yaxis.set_label_position('right')
    ax.yaxis.set_ticks_position('right')
    plt.legend(scatterpoints=1, loc='center left',bbox_to_anchor=(-0.4, 0.5))
    plt.show()
    

    The result looks like below: