Search code examples
pythonpandasmatplotlibscatter-plottransparency

How to create a scatter plot with normalized marker transparencies


I have this dataframe :

import pandas as pd
import matplotlib.pyplot as plt

rng = np.random.default_rng(seed=111)
rints = rng.integers(low=0, high=1000, size=(5,5))
df = pd.DataFrame(rints)

     0    1    2    3    4
0  474  153  723  169  713
1  505  364  658  854  767
2  718  109  141  797  463
3  968  130  246  495  197
4  450  338   83  715  787

And I'm trying to plot it as it is and set the size of markers and their transparency :

ox = np.arange(len(df))
x = np.tile(ox[:, np.newaxis], (1, len(ox)))
y = np.tile(ox, (len(df), 1))

plt.scatter(x, y, marker='o', color='tab:orange', ec='k', ls='--', s=df.values)

for ix,iy,v in zip(x.ravel(), y.ravel(), df.values.ravel()):
    plt.annotate(str(v), (ix,iy), textcoords='offset points', xytext=(0,10), ha='center')
        
plt.axis("off")
plt.margins(y=0.2)
plt.show()

Only two problems :

  1. The plot doesn't reflect the real dataframe shape, i feel like it is transposed
  2. i don't know how to adjust the transparency of the scatter points as I did with the size
    • Just proportional to the value of the cell (like I did with size). Light color for lower values and strong color for higher ones.

enter image description here


Solution

  • To avoid transposition, correctly map x and y (here using numpy.meshgrid), and use the alpha parameter of scatter (matplotlib ≥ 3.4):

    # inverting df to have the same row order
    df2 = df[::-1]
    
    # computing meshgrid
    x, y = np.meshgrid(range(df.shape[0]), range(df.shape[1]))
    
    # plotting
    plt.scatter(x, y, marker='o', color='tab:orange', ec='k', ls='--',
                s=df2, alpha=df2.div(np.max(df2)))
    
    for ix,iy,v in zip(x.ravel(), y.ravel(), df2.to_numpy().ravel()):
        plt.annotate(str(v), (ix,iy), textcoords='offset points',
                     xytext=(0,10), ha='center')
            
    plt.axis("off")
    plt.margins(y=0.2)
    plt.show()
    

    Output:

    enter image description here