A Python script: From a microplate reader dose-response Excel file to a vectorial graph

This Python script takes as input the dose-response Excel file from your microplate reader and, in a fraction of a second, produces a dose-response curve in vectorial format (editable and scalable). It is just a template. It needs to be hacked to adapt it to the particular format produced by your device. I am the author and it is released under a GPL3 licence.

 

 

 

 

import os
import re
import glob
import xlrd
import csv
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
import scipy.optimize

# convert all MS Excel files in the working directory to CSV

def csv_from_excel():
for efile in glob.glob(‘*.xlsx’):
wb = xlrd.open_workbook(efile)
sh = wb.sheet_by_name(‘Sheet1’)
csv_file = open((os.path.splitext(efile)[0]) + “.csv”, ‘wb’)
wr = csv.writer(csv_file, quoting=csv.QUOTE_ALL)

for rownum in xrange(sh.nrows):
wr.writerow(sh.row_values(rownum))
csv_file.close()

csv_from_excel()

# calculate -pM, emission ratio averages, and standard deviations

def basic_arith():
for sfile in glob.glob(‘*.csv’):
df2 = pd.read_csv(sfile, header=None)
averag = df2.iloc[:,3:7].mean(axis=1)
stand = df2.iloc[:,3:7].std(axis=1)
pM = (-1 * np.log10(df2.iloc[:,8] * math.pow(10,-6)))
df2 = pd.concat([df2, stand, pM, averag], axis=1)
df2.to_csv(sfile, header=False, index=False)

basic_arith()

# split all CSV files according to the letter on the first column (microplate row)

def split_csv():
for dfile in glob.glob(‘*.csv’):
df = pd.read_csv(dfile, header=None)
for letter, group in df.groupby(df[0].str[0]):
group.to_csv((os.path.splitext(dfile)[0]) + ‘_{}.csv’.format(letter), index=False, header=False)

split_csv()

# fit the data to a (simetric sigmoid) function, compute the IC50/EC50, and plot the curve

def sigmoid(p,x):
x0,y0,c,k=p
y = c / (1 + np.exp(-k*(x-x0))) + y0
return y

def residuals(p,x,y):
return y – sigmoid(p,x)

def sig_plot():
for ffile in os.listdir(‘.’):
if re.match(r’.+_[A-Z][.]csv’, ffile):
df3 = pd.read_csv(ffile, header=None)
x = (df3.iloc[:,10].values * -1 )
y = (df3.iloc[:,11].values / 10000)
e = (df3.iloc[:,9].values / 10000)
first3 = np.average(y[:3])
last3 = np.average(y[-3:])
p_guess=(np.median(x),np.median(y),5,0.5)
p, cov, infodict, mesg, ier = scipy.optimize.leastsq(residuals,p_guess,args=(x,y),full_output=1)
x0,y0,c,k=p

XC50 = (math.pow(10,x0) * math.pow(10,6))
if first3 > last3:
EC50 = (“EC50 = %.3f microM” % XC50)
else:
EC50 = (“IC50 = %.3f microM” % XC50)
xp = np.linspace(-9, -3, 1500)
pxp=sigmoid(p,xp)

plt.ioff()
plt.plot(x, y, ‘.’, xp, pxp, ‘-‘)
plt.errorbar(x,y,yerr=e, linestyle=’None’, color=’blue’)
plt.xlabel(‘p[M]’, position=(1., 0.), va=’bottom’, ha=’right’, labelpad=15)
plt.ylabel(‘TR-FRET\nEmission\nRatio’,rotation=’horizontal’, position=(0., 1.), va=’top’, ha=’left’, labelpad=60)
plt.title(ffile.split(‘.’)[0], y=1.02, fontweight=’bold’)
plt.figtext(0.85, 0.95, EC50, wrap=True, horizontalalignment=’center’, fontsize=12, color=’green’)
plt.grid(True)
plt.tight_layout()
plt.savefig(ffile.split(‘.’)[0] + ‘.svg’)
plt.close()

sig_plot()



Comments are closed.