Search code examples
pythondataframegeometrycolorbarscatter

Circle Plot with Color Bar


I'm trying to do a Circle Plot with a Color Bar, almost like this:

enter image description here

However, the minimum value of the colour bar is currently 1; I would like to be able to set it to 0.

import pandas            as pd
import matplotlib.pyplot as plt
import matplotlib.cm     as cm
from sklearn import preprocessing

df = pd.DataFrame({'A':[1,2,1,2,3,4,2,1,4], 
                   'B':[3,1,5,1,2,4,5,2,3], 
                   'C':[4,2,4,1,3,3,4,2,1]})

# set the Colour
x              = df.values
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled       = min_max_scaler.fit_transform(x)
df_S           = pd.DataFrame(x_scaled)
c1             = df['C']
c2             = df_S[2]
colors         = [cm.jet(color) for color in c2]

# Graph
plt.figure()
ax = plt.gca()
for a, b, color in zip(df['A'], df['B'], colors):
    circle = plt.Circle((a, 
                         b), 
                         1, # Size
                         color=color, 
                         lw=5, 
                         fill=False)
    ax.add_artist(circle)

plt.xlim([0,5])
plt.ylim([0,5])
plt.xlabel('A')
plt.ylabel('B')
ax.set_aspect(1.0)

sc = plt.scatter(df['A'], 
                 df['B'], 
                 s=0, 
                 c=c1, 
                 cmap='jet', 
                 facecolors='none')
plt.grid()

cbar = plt.colorbar(sc)
cbar.set_label('C', rotation=270, labelpad=10)

plt.show()

Credit to this original question: Plotting circles with no fill, colour & size depending on variables using scatter


Solution

  • Thanks to alec_djinn this answer does:

    • Set the min & max values of the colour bar
    • Control the colour of the circles (variable C) on the same range as the colour bar

    enter image description here

    import pandas            as pd
    import matplotlib.pyplot as plt
    import matplotlib.cm     as cm
    from sklearn import preprocessing
    from matplotlib.colors import Normalize
    
    df = pd.DataFrame({'A':[1,2,1,2,3,4,2,1,4], 
                       'B':[3,2,5,1,2,4,5,2,3], 
                       'C':[4,2,4,1,3,3,4,2,1]})
    
    # set the Colour
    x              = df[['C']].values
    min_max_scaler = preprocessing.MinMaxScaler()
    x_scaled       = min_max_scaler.fit_transform(x)
    df_S           = pd.DataFrame(x_scaled)
    c1             = df['C']
    c2             = df_S[0]
    cmap           = cm.jet # Use the same Cmap
    
    # Set the Colour Scale
    vmin = 0
    vmax = 5
    norm = Normalize(vmin, vmax)
    
    # Graph
    plt.figure()
    ax = plt.gca()
    for a, b, c in zip(df['A'], df['B'], df['C']):
        circle = plt.Circle((a, 
                             b), 
                             1, # Size
                             color=cmap(norm(c)), 
                             lw=5, 
                             fill=False)
        ax.add_artist(circle)
    plt.xlim([0,5])
    plt.ylim([0,5])
    plt.xlabel('A')
    plt.ylabel('B')
    ax.set_aspect(1.0)
    sc = plt.scatter(df['A'], 
                     df['B'], 
                     s=0, 
                     c=c1, 
                     cmap='jet', # Use the same Cmap
                     vmin = vmin,
                     vmax = vmax,
                     facecolors='none')
    plt.grid()
    cbar = plt.colorbar(sc)
    cbar.set_label('C', rotation=270, labelpad=20)
    
    plt.show()