Search code examples
pythonmatplotlibastronomy

How to set markeredgecolor to a color map based off of a pandas DataFrame


I want to make a scatter plot with two different sets of data from a DataFrame, where one has filled circle markers and the other with hollow circle markers, but both color coded by another column in the DataFrame. The code I have for this plot is:

    plt.figure(figsize = (10,10))
    plt.rcParams.update({'font.size': 30})
    plt.errorbar(fullmergedf['ir_SFR-UV_corr'] , fullmergedf['PAB_L'] , yerr = fullmergedf['PAB_L_ERR']  , linestyle = 'None' , c = 'grey' )
    plt.scatter(fullmergedf['ir_SFR-UV_corr'] , fullmergedf['PAB_L'] , s = 200 , c = fullmergedf['td_lmass'], cmap = 'coolwarm')
    plt.scatter(fullmergedf['ir_SFR-ladder_total'] , fullmergedf['PAB_L'] , s = 200 , c = fullmergedf['td_lmass'], cmap = 'coolwarm' , markerfacecolor = 'none')
    cb = plt.colorbar()
    cb.set_label('Log$[M_{\odot}]$')
    plt.ylabel("PaB L [erg/s]")
    plt.xlabel("UV + IR Ladder-SFR [$M_{\odot}/yr$]")
    plt.axis([min(fullmergedf['ir_SFR-ladder_total']) -10**-6 , max(fullmergedf['ir_SFR-ladder_total']) + 10**2 , min(fullmergedf['PAB_L']) - 10**36, max(fullmergedf['PAB_L'])  + 10**41])
    plt.xscale('log')
    plt.yscale('log')
    plt.show()

I have tried to change the c = fullmergedf['td_lmass'] in the second plt.scatter() to markeredgecolor = fullmergedf['td_lmass'], but this does not work. None of the solutions I have seen have done hollow markers with a colorbar.


Solution

  • You can first create the scatter plot the normal way, and afterwards set the facecolor to 'none':

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.scatter(np.random.rand(10), np.random.rand(10), s=200, c=np.linspace(0, 1, 10), cmap='Reds')
    scatterdots = plt.scatter(np.random.rand(10), np.random.rand(10), s=200, c=np.linspace(0, 1, 10), cmap='Greens', lw=3)
    scatterdots.set_facecolor('none')
    plt.show()
    

    resulting plot

    In the code of the question, it would be something like:

    scatterdots = plt.scatter(fullmergedf['ir_SFR-ladder_total'], fullmergedf['PAB_L'], s=200, c=fullmergedf['td_lmass'], cmap='coolwarm')
    scatterdots.set_facecolor('none')