I have a the following dataframe
import pandas as pd
import matplotlib.pyplot as plt
datas = [['RAC1','CD0287',1.52,9.88], ['RAC1','CD0695',2.08,10.05],['RAC1','CD0845',2.01,10.2], ['RAC3','CD0258',1.91,9.8], ['RAC3','CD471',1.66,9.6], ['RAC8','CD0558',1.32,9.3], ['RAC8','CD0968',2.89,10.01]]
labels = ['Plate', 'Sample', 'LogRatio', 'Strength']
df = pd.DataFrame(data = datas, columns=labels, index=[8, 3, 5, 4, 12, 44, 2])
print(df)
Plate Sample LogRatio Strength
8 RAC1 CD0287 1.52 9.88
3 RAC1 CD0695 2.08 10.05
5 RAC1 CD0845 2.01 10.20
4 RAC3 CD0258 1.91 9.80
12 RAC3 CD471 1.66 9.60
44 RAC8 CD0558 1.32 9.30
2 RAC8 CD0968 2.89 10.01
As you can see, my data are distributed on different plates. I would like to create as many plot as I have different plates : 3 plots. And on each plot, I would like to color one plate in red and the others in black.
The only way I found so far, is to do it manually by writing the code for each plate, and change the red plate for earch run (I have more than 30 plates in reality so it takes too many time). I can still show you my code if it can help you to understand:
def getIndexPlates(df):
listIndicesAllPlates = []
df = df.reset_index()
for name,group in df.groupby("Plate"):
temp_list = []
temp_list.append(name)
temp_list.append(group.index.tolist()) #create a tuple with the name of the plate and the index of all the samples in this plate
listIndexAllPlates.append(temp_list)
return listIndexAllPlates
def plotting(df,listIndexAllPlates):
plt.clf()
ax=plt.gca()
datas = df[["LogRatio", "Strength"]].as_matrix()
for sample in range(len(datas)):
if sample in listIndexAllPlates[0][1]: #if the sample is on the the first tuple of my list -> on the first plate
ax.scatter(datas[sample,0], datas[sample,1], alpha=0.8, facecolors='none', edgecolors='red')
if sample in listIndexAllPlates[1][1]:
ax.scatter(datas[sample,0], datas[sample,1], alpha=0.8, facecolors='none', edgecolors='black')
if sample in listIndexAllPlates[2][1]:
ax.scatter(datas[sample,0], datas[sample,1], alpha=0.8, facecolors='none', edgecolors='black')
plt.show()
listIndexAllPlates = getIndexPlates(df)
plotting(df,listIndexAllPlates)
So here I have my first plot with the plate 'RAC1' in red and RAC3 and RAC8 in black, and now I would like to have the second plot with RAC3 in red (RAC1 and RAC8 in black) and the third plot with RAC8 in red (RAC1 and RAC3 in black). To do so I manually change the color in my function but I would like a solution to do it automatically. And I know my way is really a bad and ugly way, I just don't know how to do it.
You can use groupby here in conjunction with difference of the pandas Index object to loop through your plates and get the indices for the current plate and the rest of them:
for label, plate_df in df.groupby("Plate"):
plate_indices = plate_df.index
rest_indices = df.index.difference(plate_indices)
# do your plotting here accordingly
print(label, plate_indices, rest_indices)
RAC1 Int64Index([8, 3, 5], dtype='int64') Int64Index([2, 4, 12, 44], dtype='int64')
RAC3 Int64Index([4, 12], dtype='int64') Int64Index([2, 3, 5, 8, 44], dtype='int64')
RAC8 Int64Index([44, 2], dtype='int64') Int64Index([3, 4, 5, 8, 12], dtype='int64')
To include the plotting, just include your matplotlib statements:
plot_kwargs = {"alpha": 0.8, "facecolors": "none"}
for label, plate_df in df.groupby("Plate"):
plate_indices = plate_df.index
rest_indices = df.index.difference(plate_indices)
# create plot
plt.clf()
ax=plt.gca()
ax.scatter(df.loc[plate_indices, "LogRatio"], df.loc[plate_indices, "Strength"], edgecolors='red', **plot_kwargs)
ax.scatter(df.loc[rest_indices, "LogRatio"], df.loc[rest_indices, "Strength"], edgecolors='black', **plot_kwargs)
plt.show()

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With