python continued / matplotlib¶

9/13/2022¶

print view

In [1]:
%%html

<script src="http://bits.csb.pitt.edu/asker.js/lib/asker.js"></script>

<script>

require(['https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.js'], function(Ch){
 Chart = Ch;
});

$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');


//the callback is provided a canvas object and data 
var chartmaker = function(canvas, labels, data) {
  var ctx = $(canvas).get(0).getContext("2d");
     var dataset = {labels: labels,                     
    datasets:[{
     data: data,
     backgroundColor: "rgba(150,64,150,0.5)",
         fillColor: "rgba(150,64,150,0.8)",    
  }]};
  var myBarChart = new Chart(ctx,{type:'bar',data:dataset,options:{legend: {display:false}}});

};

$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>
In [2]:
%%html

<div id="assign2" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#assign2';
	jQuery(divid).asker({
	    id: divid,
	    question: "What do you think of pysb?",
		answers: ['Awesome','Okay','Demon spawn'],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Conditionals and Control Flow¶

if statements¶

  • An if statement conditionally executes a block of code
    • The condition is some Boolean value
    • A block of code is delineated by consistent indentation.
    • Blank lines and comments will not end a block
    • Whitespace is significant - do not mix tabs and spaces
  • In an if..elif..else statement, only one block of code will be executed
In [3]:
if False:
    print(1)
elif True:
    print(2)
else:
    print(3)
2
In [4]:
val = 0
if val >= 0:
    val += 1
elif val < 1:
    val += 2
elif True:
    val += 3
else:
    val += 5
    
    val += 7
In [5]:
%%html
<div id="if1" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#if1';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the value of val?",
		answers: ["1","4","6","8","11","16"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

pass¶

pass does nothing

In [6]:
if True:
    pass
else:
    print("I will never print")

Logical Operators¶

  • and, or, and not
  • not has higher precedence than and which has higher precedence than or
    • all three have lower precedence than comparison operators
    • but use parentheses to avoid confusion
In [7]:
%%html
<div id="logic1" style="width: 600px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#logic1';
	jQuery(divid).asker({
	    id: divid,
	    question: "Which of the following is equivalent to <tt>not (x and y)</tt>",
		answers: ["<tt>not x and not y</tt>","<tt>not x and y</tt>","<tt>x or y</tt>","<tt>not x or not y</tt>"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>
In [8]:
x = 3; y = 4; z = 5
val = x != 3 or not y < 0 and z < 10 or not y == 0 and z < 0
In [9]:
%%html
<div id="cond1" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#cond1';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the value of val?",
		answers: ["True","False"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Membership testing¶

in and not in can be used to see if an object is in a collection

In [10]:
l = [1,2,3]
In [11]:
1 in l
Out[11]:
True
In [12]:
345 in l
Out[12]:
False
In [13]:
"1" not in l
Out[13]:
True
In [14]:
"good" in "goodness"
Out[14]:
True
In [15]:
val = 'cat' in 'catalog'
In [16]:
%%html
<div id="catin" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#catin';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is val?",
		answers: ["True","False","None"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>
In [17]:
val = 'cat' in ['catalog','catastrophe']
In [18]:
%%html
<div id="catin2" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#catin2';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is val?",
		answers: ["True","False","None"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Loops¶

In [19]:
i = 0
while i < 3: #as long as this condition is true...
    print(i) #...execute this block of code
    i += 1   
0
1
2
In [20]:
letters = ['a','b','c','d','e','f','g']
for i in letters: #for every item in this collection...
    print(i) #...execute this block of code with i set to the object
a
b
c
d
e
f
g

range¶

The preferred method of looping is to use a for loop. There are a number of builtin functions to help create collections to iterate over.

In [21]:
list(range(3))
Out[21]:
[0, 1, 2]
In [22]:
list(range(1,10))
Out[22]:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
In [23]:
list(range(1,10,3))
Out[23]:
[1, 4, 7]
In [24]:
val = 0
for i in range(100):
    val += i
In [25]:
%%html
<div id="summer" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#summer';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the value of val?",
		answers: ["0","99","100","101","4950","5050"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Iterable¶

for will loop over any iterable object

In addition to collections, this includes any object that can provide items one at a time

  • Most importantly files
In [26]:
f = open("brca1.fasta")
cnt = 0
for line in f.readlines():
    cnt += len(line)
cnt
Out[26]:
2005
In [27]:
f = open("brca1.fasta")
cnt = 0
for line in f:  #essentially equivalent to readlines, but better - why?
    cnt += len(line)
cnt
Out[27]:
2005

break and continue¶

break will exit out of the entire loop while continue will skip to the next iteration

In [28]:
i = 0
while True:
    i += 1
    if i < 6:
        continue
    print(i)
    if i > 4:
        break
6
In [29]:
x = 0
while x < 100:
    if x < 50:
        pass
    elif x == 5:
        break
    x += 1
In [30]:
%%html
<div id="breakq" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#breakq';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the value of x?",
		answers: ["5","50","100","101","Nothing"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

Slicing¶

What if you don't want to iterate over the full list?

In [31]:
s = "Hello"
s[0:2]
Out[31]:
'He'
In [32]:
s[2:] # empty indices indicate remainder of string/list
Out[32]:
'llo'
In [33]:
s[:-2] #negative indices count from the back
Out[33]:
'Hel'
In [34]:
s2 = "Hello, world"
s2[:-2]
Out[34]:
'Hello, wor'
In [35]:
l = ["cat","dog","fish","mouse"]
val = len(l[2:3])
In [36]:
%%html
<div id="slicer" style="width: 500px"></div>
<script>
$('head').append('<link rel="stylesheet" href="http://bits.csb.pitt.edu/asker.js/themes/asker.default.css" />');

    var divid = '#slicer';
	jQuery(divid).asker({
	    id: divid,
	    question: "What is the value of val?",
		answers: ["0","1","2","3","4","5"],
        server: "http://bits.csb.pitt.edu/asker.js/example/asker.cgi",
		charter: chartmaker})
    
$(".jp-InputArea .o:contains(html)").closest('.jp-InputArea').hide();


</script>

matplotlib¶

make easy things easy and hard things possible¶

In [37]:
import matplotlib.pyplot as plt
# next is a python notebook command to embed plot output in the notebook
%matplotlib inline 

plt has hundreds of functions for creating and manipulating plots

plt.plot creates line/point graphs

  • you can specify an arbitrary number of x,y,format arguments
In [38]:
plt.plot([0,1,2,3],[0,1,2,3],"-b",[0,1,2,3],[0,1,4,9],"--r")
plt.ylabel("Y")
plt.xlabel("X")
plt.show() #not actually necessary in notebook

matplotlib is stateful¶

In [39]:
plt.plot([1,2,4,9,16],label="one") #if only one data set is provide, assume uniform x
plt.plot([0.5,1,2,4.5,8],'^-.',label="two") #keep adding to current graph until show is called
plt.legend() #uses labels
plt.show()
In [40]:
plt.show() # this doesn't show anything since we haven't created another plot
plt.close() #another way to finish with a plot

If you use the %matplotlib command in ipython, the plot will be updated with every command (can skip show)

Format codes¶

marker  description
”.” point
”,” pixel
“o” circle
“v” triangle_down
“^” triangle_up
“<” triangle_left
“>” triangle_right
“1” tri_down
“2” tri_up
“3” tri_left
“4” tri_right
“8” octagon
“s” square
“p” pentagon
“*” star
“h” hexagon1
“H” hexagon2
“+” plus
“x” x
“D” diamond
“d” thin_diamond
“|” vline
“_” hline

Colors¶

    'b'         blue
    'g'         green
    'r'         red
    'c'         cyan
    'm'         magenta
    'y'         yellow
    'k'         black
    'w'         white

Can also specify colors with full names or hexadecimal

In [41]:
plt.plot([1,2,4,6,7,4,2,2],'orange',linewidth=6)
plt.show()

Plotting expression data¶

In [42]:
#https://asinansaglam.github.io/python_bio_2022/files/Spellman.csv
f = open('../files/Spellman.csv')
header = f.readline().rstrip().split(',')#rstrip removes newline
data = []
for line in f:
    data.append(line.rstrip().split(','))
len(data)
Out[42]:
4381
In [43]:
for row in data[:10]: #first 10 only
    values = list(map(float, row[1:]))
    times = list(map(int, header[1:]))
    plt.plot(times,values,label=row[0])
plt.legend(loc='upper center',ncol=5,prop={'size':7})
plt.xlabel("Time")
Out[43]:
Text(0.5, 0, 'Time')

Data conversion...

In [44]:
for i in range(1,len(header)):
    header[i] = int(header[i])
    for r in range(len(data)):
        data[r][i] = float(data[r][i])

Bar charts¶

In [45]:
plt.bar([1.1,2.1,3.1],[30,40,50],0.5,yerr=[2,10,12],ecolor="black",alpha=0.5,label="One")
plt.bar([1.4,2.4,3.4],[60,50,20],0.5,color='r',yerr=[10,4,1],ecolor="black",alpha=0.5,label="Two")
plt.xticks([1.4,2.4,3.4], ['A','B','C'])
plt.ylim([0,100])
plt.legend();

Histograms¶

In [46]:
import random
rdata = []
for i in range(1000):
    rdata.append(random.normalvariate(0,1))
    
plt.hist(rdata,10);

Combining chart types¶

Just accumulate plots

In [47]:
plt.hist(rdata,10)
plt.plot([-3,-1,0,1,2,3],[20,30,50,60,80,90],'-r',linewidth=3)
plt.show()

Terminology¶

Figure¶

The full canvas you are creating your plot(s) on.

Axes¶

A single plot

Multiple Plots on a Figure¶

subplots(nrows,ncols)

In [48]:
fig, axes = plt.subplots(2,1)
plt.sca(axes[0]) #set current axis to first
plt.plot(header[1:],data[0][1:])
plt.ylabel(data[0][0])

plt.sca(axes[1])
plt.plot(header[1:],data[1][1:],'g')
plt.ylabel(data[1][0])
plt.show()

See also GridSpec

Multiple Plots on a Figure¶

In [49]:
numgenes = 3
fig, axes = plt.subplots(numgenes,1,sharex=True,sharey=True)
colors = ['b','g','purple']
for i in range(numgenes):
    #most plot methods have equivalents on axes objects
    axes[i].plot(header[1:],data[i][1:],color=colors[i])
    axes[i].set_ylabel(data[i][0])

Exporting charts¶

Instead of plt.show use plt.savefig

bbox_inches='tight' tells matplotlib to try harder to fit everything nicely.

In [50]:
plt.axes(aspect=1)
plt.pie([8,2,1],labels=["Novice","Beginner","Proficient"])
plt.savefig("pie.png",bbox_inches='tight')
In [51]:
ls *png
linux.png  pie.png

Other formats: pdf, svg, eps...

Other chart types¶

Gallery

Seaborn¶

Making (some) hard things easy

Gallery

Project¶

https://asinansaglam.github.io/python_bio_2022/files/Spellman.csv

  • plot a gene
  • plot the histogram of initial expression levels
  • plot the histogram of final expression levels
  • plot the above histograms on the same plot with transparent fill
  • plot the above with identical bin sizes for both histograms
  • plot the above histograms on different subplots, vertically stacked
In [52]:
f = open('../files/Spellman.csv')
header = f.readline().rstrip().split(',')#rstrip removes newline
data = []
for line in f:
    data.append(line.rstrip().split(','))

for i in range(1,len(header)):
    header[i] = int(header[i])
    for r in range(len(data)):
        data[r][i] = float(data[r][i])
In [53]:
first = [row[1] for row in data]
In [54]:
#plot a gene
def plot_gene(genenum):
    plt.figure()
    plt.plot(header[1:],data[genenum][1:])
    plt.title(data[genenum][0])
plot_gene(3)
plot_gene(4)
In [55]:
plt.hist(first);
In [56]:
last = [row[-1] for row in data]
plt.hist(last);
In [57]:
plt.hist(first,alpha=.5);
plt.hist(last,alpha=.5);
In [58]:
bins = [-3,-2.5,-2,-1.5,-1,-.5,0,.5,1,1.5,2,2.5,3] #np.linspace would be nicer
plt.hist(first,alpha=.5,bins=bins);
plt.hist(last,alpha=.5,bins=bins);
In [59]:
import numpy as np
bins = np.linspace(-3,3,100)
fig,axes = plt.subplots(2,1,sharex=True,sharey=True)
axes[0].hist(first,alpha=.5,bins=bins);
axes[1].hist(last,alpha=.5,bins=bins,color='orange');