<jupyter_start><jupyter_text>E164: Introduction to Biological System Design Introduction to Biological Data Analysis Ayush PandeyIf you have not setup your computer to run this notebook, make sure to follow steps here: https://docs.google.com/document/d/1js7XQbjorU5LCIoWfrzkUCXjjQkVcITkT0N8osiy4Go/edit?usp=sharingThe purpose of this interactive Python notebook is to introduce basic data analysis tools available in Python with the help of biological data examples.If you have installed numpy, scipy, matplotlib, and pandas already, then you are all set to run this notebook.  Data Analysis with Python Introduction to PandasYou can think of Pandas as the Python data-management library. It can be used to manage large quantities of data in a structured way so you don't get lost and provides functions to retreive/store/edit your data so that it is easily interfaced with numerical, scientific, and plotting libraries.More information on Pandas here: https://pandas.pydata.org/pandas-docs/stable/Data is often stored as .csv files. Here's how to import a CSV file with Pandas and structure the data as desired.<jupyter_code>import pandas as pd

url = 'https://raw.githubusercontent.com/biocircuits/bioscrape/master/inference%20examples/data/od_data.csv'
# To import a CSV file, you can use the `read_csv` function. 
# Either provide a URL as its input or a string of address to the CSV file on your local machine.
df = pd.read_csv(url)
# You get a "dataframe" object out that contains all of the data in the CSV file<jupyter_output><empty_output><jupyter_text>In an IPYNB (like this one), the Pandas dataframes are nicely formatted:<jupyter_code>df<jupyter_output><empty_output><jupyter_text>Accessing the dataframe in arrays:<jupyter_code>import numpy as np
time_array = np.array(df['t'])
# Here's the time in minutes from the dataset:
time_array<jupyter_output><empty_output><jupyter_text>Plotting dataframe using matplotlib:<jupyter_code>import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# Plot the data for the container A1 against time:
# Convert time to hours and "A1" density data to cell counts.
ax.plot(df['t']/60, df['A1']*1e8, lw = 2)
ax.set_xlabel('Time (in hours)', fontsize = 18)
ax.set_ylabel('Bacteria Population', fontsize = 18)
ax.tick_params(labelsize = 18)<jupyter_output><empty_output><jupyter_text>Now plot all data together:<jupyter_code>fig, ax = plt.subplots()
for column_title in df:
    # the first two columns are not data, they are time columns, so we ignore those:
    if column_title == 't' or column_title == "Time":
        # Skip this and continue to iterate
        continue
    ax.plot(df['t']/60, df[column_title]*1e8, alpha = 0.7, lw = 2, label = column_title)
ax.set_xlabel('Time (in hours)', fontsize = 18)
ax.set_ylabel('Bacteria Population', fontsize = 18)
ax.tick_params(labelsize = 14)
# bbox_to_anchor command  is used to set the position of the legend box
ax.legend(fontsize = 12, bbox_to_anchor = (1.05,1.1), loc = "best");<jupyter_output><empty_output><jupyter_text>Manually fit logistic growth to the OD data<jupyter_code>import numpy as np
def logistic_growth(t, x, k, C):
    return k*x*(1 - x/C)

timepoints = np.array(df['t']/60) # time array in hours
from my_numerical_integrators import integrate

# x(t+ dt) = x(t) + f(x,t)*dt

x0 = np.mean(df.iloc[0][2:])*1e8 # Initial condition = Get from data
k = 0.45 # growth rate in 1/hour unit
C = 6e7 # maximum capacity
x = integrate(logistic_growth, timepoints, x0, k, C)
fig, ax = plt.subplots()
# Plot model simulation
ax.plot(timepoints, x, linewidth = 4, label = 'Model')

# Plot experimental data
for column_title in df:
    # the first two columns are not data, they are time columns, so we ignore those:
    if column_title == 't' or column_title == "Time":
        # Skip this and continue to iterate
        continue
    ax.plot(timepoints, df[column_title]*1e8, alpha = 0.5, lw = 1, label = 'Replicate: '+column_title)
ax.set_xlabel('Time (in hours)', fontsize = 18)
ax.set_ylabel('Bacteria Population', fontsize = 18)
ax.tick_params(labelsize = 14)
# bbox_to_anchor command  is used to set the position of the legend box
ax.legend(fontsize = 12, bbox_to_anchor = (1.05,1.1), loc = "best");<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09695682944090588, 'fraction_numerical': 0.01863647086577023, 'mean_word_length': 5.0398860398860394, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '416373', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1443, 'n_tokens_neox': 1366, 'n_words': 494, 'path': 'reading/week2_data_analysis.ipynb', 'repo_name': 'BioSysDesign/E164', 'size': '4239'}