Optogenetics-Sleep-Deprivation/7.UAS-ChRmine-attP5_Red_Stimulus.ipynb

934 lines
433 KiB
Text
Raw Normal View History

2026-05-26 14:20:57 +00:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 36,
"id": "b8cae812-466a-4fb0-9bca-c884b65e7a85",
"metadata": {},
"outputs": [],
"source": [
"import ethoscopy as etho\n",
"import pandas as pd\n",
"from scipy.stats import mannwhitneyu\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import seaborn as sns"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "5289d86c-0107-4089-83e3-327b70168e08",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2.1.0'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"etho.__version__"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "3d32b423-cc70-43f2-a2cc-ed9bd08c2981",
"metadata": {},
"outputs": [],
"source": [
"meta = '/home/rdingjin/attP5_2026-04-21/metadata_Phase5_2026-04-21_ChRmine.csv'\n",
"local = '/mnt/ethoscope_results'"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "df11ef6f-5475-45b0-95c3-2a8672a21219",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Ethoscopes ('ETHOSCOPE_278',) have multiple files for their day, the largest file has been kept. If you want all files for that day please add a time column\n"
]
}
],
"source": [
"metadata = etho.link_meta_index(meta, local)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "ebfbf3dc-d405-4f7b-a4a1-1eacff24f3a5",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Loading ROI_1 from ETHOSCOPE_278\n",
"Loading ROI_2 from ETHOSCOPE_278\n",
"Loading ROI_3 from ETHOSCOPE_278\n",
"Loading ROI_4 from ETHOSCOPE_278\n",
"Loading ROI_5 from ETHOSCOPE_278\n",
"Loading ROI_6 from ETHOSCOPE_278\n",
"Loading ROI_7 from ETHOSCOPE_278\n",
"Loading ROI_8 from ETHOSCOPE_278\n",
"Loading ROI_9 from ETHOSCOPE_278\n",
"Loading ROI_10 from ETHOSCOPE_278\n",
"Loading ROI_11 from ETHOSCOPE_278\n",
"Loading ROI_12 from ETHOSCOPE_278\n",
"Loading ROI_13 from ETHOSCOPE_278\n",
"Loading ROI_14 from ETHOSCOPE_278\n",
"Loading ROI_15 from ETHOSCOPE_278\n",
"Loading ROI_16 from ETHOSCOPE_278\n",
"Loading ROI_17 from ETHOSCOPE_278\n",
"Loading ROI_18 from ETHOSCOPE_278\n",
"Loading ROI_19 from ETHOSCOPE_278\n",
"Loading ROI_20 from ETHOSCOPE_278\n",
"Loading ROI_1 from ETHOSCOPE_302\n",
"Loading ROI_2 from ETHOSCOPE_302\n",
"Loading ROI_3 from ETHOSCOPE_302\n",
"Loading ROI_4 from ETHOSCOPE_302\n",
"Loading ROI_5 from ETHOSCOPE_302\n",
"Loading ROI_6 from ETHOSCOPE_302\n",
"Loading ROI_7 from ETHOSCOPE_302\n",
"Loading ROI_8 from ETHOSCOPE_302\n",
"Loading ROI_9 from ETHOSCOPE_302\n",
"Loading ROI_10 from ETHOSCOPE_302\n",
"Loading ROI_11 from ETHOSCOPE_302\n",
"Loading ROI_12 from ETHOSCOPE_302\n",
"Loading ROI_13 from ETHOSCOPE_302\n",
"Loading ROI_14 from ETHOSCOPE_302\n",
"Loading ROI_15 from ETHOSCOPE_302\n",
"Loading ROI_16 from ETHOSCOPE_302\n",
"Loading ROI_17 from ETHOSCOPE_302\n",
"Loading ROI_18 from ETHOSCOPE_302\n",
"Loading ROI_19 from ETHOSCOPE_302\n",
"Loading ROI_20 from ETHOSCOPE_302\n"
]
}
],
"source": [
"#fetch data from ethoscope\n",
"data = etho.load_ethoscope(metadata, reference_hour = 9.0, FUN = etho.sleep_annotation)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "a32d69f8-e66c-47fc-9b9a-2273f2c5082b",
"metadata": {},
"outputs": [],
"source": [
"df = etho.behavpy(data, metadata, check = True)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "e633d7d9-99db-4815-900d-e79d11dd65b1",
"metadata": {},
"outputs": [],
"source": [
"df.to_pickle('/home/rdingjin/attP5_2026-04-21/phase5_ChRmine.pkl')"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "ae2ff7e0-2f6c-4cc0-9afd-a1c021140760",
"metadata": {},
"outputs": [],
"source": [
"import ethoscopy as etho\n",
"import pandas as pd\n",
"import numpy as np\n",
"from scipy.stats import wilcoxon, shapiro, ttest_rel\n",
"df = pd.read_pickle('/home/rdingjin/attP5_2026-04-21/phase5_ChRmine.pkl')"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "94a0854d-4b5a-475f-a856-c61ec01d080e",
"metadata": {},
"outputs": [],
"source": [
"df = df.baseline(column = 'baseline')"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "cae6a067-5fd7-493a-9f23-c75d63e6ae06",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
" ==== METADATA ====\n",
"\n",
" date machine_name region_id \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 2026-04-21 ETHOSCOPE_278 1 \n",
"2026-04-21_16-50-58_278441|02 2026-04-21 ETHOSCOPE_278 2 \n",
"2026-04-21_16-50-58_278441|03 2026-04-21 ETHOSCOPE_278 3 \n",
"2026-04-21_16-50-58_278441|04 2026-04-21 ETHOSCOPE_278 4 \n",
"2026-04-21_16-50-58_278441|05 2026-04-21 ETHOSCOPE_278 5 \n",
"2026-04-21_16-50-58_278441|06 2026-04-21 ETHOSCOPE_278 6 \n",
"2026-04-21_16-50-58_278441|07 2026-04-21 ETHOSCOPE_278 7 \n",
"2026-04-21_16-50-58_278441|08 2026-04-21 ETHOSCOPE_278 8 \n",
"2026-04-21_16-50-58_278441|09 2026-04-21 ETHOSCOPE_278 9 \n",
"2026-04-21_16-50-58_278441|10 2026-04-21 ETHOSCOPE_278 10 \n",
"2026-04-21_16-50-58_278441|11 2026-04-21 ETHOSCOPE_278 11 \n",
"2026-04-21_16-50-58_278441|12 2026-04-21 ETHOSCOPE_278 12 \n",
"2026-04-21_16-50-58_278441|13 2026-04-21 ETHOSCOPE_278 13 \n",
"2026-04-21_16-50-58_278441|14 2026-04-21 ETHOSCOPE_278 14 \n",
"2026-04-21_16-50-58_278441|15 2026-04-21 ETHOSCOPE_278 15 \n",
"2026-04-21_16-50-58_278441|16 2026-04-21 ETHOSCOPE_278 16 \n",
"2026-04-21_16-50-58_278441|17 2026-04-21 ETHOSCOPE_278 17 \n",
"2026-04-21_16-50-58_278441|18 2026-04-21 ETHOSCOPE_278 18 \n",
"2026-04-21_16-50-58_278441|19 2026-04-21 ETHOSCOPE_278 19 \n",
"2026-04-21_16-50-58_278441|20 2026-04-21 ETHOSCOPE_278 20 \n",
"2026-04-21_17-13-12_30232c|01 2026-04-21 ETHOSCOPE_302 1 \n",
"2026-04-21_17-13-12_30232c|02 2026-04-21 ETHOSCOPE_302 2 \n",
"2026-04-21_17-13-12_30232c|03 2026-04-21 ETHOSCOPE_302 3 \n",
"2026-04-21_17-13-12_30232c|04 2026-04-21 ETHOSCOPE_302 4 \n",
"2026-04-21_17-13-12_30232c|05 2026-04-21 ETHOSCOPE_302 5 \n",
"2026-04-21_17-13-12_30232c|06 2026-04-21 ETHOSCOPE_302 6 \n",
"2026-04-21_17-13-12_30232c|07 2026-04-21 ETHOSCOPE_302 7 \n",
"2026-04-21_17-13-12_30232c|08 2026-04-21 ETHOSCOPE_302 8 \n",
"2026-04-21_17-13-12_30232c|09 2026-04-21 ETHOSCOPE_302 9 \n",
"2026-04-21_17-13-12_30232c|10 2026-04-21 ETHOSCOPE_302 10 \n",
"2026-04-21_17-13-12_30232c|11 2026-04-21 ETHOSCOPE_302 11 \n",
"2026-04-21_17-13-12_30232c|12 2026-04-21 ETHOSCOPE_302 12 \n",
"2026-04-21_17-13-12_30232c|13 2026-04-21 ETHOSCOPE_302 13 \n",
"2026-04-21_17-13-12_30232c|14 2026-04-21 ETHOSCOPE_302 14 \n",
"2026-04-21_17-13-12_30232c|15 2026-04-21 ETHOSCOPE_302 15 \n",
"2026-04-21_17-13-12_30232c|16 2026-04-21 ETHOSCOPE_302 16 \n",
"2026-04-21_17-13-12_30232c|17 2026-04-21 ETHOSCOPE_302 17 \n",
"2026-04-21_17-13-12_30232c|18 2026-04-21 ETHOSCOPE_302 18 \n",
"2026-04-21_17-13-12_30232c|19 2026-04-21 ETHOSCOPE_302 19 \n",
"2026-04-21_17-13-12_30232c|20 2026-04-21 ETHOSCOPE_302 20 \n",
"\n",
" sleep_deprived species food \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|02 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|03 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|04 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|05 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|06 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|07 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|08 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|09 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|10 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|11 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|12 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|13 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|14 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|15 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|16 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|17 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|18 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|19 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_16-50-58_278441|20 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|01 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|02 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|03 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|04 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|05 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|06 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|07 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|08 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|09 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|10 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|11 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|12 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|13 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|14 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|15 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|16 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|17 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|18 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|19 True UAS_ChRmine_attP5 normal_food \n",
"2026-04-21_17-13-12_30232c|20 True UAS_ChRmine_attP5 normal_food \n",
"\n",
" baseline sex time \n",
"id \n",
"2026-04-21_16-50-58_278441|01 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|02 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|03 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|04 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|05 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|06 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|07 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|08 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|09 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|10 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|11 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|12 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|13 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|14 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|15 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|16 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|17 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|18 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|19 0 male 16-50-58 \n",
"2026-04-21_16-50-58_278441|20 0 male 16-50-58 \n",
"2026-04-21_17-13-12_30232c|01 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|02 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|03 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|04 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|05 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|06 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|07 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|08 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|09 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|10 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|11 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|12 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|13 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|14 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|15 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|16 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|17 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|18 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|19 0 male 17-13-12 \n",
"2026-04-21_17-13-12_30232c|20 0 male 17-13-12 \n",
" ====== DATA ======\n",
"\n",
" t x y w \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 28370 505.360000 47.280000 18.280000 \n",
"2026-04-21_16-50-58_278441|01 28380 529.000000 47.000000 19.000000 \n",
"2026-04-21_16-50-58_278441|01 28390 526.275000 47.475000 17.600000 \n",
"2026-04-21_16-50-58_278441|01 28400 346.589744 37.076923 14.153846 \n",
"2026-04-21_16-50-58_278441|01 28410 19.000000 8.000000 16.000000 \n",
"... ... ... ... ... \n",
"2026-04-21_17-13-12_30232c|20 529000 137.000000 29.000000 22.541667 \n",
"2026-04-21_17-13-12_30232c|20 529010 137.000000 29.000000 22.633333 \n",
"2026-04-21_17-13-12_30232c|20 529020 137.000000 29.000000 22.741935 \n",
"2026-04-21_17-13-12_30232c|20 529030 137.000000 29.000000 22.482759 \n",
"2026-04-21_17-13-12_30232c|20 529040 137.000000 29.000000 22.333333 \n",
"\n",
" h phi max_velocity \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 7.760000 86.680000 234.897690 \n",
"2026-04-21_16-50-58_278441|01 8.000000 90.000000 34.584281 \n",
"2026-04-21_16-50-58_278441|01 7.575000 89.475000 34.584281 \n",
"2026-04-21_16-50-58_278441|01 6.769231 111.205128 150.618648 \n",
"2026-04-21_16-50-58_278441|01 10.000000 159.000000 1.530660 \n",
"... ... ... ... \n",
"2026-04-21_17-13-12_30232c|20 12.083333 153.125000 0.808870 \n",
"2026-04-21_17-13-12_30232c|20 12.133333 151.133333 0.888953 \n",
"2026-04-21_17-13-12_30232c|20 11.935484 141.064516 0.758366 \n",
"2026-04-21_17-13-12_30232c|20 12.034483 115.206897 0.814477 \n",
"2026-04-21_17-13-12_30232c|20 12.000000 131.500000 0.846991 \n",
"\n",
" mean_velocity dist has_interacted \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 39.210140 2.940760 0.0 \n",
"2026-04-21_16-50-58_278441|01 34.584281 3.423844 0.0 \n",
"2026-04-21_16-50-58_278441|01 30.934718 3.712166 0.0 \n",
"2026-04-21_16-50-58_278441|01 24.359208 2.850027 0.0 \n",
"2026-04-21_16-50-58_278441|01 1.530660 0.146943 0.0 \n",
"... ... ... ... \n",
"2026-04-21_17-13-12_30232c|20 0.687834 0.049524 0.0 \n",
"2026-04-21_17-13-12_30232c|20 0.697910 0.062812 0.0 \n",
"2026-04-21_17-13-12_30232c|20 0.676596 0.062923 0.0 \n",
"2026-04-21_17-13-12_30232c|20 0.686109 0.059691 0.0 \n",
"2026-04-21_17-13-12_30232c|20 0.684123 0.024628 0.0 \n",
"\n",
" beam_cross moving micro walk \\\n",
"id \n",
"2026-04-21_16-50-58_278441|01 0.0 True False True \n",
"2026-04-21_16-50-58_278441|01 0.0 True False True \n",
"2026-04-21_16-50-58_278441|01 0.0 True False True \n",
"2026-04-21_16-50-58_278441|01 0.0 True False True \n",
"2026-04-21_16-50-58_278441|01 0.0 True True False \n",
"... ... ... ... ... \n",
"2026-04-21_17-13-12_30232c|20 0.0 False False False \n",
"2026-04-21_17-13-12_30232c|20 0.0 False False False \n",
"2026-04-21_17-13-12_30232c|20 0.0 False False False \n",
"2026-04-21_17-13-12_30232c|20 0.0 False False False \n",
"2026-04-21_17-13-12_30232c|20 0.0 False False False \n",
"\n",
" is_interpolated asleep \n",
"id \n",
"2026-04-21_16-50-58_278441|01 False False \n",
"2026-04-21_16-50-58_278441|01 False False \n",
"2026-04-21_16-50-58_278441|01 False False \n",
"2026-04-21_16-50-58_278441|01 False False \n",
"2026-04-21_16-50-58_278441|01 False False \n",
"... ... ... \n",
"2026-04-21_17-13-12_30232c|20 False False \n",
"2026-04-21_17-13-12_30232c|20 False False \n",
"2026-04-21_17-13-12_30232c|20 False False \n",
"2026-04-21_17-13-12_30232c|20 False False \n",
"2026-04-21_17-13-12_30232c|20 False False \n",
"\n",
"[1973478 rows x 16 columns]\n"
]
}
],
"source": [
"df.display()"
]
},
{
"cell_type": "code",
"execution_count": 91,
"id": "75ace6ce-053d-4644-b356-0d984e5bf9e8",
"metadata": {},
"outputs": [],
"source": [
"#define dead and/or escaped flies\n",
"dead_flies = ['2026-04-21_16-50-58_278441|12', '2026-04-21_17-13-12_30232c|02', '2026-04-21_17-13-12_30232c|10',\n",
" '2026-04-21_16-50-58_278441|11', \n",
" '2026-04-21_17-13-12_30232c|16','2026-04-21_17-13-12_30232c|07', '2026-04-21_17-13-12_30232c|01'\n",
" ]"
]
},
{
"cell_type": "code",
"execution_count": 92,
"id": "76cd7456-6246-4665-a08a-d6f270a8567d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/srv/venv/lib/python3.12/site-packages/ethoscopy/behavpy_core.py:1611: FutureWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
" tdf.groupby(\"id\", group_keys=False).apply(\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 950x330 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#heatmap of UAS-ChRmine-attP5 sleep\n",
"start_hour = 0\n",
"end_hour = 120\n",
"fig = df.remove('id', *dead_flies).t_filter(start_time=start_hour, end_time=end_hour).heatmap(variable = 'asleep')\n",
"fig.show()"
]
},
{
"cell_type": "code",
"execution_count": 107,
"id": "00063f93-97a5-4bc3-aa27-c509e78a1a0e",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1266.67x483.333 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"start_hour = 0\n",
"end_hour = 120\n",
"\n",
"# Generate plot from Ethoscopy\n",
"fig = df.remove('id', *dead_flies).t_filter(start_time=start_hour, end_time=end_hour).plot_overtime(variable='asleep', avg_window=30, grids=True)\n",
"\n",
"# Extract the main axis from the figure\n",
"ax = fig.axes[0]\n",
"\n",
"# Add shading stimulus shading\n",
"# Draw a vertical span from ZT 48 to ZT 72\n",
"ax.axvspan(72, 96, color='#ff4c4c', alpha=0.3, zorder=1)\n",
"\n",
"# Set custom labels\n",
"ax.set_xlabel(\"Zeitgeber Time (Hours)\", fontsize=12)\n",
"ax.set_ylabel(\"Fraction of Time Asleep\", fontsize=12)\n",
"\n",
"# Show plot\n",
"fig.show()\n",
"\n",
"# Save as a high-resolution PNG\n",
"plt.savefig(\"Figure_5.png\", dpi=600, bbox_inches='tight')"
]
},
{
"cell_type": "code",
"execution_count": 94,
"id": "9f7a8ef1-7d73-40af-9da1-2efe6926690c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- Individual Fly Sleep (Baseline: 0h to 72h, Averaged per day) ---\n",
" Fly_Label Base_Sleep_24h Base_Day_12h Base_Night_12h\n",
"ETHOSCOPE_278 - Fly 01 6.937963 3.901215 3.890741\n",
"ETHOSCOPE_278 - Fly 02 5.021296 2.897451 2.758333\n",
"ETHOSCOPE_278 - Fly 03 9.868519 5.322676 5.706481\n",
"ETHOSCOPE_278 - Fly 04 8.947222 7.247184 3.287037\n",
"ETHOSCOPE_278 - Fly 05 13.071296 7.177238 7.465741\n",
"ETHOSCOPE_278 - Fly 06 18.107407 8.880854 11.171296\n",
"ETHOSCOPE_278 - Fly 07 9.376852 4.353301 5.973148\n",
"ETHOSCOPE_278 - Fly 08 16.220370 7.709544 10.199074\n",
"ETHOSCOPE_278 - Fly 09 13.152778 6.304683 8.228704\n",
"ETHOSCOPE_278 - Fly 10 5.661111 3.347955 3.046296\n",
"ETHOSCOPE_278 - Fly 13 13.331481 6.891652 7.942593\n",
"ETHOSCOPE_278 - Fly 14 11.434259 5.816242 6.891667\n",
"ETHOSCOPE_278 - Fly 15 7.667593 3.616341 4.839815\n",
"ETHOSCOPE_278 - Fly 16 9.789815 6.105513 5.021296\n",
"ETHOSCOPE_278 - Fly 17 9.799074 4.573120 6.223148\n",
"ETHOSCOPE_278 - Fly 18 11.271296 4.963679 7.390741\n",
"ETHOSCOPE_278 - Fly 19 9.343519 5.845880 4.777778\n",
"ETHOSCOPE_278 - Fly 20 13.079630 5.521043 8.767593\n",
"ETHOSCOPE_302 - Fly 03 10.271296 4.022809 7.168519\n",
"ETHOSCOPE_302 - Fly 04 13.408333 6.266507 8.575000\n",
"... (Showing first 20 rows)\n",
"\n",
"--- Grand Summary Statistics (Baseline: 0h to 72h) ---\n",
"Total Flies Analyzed: n = 33\n",
"\n",
"[ OVERALL SLEEP (Scaled to 24h Baseline Average) ]\n",
"Mean ± SEM: 11.93 ± 0.56 hours\n",
"Median: 12.77 hours\n",
"\n",
"[ DAY TIME (ZT 0-12, Averaged to 12h blocks) ]\n",
"Mean ± SEM: 5.93 ± 0.26 hours\n",
"Median: 6.11 hours\n",
"\n",
"[ NIGHT TIME (ZT 12-24, Averaged to 12h blocks) ]\n",
"Mean ± SEM: 7.33 ± 0.41 hours\n",
"Median: 7.79 hours\n"
]
}
],
"source": [
"# BASELINE\n",
"\n",
"# Define baseline time period\n",
"start_hour = 0\n",
"end_hour = 72\n",
"\n",
"# Filter the dataset to ONLY include data within specific baseline window\n",
"base_df = df.t_filter(start_time=start_hour, end_time=end_hour).copy()\n",
"\n",
"# Exclude dead flies\n",
"base_df = base_df[~base_df.index.get_level_values('id').isin(dead_flies)]\n",
"\n",
"# Calculate Overall 24h Baseline Average\n",
"sleep_hours = (base_df.groupby('id')['asleep'].sum() * 10) / 3600\n",
"\n",
"# (72 - 0) / 24 evaluates to exactly 3 days. \n",
"# Dividing total sleep by 3 to average the 72 hours into a single 24-hour metric\n",
"days_tracked = (end_hour - start_hour) / 24 \n",
"base_overall = (sleep_hours / days_tracked).reset_index(name='Base_Sleep_24h')\n",
"\n",
"# Calculate Day/Night 12h Baseline Averages\n",
"base_df['zt_hour'] = (base_df['t'] / 3600) % 24\n",
"base_df['Phase'] = np.where(base_df['zt_hour'] < 12, 'Day', 'Night')\n",
"\n",
"base_phase = base_df.groupby(['id', 'Phase']).agg(\n",
" total_sleep_epochs=('asleep', 'sum'),\n",
" total_tracking_epochs=('t', 'count')\n",
").reset_index()\n",
"\n",
"# Tracking_Hours will be ~24 for Day and ~24 for Night \n",
"# Dividing sleep by tracking hours and multiplying by 12 averages it to a single 12h block.\n",
"base_phase['Sleep_Hours'] = (base_phase['total_sleep_epochs'] * 10) / 3600\n",
"base_phase['Tracking_Hours'] = (base_phase['total_tracking_epochs'] * 10) / 3600\n",
"base_phase['Base_Sleep_12h'] = (base_phase['Sleep_Hours'] / base_phase['Tracking_Hours']) * 12\n",
"\n",
"base_pivot = base_phase.pivot(index='id', columns='Phase', values='Base_Sleep_12h').reset_index()\n",
"# Rename columns\n",
"base_pivot.columns = ['id', 'Base_Day_12h', 'Base_Night_12h']\n",
"\n",
"# Merge and clean up data\n",
"merged_df = pd.merge(base_overall, base_pivot, on='id')\n",
"\n",
"merged_df['Machine'] = merged_df['id'].map(df.meta['machine_name'])\n",
"merged_df['Tube'] = merged_df['id'].apply(lambda x: str(x).split('|')[-1])\n",
"merged_df['Fly_Label'] = merged_df['Machine'] + \" - Fly \" + merged_df['Tube']\n",
"\n",
"clean_table = merged_df.dropna(subset=['Machine']).sort_values(by=['Machine', 'Tube'])\n",
"baseline_stats = clean_table[['Fly_Label', 'Base_Sleep_24h', 'Base_Day_12h', 'Base_Night_12h']]\n",
"\n",
"# PRINT RESULTS\n",
"print(f\"--- Individual Fly Sleep (Baseline: {start_hour}h to {end_hour}h, Averaged per day) ---\")\n",
"print(baseline_stats.head(20).to_string(index=False)) \n",
"print(\"... (Showing first 20 rows)\\n\")\n",
"\n",
"print(f\"--- Grand Summary Statistics (Baseline: {start_hour}h to {end_hour}h) ---\")\n",
"print(f\"Total Flies Analyzed: n = {len(baseline_stats)}\")\n",
"\n",
"# 1. OVERALL 24H STATS\n",
"print(\"\\n[ OVERALL SLEEP (Scaled to 24h Baseline Average) ]\")\n",
"print(f\"Mean ± SEM: {baseline_stats['Base_Sleep_24h'].mean():.2f} ± {baseline_stats['Base_Sleep_24h'].sem():.2f} hours\")\n",
"print(f\"Median: {baseline_stats['Base_Sleep_24h'].median():.2f} hours\")\n",
"\n",
"# 2. DAY TIME STATS\n",
"print(f\"\\n[ DAY TIME (ZT 0-12, Averaged to 12h blocks) ]\")\n",
"print(f\"Mean ± SEM: {baseline_stats['Base_Day_12h'].mean():.2f} ± {baseline_stats['Base_Day_12h'].sem():.2f} hours\")\n",
"print(f\"Median: {baseline_stats['Base_Day_12h'].median():.2f} hours\")\n",
"\n",
"# 3. NIGHT TIME STATS\n",
"print(f\"\\n[ NIGHT TIME (ZT 12-24, Averaged to 12h blocks) ]\")\n",
"print(f\"Mean ± SEM: {baseline_stats['Base_Night_12h'].mean():.2f} ± {baseline_stats['Base_Night_12h'].sem():.2f} hours\")\n",
"print(f\"Median: {baseline_stats['Base_Night_12h'].median():.2f} hours\")"
]
},
{
"cell_type": "code",
"execution_count": 95,
"id": "ac65afcf-69b7-4ae8-b409-11e2ffb5ae94",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- Individual Fly Sleep (Stimulus: 72h to 96h) ---\n",
" Fly_Label Stim_Sleep_24h Stim_Day_12h Stim_Night_12h\n",
"ETHOSCOPE_278 - Fly 01 2.544444 1.677778 0.866667\n",
"ETHOSCOPE_278 - Fly 02 8.975000 5.325000 3.650000\n",
"ETHOSCOPE_278 - Fly 03 8.883333 2.972222 5.911111\n",
"ETHOSCOPE_278 - Fly 04 13.900000 6.030556 7.869444\n",
"ETHOSCOPE_278 - Fly 05 10.372222 5.900000 4.472222\n",
"ETHOSCOPE_278 - Fly 06 13.061111 3.652778 9.408333\n",
"ETHOSCOPE_278 - Fly 07 6.900000 3.025000 3.875000\n",
"ETHOSCOPE_278 - Fly 08 8.205556 6.894444 1.311111\n",
"ETHOSCOPE_278 - Fly 09 1.513889 1.416667 0.097222\n",
"ETHOSCOPE_278 - Fly 10 7.452778 3.280556 4.172222\n",
"ETHOSCOPE_278 - Fly 13 14.208333 5.588889 8.619444\n",
"ETHOSCOPE_278 - Fly 14 13.511111 7.300000 6.211111\n",
"ETHOSCOPE_278 - Fly 15 12.263889 4.763889 7.500000\n",
"ETHOSCOPE_278 - Fly 16 13.011111 6.691667 6.319444\n",
"ETHOSCOPE_278 - Fly 17 9.977778 4.872222 5.105556\n",
"ETHOSCOPE_278 - Fly 18 14.775000 5.833333 8.941667\n",
"ETHOSCOPE_278 - Fly 19 5.666667 2.138889 3.527778\n",
"ETHOSCOPE_278 - Fly 20 11.283333 5.755556 5.527778\n",
"ETHOSCOPE_302 - Fly 03 10.577778 4.802778 5.775000\n",
"ETHOSCOPE_302 - Fly 04 11.647222 6.002778 5.644444\n",
"... (Showing first 20 rows)\n",
"\n",
"--- Grand Summary Statistics (Stimulus: 72h to 96h) ---\n",
"Total Flies Analyzed: n = 33\n",
"\n",
"[ OVERALL SLEEP (24h Stimulus Block) ]\n",
"Mean ± SEM: 11.63 ± 0.67 hours\n",
"Median: 12.26 hours\n",
"\n",
"[ DAY TIME (ZT 0-12 during Stimulus) ]\n",
"Mean ± SEM: 5.30 ± 0.33 hours\n",
"Median: 5.76 hours\n",
"\n",
"[ NIGHT TIME (ZT 12-24 during Stimulus) ]\n",
"Mean ± SEM: 6.33 ± 0.46 hours\n",
"Median: 6.23 hours\n"
]
}
],
"source": [
"# Define stimulus time period\n",
"start_hour = 72\n",
"end_hour = 96\n",
"\n",
"# Filter the dataset to ONLY include data within specific stimulus window\n",
"stim_df = df.t_filter(start_time=start_hour, end_time=end_hour).copy()\n",
"\n",
"# Exclude dead flies\n",
"stim_df = stim_df[~stim_df.index.get_level_values('id').isin(dead_flies)]\n",
"\n",
"# Calculate Overall 24h Stimulus Average\n",
"sleep_hours = (stim_df.groupby('id')['asleep'].sum() * 10) / 3600\n",
"days_tracked = (end_hour - start_hour) / 24 \n",
"stim_overall = (sleep_hours / days_tracked).reset_index(name='Stim_Sleep_24h')\n",
"\n",
"# Calculate Day/Night 12h Stimulus Averages\n",
"stim_df['zt_hour'] = (stim_df['t'] / 3600) % 24\n",
"stim_df['Phase'] = np.where(stim_df['zt_hour'] < 12, 'Day', 'Night')\n",
"\n",
"stim_phase = stim_df.groupby(['id', 'Phase']).agg(\n",
" total_sleep_epochs=('asleep', 'sum'),\n",
" total_tracking_epochs=('t', 'count')\n",
").reset_index()\n",
"\n",
"# Tracking_Hours will now be ~12 for Day and ~12 for Night\n",
"# Dividing sleep by tracking hours and multiplying by 12 averages it to a single 12h block.\n",
"stim_phase['Sleep_Hours'] = (stim_phase['total_sleep_epochs'] * 10) / 3600\n",
"stim_phase['Tracking_Hours'] = (stim_phase['total_tracking_epochs'] * 10) / 3600\n",
"stim_phase['Stim_Sleep_12h'] = (stim_phase['Sleep_Hours'] / stim_phase['Tracking_Hours']) * 12\n",
"\n",
"stim_pivot = stim_phase.pivot(index='id', columns='Phase', values='Stim_Sleep_12h').reset_index()\n",
"# Rename columns \n",
"stim_pivot.columns = ['id', 'Stim_Day_12h', 'Stim_Night_12h']\n",
"\n",
"# Merge and clean up data\n",
"merged_df = pd.merge(stim_overall, stim_pivot, on='id')\n",
"\n",
"merged_df['Machine'] = merged_df['id'].map(df.meta['machine_name'])\n",
"merged_df['Tube'] = merged_df['id'].apply(lambda x: str(x).split('|')[-1])\n",
"merged_df['Fly_Label'] = merged_df['Machine'] + \" - Fly \" + merged_df['Tube']\n",
"\n",
"clean_table = merged_df.dropna(subset=['Machine']).sort_values(by=['Machine', 'Tube'])\n",
"stim_stats = clean_table[['Fly_Label', 'Stim_Sleep_24h', 'Stim_Day_12h', 'Stim_Night_12h']]\n",
"\n",
"# PRINT RESULTS\n",
"print(f\"--- Individual Fly Sleep (Stimulus: {start_hour}h to {end_hour}h) ---\")\n",
"print(stim_stats.head(20).to_string(index=False)) \n",
"print(\"... (Showing first 20 rows)\\n\")\n",
"\n",
"print(f\"--- Grand Summary Statistics (Stimulus: {start_hour}h to {end_hour}h) ---\")\n",
"print(f\"Total Flies Analyzed: n = {len(stim_stats)}\")\n",
"\n",
"# 1. OVERALL 24H STATS\n",
"print(\"\\n[ OVERALL SLEEP (24h Stimulus Block) ]\")\n",
"print(f\"Mean ± SEM: {stim_stats['Stim_Sleep_24h'].mean():.2f} ± {stim_stats['Stim_Sleep_24h'].sem():.2f} hours\")\n",
"print(f\"Median: {stim_stats['Stim_Sleep_24h'].median():.2f} hours\")\n",
"\n",
"# 2. DAY TIME STATS\n",
"print(f\"\\n[ DAY TIME (ZT 0-12 during Stimulus) ]\")\n",
"print(f\"Mean ± SEM: {stim_stats['Stim_Day_12h'].mean():.2f} ± {stim_stats['Stim_Day_12h'].sem():.2f} hours\")\n",
"print(f\"Median: {stim_stats['Stim_Day_12h'].median():.2f} hours\")\n",
"\n",
"# 3. NIGHT TIME STATS\n",
"print(f\"\\n[ NIGHT TIME (ZT 12-24 during Stimulus) ]\")\n",
"print(f\"Mean ± SEM: {stim_stats['Stim_Night_12h'].mean():.2f} ± {stim_stats['Stim_Night_12h'].sem():.2f} hours\")\n",
"print(f\"Median: {stim_stats['Stim_Night_12h'].median():.2f} hours\")"
]
},
{
"cell_type": "code",
"execution_count": 96,
"id": "5fa83974-cf50-4d0a-8e07-0c01d583ed21",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"--- 24h Total Statistical Analysis ---\n",
"Shapiro-Wilk P-value (Normality of differences): 0.1517\n",
"Result: Data is normal. Used Paired T-test.\n",
"P-value: 6.6325e-01\n",
"Significance: ns\n",
"\n",
"--- Daytime Statistical Analysis ---\n",
"Shapiro-Wilk P-value (Normality of differences): 0.0569\n",
"Result: Data is normal. Used Paired T-test.\n",
"P-value: 5.9746e-02\n",
"Significance: ns\n",
"\n",
"--- Nighttime Statistical Analysis ---\n",
"Shapiro-Wilk P-value (Normality of differences): 0.1283\n",
"Result: Data is normal. Used Paired T-test.\n",
"P-value: 5.2551e-02\n",
"Significance: ns\n"
]
}
],
"source": [
"# STATISTICS\n",
"\n",
"# Merge Baseline and Stimulus data on Fly_Label\n",
"# This ensures we are comparing the SAME fly to itself\n",
"paired_df = pd.merge(baseline_stats, stim_stats, on='Fly_Label')\n",
"\n",
"def run_paired_stats(df, base_col, stim_col, label):\n",
" # Calculate the differences for the paired test\n",
" diffs = df[stim_col] - df[base_col]\n",
" \n",
" # 2. Shapiro-Wilk Test for Normality\n",
" # We test if the differences are normally distributed\n",
" _, p_shapiro = shapiro(diffs)\n",
" \n",
" print(f\"\\n--- {label} Statistical Analysis ---\")\n",
" print(f\"Shapiro-Wilk P-value (Normality of differences): {p_shapiro:.4f}\")\n",
" \n",
" # 3. Determine Test: If P > 0.05, data is normal (use t-test). If P < 0.05, use Wilcoxon.\n",
" if p_shapiro > 0.05:\n",
" stat, p_val = ttest_rel(df[base_col], df[stim_col])\n",
" print(f\"Result: Data is normal. Used Paired T-test.\")\n",
" else:\n",
" stat, p_val = wilcoxon(df[base_col], df[stim_col])\n",
" print(f\"Result: Data is not normal. Used Wilcoxon Signed-Rank test.\")\n",
" \n",
" print(f\"P-value: {p_val:.4e}\")\n",
" if p_val < 0.0001: print(\"Significance: ****\")\n",
" elif p_val < 0.001: print(\"Significance: ***\")\n",
" elif p_val < 0.01: print(\"Significance: **\")\n",
" elif p_val < 0.05: print(\"Significance: *\")\n",
" else: print(\"Significance: ns\")\n",
"\n",
"# Run for all three metrics\n",
"run_paired_stats(paired_df, 'Base_Sleep_24h', 'Stim_Sleep_24h', '24h Total')\n",
"run_paired_stats(paired_df, 'Base_Day_12h', 'Stim_Day_12h', 'Daytime')\n",
"run_paired_stats(paired_df, 'Base_Night_12h', 'Stim_Night_12h', 'Nighttime')"
]
},
{
"cell_type": "code",
"execution_count": 106,
"id": "09e3b6c5-5971-44c5-91b4-51cc0ab88aad",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAqwAAAJICAYAAACkF7akAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAuJdJREFUeJzs3XdcU/f+P/BX2AQIe6MIgigqioqCWnHvWa+jWrVW67Z11Ku1u7dq21vba6vf1qrVqrdWr1rr1oqWKu4JOEH2DnuTEPL7A8nPCCqEQEJ4PR+PPsr5nJOTdzDAK+d8hkAul8tBRERERKSl9DRdABERERHRizCwEhEREZFWY2AlIiIiIq3GwEpEREREWo2BlYiIiIi0GgMrEREREWk1BlYiIiIi0moMrERERESk1RhY6+n111/H66+/rukyiIiIiHSWgaYLaOpSU1M1XQIRERGRTuMVViIiIiLSagysRERERKTVGFiJiIiISKsxsBIRERGRVmNgJSIiIiKtxsBKRERERFqNgZWIiIiItBoDKxERERFpNQZWIiIiItJqDKxEREREpNUYWImIiIhIqzGwEhEREZFWY2AlIiIiIq3GwEpEREREWo2BlYiIiIi0GgMrEREREWk1BlYiIiIi0moMrERERESk1RhYiYiIiEirMbASERERkVZjYCUiIiIircbASlrh+++/h4+PD+Lj47Fq1Sp069YNXbt2xXvvvYeSkhLFcWFhYXjttdfQrVs3+Pv7Y8iQIfjmm280WDlpM76vqCHwfUXU+Aw0XQDR05YsWQI3NzcsW7YM9+7dw//+9z/Y2NhgxYoViIqKwty5c+Hj44O3334bRkZGiI+Px82bNzVdNmk5vq+oIfB9RdR4GFhJq7Rr1w5r165VbOfm5mL//v1YsWIFwsLCIJVKsWXLFtjY2GiwSmpq+L6ihsD3FVHjYZcA0iqTJ09W2u7WrRtyc3NRWFgIkUgEAAgJCUFFRYUmyqMmiu8ragh8XxE1HgZW0iouLi5K21W/9PPy8jB8+HB06dIFH3zwAXr27ImlS5fi+PHj/GNAL8X3FTUEvq+IGg8DK2kVPb2a35JyuRwmJib473//ix07dmDMmDF4+PAhli5dipkzZ0ImkzVypdSU8H1FDYHvK6LGw8BKTYqenh6CgoLw3nvv4fjx41i6dCkuX76MK1euaLo0asL4vqKGwPcVkfowsFKTkZubW62tXbt2AACJRNLI1ZCu4PuKGgLfV0TqxVkCqMnYtGkTrl+/juDgYLi6uiIrKwu//vornJyc0LVrV02XR00U31fUEPi+IlIvBlZqMvr374/k5GQcOHAAOTk5sLa2Rvfu3bF48WJYWFhoujxqovi+oobA9xWRegnkcrlc00U0ZQMGDABQOXUJEREREakf+7ASERERkVZjlwCqNblcrrROdnNgamoKgUCg6TJ0Gt9X1BD4viLSLQysVCtyuRxjx47F9evXNV1KowoICMDvv//OPwINhO8rvq8aAt9XfF+R7mGXAKqVkpKSZvfLHwCuXbvW7K7SNCa+r6gh8H1FpHt4hZXq7M6dOxAKhZouo0EVFxejU6dOmi6jWeH7ihoC31dEuoGBlepMKBTq/B8Aanx8X1FD4PuKSDewSwARERERaTUGViIiIiLSagysRERERKTVGFiJiIiISKsxsBIRERGRVmNgJSIiIiKtxmmtqFZMTU0REBCg+FrXNbfXqynN7fvc3F6vpjS373Nze73UPAnkcrlc00U0ZQMGDAAAhISEaLiShlf1Vmkuy/41t9erKc3t+9zcXq+mNLfvc3N7vdT88Aor1Vpz+0XY3F6vpjS373Nze72a0ty+z83t9VLzwz6sRERERKTVGFiJiIiISKsxsBIRERGRVmNgJSIiIiKtxsBKRERERFpNqwLriRMnMH/+fPTp0wedO3fGmDFjsH//fjw789b//vc/DBkyBB07dsTo0aNx7ty5Wp0/PT0dixcvhr+/P7p37473338fhYWFDfFSiIiIiEhNtCqw7tixA6ampli1ahV++OEH9OnTBx9++CE2bdqkOObYsWP48MMPMWzYMGzZsgWdO3fGokWLcPv27ReeWyqVYvbs2YiLi8P69evxySef4MKFC1i+fHkDvyoiIiIiqg+tmof1hx9+gI2NjWI7KCgIubm52L59OxYsWAA9PT189913GDFiBJYsWQIACAwMxKNHj7Bp0yZs2bLluec+deoUoqKicPz4cXh6egIARCIRZs2ahfDwcPj5+TXoayMiIiIi1WjVFdanw2qVdu3aobCwEMXFxUhMTERcXByGDRumdMzw4cNx6dIlSCSS557777//ho+PjyKsAkCvXr1gZWWF0NBQ9b0IIiIiIlIrrQqsNblx4wYcHR1hbm6OmJgYAICHh4fSMa1bt4ZUKkViYuJzzxMTE6MUVoHKlUE8PDwU5yUiIiIi7aNVXQKedf36dRw/fhwrV64EAOTl5QGovJX/tKrtqv01yc/Ph4WFRbV2S0vLFz4OAAYMGPDcfampqXB2dn7h44mIiIhIdVp7hTUtLQ1Lly5Fjx49MH36dE2XQ0REREQaopVXWPPz8/HWW2/BysoK33//PfT0KnO1paUlAKCgoAD29vZKxz+9vyYikajGKazy8vJeeoU0JCTkuftedPWViIiIiOpP666wlpaWYu7cuSgoKMDWrVuVbuNX9UF9ts9pTEwMDA0N0aJFi+ee19PTs9rj5HI5YmNjq/VtJSIiIiLtoVWBtby8HEuWLEFMTAy2bt0KR0dHpf0tWrRAq1atcPLkSaX248ePIygoCEZGRs89d58+ffDgwQPExcUp2i5duoTc3FwEBwer9XUQERERkfpoVWD99NNPce7cOcybNw+FhYW4ffu24r+qKasWL16Mo0eP4rvvvsOVK1fw8ccfIzw8HAsWLFCcJzk5Gb6+vti4caOibciQIfD29sbixYtx7tw5HD9+HKtXr0bfvn05BysRERGRFtOqPqxhYWEAgC+++KLavpCQELi5uWHkyJEoKSnBli1b8NNPP8HDwwMbN26Ev7+/4li5XA6ZTKa0pKuhoSG2bt2Kzz//HMuWLYOBgQEGDRqE1atXN/wLIyIiIiKVCeRPpzqqs6pBVy8amEVEREREqtOqK6xEmpSamoqrV6+ivLwcnTt3RuvWrTVdEhEREYGBlQhAZVjdtm0bysvLAQARERGYOHEifH19NVwZERERMbCSThOLxSguLn7pcX/++ScyMzOV2o4ePQozMzMAgFAoVJr7l4iIiBoPAyvprIKCAqxevRq16aYdGxuLnJwcpTahUIhHjx4BAPT09LB+/foal/clIiKihsVBV/XEQVfa7WVXWFNTU7F161YMHToUFy5cUNrXr18/dO7cGQCvsBIREWkSr7CSTqttyAwICICvry8uX74MqVQKf39/dO/evYGrIyIiotpgYCV6wtfXl4OsiIiItJBWrXRFRERERPQsBlYiIiIi0moMrERERESk1RhYiYiIiEirMbASERERkVZjYCUiIiIircbASkRERERajYGViIiIiLQaAysRERERaTUGViIiIiLSagysRERERKTVGFiJiIiISKsxsBIRERGRVmNgJSIiIiKtxsBKRERERFqNgZWIiIiItBoDKxERERFpNQZWIiIiItJqDKxEREREpNUYWImIiIhIqzGwEhEREZFWY2AlIiIiIq3GwEpEREREWo2BlYiIiIi0GgMrEREREWk1BlYiIiIi0moMrERERESk1RhYiYiIiEirMbBSrZWXlyMuLg6ZmZmaLoWIiIiaEQNNF0BNQ2pqKv773/+isLAQANCxY0eMGzcOenr8zENEREQNi4GVauXYsWNIT0+HVCoFAJw/fx6Wlpbw9vau87mEQiHs7e3VXSIRERHpKAZWqpXY2FiEhIQotT18+BCurq51Ppeenh7Wr18PCwsLdZVHREREOoyBlWrF09MTAwYMUFxhBYCRI0cqXWFNTU3F1q1bMXv2bDg7Oz/3XEKhkGGViIiIao2BlWpl+PDhyM3NRUFBAQDAz88PAwYMgEAgqHass7Mz3N3dG7tEIiIi0lE
"text/plain": [
"<Figure size 700x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# 1. PREPARE DATA & CALCULATE STATS\n",
"combined = pd.merge(baseline_stats, stim_stats, on='Fly_Label')\n",
"\n",
"# Calculate the paired statistics for the brackets\n",
"p_values = {}\n",
"metrics = {\n",
" '24h': ('Base_Sleep_24h', 'Stim_Sleep_24h'),\n",
" 'Day': ('Base_Day_12h', 'Stim_Day_12h'),\n",
" 'Night': ('Base_Night_12h', 'Stim_Night_12h')\n",
"}\n",
"\n",
"for phase, (base_col, stim_col) in metrics.items():\n",
" diffs = combined[stim_col] - combined[base_col]\n",
" _, p_shapiro = shapiro(diffs)\n",
" \n",
" if p_shapiro > 0.05:\n",
" _, p_val = ttest_rel(combined[base_col], combined[stim_col])\n",
" else:\n",
" _, p_val = wilcoxon(combined[base_col], combined[stim_col])\n",
" p_values[phase] = p_val\n",
"\n",
"plot_df = combined.melt(id_vars=['Fly_Label'], var_name='Variable', value_name='Hours')\n",
"plot_df['Condition'] = plot_df['Variable'].apply(lambda x: '24h' if '24h' in x else ('Day' if 'Day' in x else 'Night'))\n",
"plot_df['State'] = plot_df['Variable'].apply(lambda x: 'Baseline' if 'Base' in x else 'Stimulus')\n",
"\n",
"# 2. GENERATE PLOT\n",
"plt.figure(figsize=(7, 6))\n",
"sns.set_theme(style=\"ticks\")\n",
"\n",
"order = ['24h', 'Day', 'Night']\n",
"hue_order = ['Baseline', 'Stimulus']\n",
"palette = {'Baseline': '#cccccc', 'Stimulus': '#ff4c4c'}\n",
"\n",
"# Boxplot\n",
"sns.boxplot(\n",
" data=plot_df, x='Condition', y='Hours', hue='State', \n",
" order=order, hue_order=hue_order, palette=palette,\n",
" width=0.6, gap=0.2, boxprops={'edgecolor': 'black', 'alpha': 0.7},\n",
" medianprops={'color': 'black', 'linewidth': 1.5}, showfliers=False\n",
")\n",
"\n",
"# Stripplot\n",
"sns.stripplot(\n",
" data=plot_df, x='Condition', y='Hours', hue='State', \n",
" order=order, hue_order=hue_order, dodge=True,\n",
" palette=['black', 'black'], alpha=0.5, size=4, jitter=0.05,\n",
" legend=False\n",
")\n",
"\n",
"# 3. ADD MEDIAN LABELS\n",
"ax = plt.gca()\n",
"medians = plot_df.groupby(['Condition', 'State'], sort=False)['Hours'].median()\n",
"offsets = {'Baseline': -0.4, 'Stimulus': 0.4}\n",
"\n",
"for i, cond in enumerate(order):\n",
" for state in hue_order:\n",
" val = medians[(cond, state)]\n",
" ax.text(i + offsets[state], val, f\"{val:.1f}h\", \n",
" ha='center', va='bottom', fontsize=10)\n",
"\n",
"# 4. ADD SIGNIFICANCE BRACKETS\n",
"y_max = plot_df['Hours'].max()\n",
"y_line = y_max + 1.0 \n",
"h = 0.4 \n",
"\n",
"for i, cond in enumerate(order):\n",
" p = p_values[cond]\n",
" \n",
" if p < 0.0001: star = '****'\n",
" elif p < 0.001: star = '***'\n",
" elif p < 0.01: star = '**'\n",
" elif p < 0.05: star = '*'\n",
" else: star = 'ns'\n",
" \n",
" x1, x2 = i - 0.2, i + 0.2\n",
" plt.plot([x1, x1, x2, x2], [y_line, y_line+h, y_line+h, y_line], lw=1.5, c='k')\n",
" plt.text((x1+x2)*.5, y_line+h, star, ha='center', va='bottom', fontsize=12)\n",
"\n",
"# 5. FORMATTING\n",
"sns.despine()\n",
"plt.ylabel('Average time spent asleep (hours)', fontsize=12)\n",
"plt.xlabel('')\n",
"plt.xlim(-0.6, 2.5) \n",
"\n",
"plt.ylim(0, max(20, y_line + h + 1.5)) \n",
"\n",
"# Legend is moved outside\n",
"plt.legend(title='', frameon=False, loc='center left', bbox_to_anchor=(1, 0.5))\n",
"plt.tight_layout()\n",
"\n",
"plt.savefig(\"ChRmine-attP5_RED.png\", dpi=600, bbox_inches='tight')\n",
"plt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}