Python Software - Tips
A collection of tips and code examples for analysis with Python. I did not invent them; typically I faced the problem in my work, searched the web and found hints or similar examples.
Use of lambda function to sort a dictionary
We can use a lambda function to apply functions like min, max, sorted, largeq to a dictionary using keys or its values - lambda functions
A good set of inliners for common tasks
Inliners can be used to perform common tasks in a very efficient and elegant way - inliners
A way to access dictionary elements with dot
A fast solution is to use SimpleNamespace. Here is an example
from types import SimpleNamespace
adict = {'one':1, 'two':2}
adotdict = SimpleNamespace(**adict)
print(adotdict.one)
Alternatives to doing loops in Python
Loops can be handy but also costly and slow if appied to large lists. Python offers three alternatives:
1. Map : map(function, iterable)
apply a function to the elements of the list. Returns a list of the same size.
2. Filter : filter(function, iterable)
apply a function to select elements from a list. Returns a reduced-size list depending on the selection
3. Reduce : reduce(function, iterable)
apply a function iteratively to all elements of the list. Returns a single value.
Examples
x = [1, 2, 3, 4 ,5]
y = map(lambda a : a**2, x)
list(y)
y = filter(lambda a: a>=3, x)
list(y)
y = reduce(lambda a, b: a+b, x)
Using dot notation to python dicts
In python a simple directory is defined as below:
mydict = {'x': [1,2], 'y': [3,4]}
mydict['x'] --> would return [1,2]
mydict['x'][0] --> would return [1]
from types import SimpleNamespace
d = dict(x=[1, 2], y=['a', 'b'])
nsd = SimpleNamespace(**d)
nsd # namespace(x=[1, 2], y=['a', 'b'])
nsd.x
nsd.x[0]
vars(nsd) # to convert back to a normal dictionary
Figures and plotting
Add a second x-scale in graph
fig, ax = plt.subplots(1,1, figsize=(15,8))
width = 1.0
xscale = dflist['ipslot']*b_h_dist
p1 = plt.bar(xscale, dflist['lrip1'], width,)
p2 = plt.bar(xscale, dflist['lrip2'], width, )
p3 = plt.bar(xscale, dflist['lrip5'], width, )
p4 = plt.bar(xscale, dflist['lrip8'], width, )
lrdf.groupby(['z-pos/m','ip']).count()['RFbucketbeam1'].unstack().plot(marker='o', ms=10.5, label='lpc', ax=ax)
plt.ylabel('Long-range encounters')
plt.xlabel('Distance from IP')
plt.title('LHC - Long-range encounters per IP for bunches colliding at IP1/IP5'.format(fno))
plt.legend((p1[0], p2[0], p3[0], p4[0]), ('IP1', 'IP2', 'IP5', 'IP8'))
plt.grid()
ax2 = ax.twiny()
xlow,xmax = ax1.get_xlim()
new_ticklocations = np.arange(int(xlow/b_h_dist),int(xmax/b_h_dist),5)
new_ticklabels = [str(i) for i in new_ticklocations]
ax2.set_xlim(int(xlow/b_h_dist),int(xmax/b_h_dist))
ax2.set_xticks(new_ticklocations)
ax2.set_xticklabels(new_ticklabels)
ax2.xaxis.set_ticks_position('default')
ax2.xaxis.set_label_position('bottom')
ax2.spines['bottom'].set_position(('outward', 36))
ax2.set_xlabel('Distance from IP [m]')
plt.show()
pltsave(fig,'LRencounters.pdf')
Subplots axis array as simple list
In figures with multiple subplots can be created with the command fig,axes = plt.subplots(nrows=2, ncols=2)
. However this returns a 2D array if ncols or nrows is specified, otherwise an 1D array - single graph. However we oftern need to access the subplots in iteration thorugh a signle list, here is how:
fig, axes = plt.subplots(nrows=2, ncols=2, squeeze=False)
axlist = axes.flatten()
squeeze
option forces plt.subplots to always return a 2D numpy array, which is then converted to an 1D array.
A good tutorial for matplotlib scientific plotting and references therein.