Search code examples
pythonpandasmatplotlibdata-processing

Is there a way to plot columns with the same name as the same colour?


I am attempting to plot one dataset which has many columns with the same name. I was trying to reuse a plotting program I made earlier, but the issue is that it plots each column in a different colour, instead I would like each column with the same name to be the same colour. Furthermore, it adds each column to the legend causing a lot of mess in the figure which I have attached. Is there a way to just put one label per colour? Any help to fix these issues would be greatly appreciated!

Here is an example plot As you can see instead of plotting both "O" as one colour, it plots it as two since there are two columns of data, and created a duplicate in the legend.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

s = pd.read_csv('Edit_This.csv') # reads the .csv file can be found in dropbox > shared manuscripts > Ravi Ben MoOx Nucleation and LEIS > Figures

xmin = 0 # Change these bounds as needed
xmax = 1
ymin = 0
ymax = 2500

y_axis_columns = s.columns[1:] # Reads column data to plot y values from index 1 onwards

for col_name in y_axis_columns: # Loop to plot all columns until it finds an empty one
   plt.plot(s.depth,s[col_name], label=col_name)
   plt.tight_layout()
   from matplotlib.ticker import MaxNLocator
   axes = plt.gca()
   axes.yaxis.set_major_locator(MaxNLocator(integer=True))
   axes.set_xlim([xmin,xmax])
   axes.set_ylim(ymin,ymax)
   plt.xlabel('Depth (nm)', fontsize=12) # Edit as needed
   plt.ylabel('Intensity (counts/nC)', fontsize=12) 
   plt.legend(loc='upper center', fontsize=10) # Defines legend formatting
   plt.savefig("6_Sputter1_5-222cyc_SiOx.png", dpi = 1200) # Edit export file name and DPI here
plt.show()

You can download the data from this link


Solution

  • Ok, the problem emerges because you have multiple columns with the same name. So, you need to handle that. The following code does so:

    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib.lines import Line2D
    
    s = pd.read_csv('Edit_This.csv') # reads the .csv file can be found in dropbox > shared manuscripts > Ravi Ben MoOx Nucleation and LEIS > Figures
    
    xmin = 0 # Change these bounds as needed
    xmax = 1
    ymin = 0
    ymax = 2500
    
    y_axis_columns = s.columns[1:] # Reads column data to plot y values from index 1 onwards
    
    
    # this is the color dictionary
    colors = {"O": 'r', "Mo": 'b', 'Al':'g'}
    
    for col_name in y_axis_columns: # Loop to plot all columns until it finds an empty one
       plt.plot(s.depth,s[col_name], label=col_name, color=colors[col_name.split('.')[0]])
       plt.tight_layout()
       from matplotlib.ticker import MaxNLocator
       axes = plt.gca()
    
    axes.yaxis.set_major_locator(MaxNLocator(integer=True))
    axes.set_xlim([xmin,xmax])
    axes.set_ylim(ymin,ymax)
    plt.xlabel('Depth (nm)', fontsize=12) # Edit as needed
    plt.ylabel('Intensity (counts/nC)', fontsize=12) 
    
    # Defines legend formatting
    custom_lines = [Line2D([0], [0], color='r', lw=4),
                    Line2D([0], [0], color='b', lw=4),
                    Line2D([0], [0], color='g', lw=4)]
    plt.legend(custom_lines, ['O', 'Mo', 'Al'], loc='upper center', fontsize=10)
    
    plt.savefig("6_Sputter1_5-222cyc_SiOx.png", dpi = 1200) # Edit export file name and DPI here
    plt.show()
    

    Which produces the following image: enter image description here