Files
bio-performx/pdf_generation.ipynb
T

878 lines
348 KiB
Plaintext
Raw Normal View History

{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "6eee3ddd",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "d95cd8b1",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_excel('data/SECA body comp for all patients.xlsx')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "6bbc907f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Data shape: (63, 147)\n",
"Columns: ['MeasurementDate', 'Comment', 'ExternalDeviceId', 'ExternalPatientId', 'FirstName', 'LastName', 'BirthDate', 'Age', 'Ethnicity', 'Gender', 'Height', 'Height_Unit', 'Weight', 'Weight_Unit', 'WaistCircumference', 'WaistCircumference_Unit', 'PAL', 'Adult_BMI', 'Adult_BMI_Unit', 'Adult_FM', 'Adult_FM_Unit', 'Adult_FMP', 'Adult_FMP_Unit', 'Adult_FMI', 'Adult_FMI_Unit', 'Adult_ZFMI', 'Adult_FFM', 'Adult_FFM_Unit', 'Adult_FFMP', 'Adult_FFMP_Unit', 'Adult_FFMI', 'Adult_FFMI_Unit', 'Adult_TBW', 'Adult_TBW_Unit', 'Adult_TBWP', 'Adult_TBWP_Unit', 'Adult_ECW', 'Adult_ECW_Unit', 'Adult_ECWP', 'Adult_ECWP_Unit', 'Adult_ECWbyTBW', 'Adult_ECWbyTBW_Unit', 'Adult_SMM', 'Adult_SMM_Unit', 'Adult_SMMBMIIndependant', 'Adult_SMMBMIIndependant_Unit', 'Adult_SMMP', 'Adult_SMMP_Unit', 'Adult_SMI', 'Adult_SMI_Unit', 'Adult_SMoA', 'Adult_SMoA_Unit', 'Adult_SMoABMIIndependant', 'Adult_SMoABMIIndependant_Unit', 'Adult_ZSMI', 'Adult_SSMMRightArm', 'Adult_SSMMRightArm_Unit', 'Adult_SSMMLeftArm', 'Adult_SSMMLeftArm_Unit', 'Adult_SSMMRightLeg', 'Adult_SSMMRightLeg_Unit', 'Adult_SSMMLeftLeg', 'Adult_SSMMLeftLeg_Unit', 'Adult_SSMMTorso', 'Adult_SSMMTorso_Unit', 'Adult_SSMMRightArmBMIIndependant', 'Adult_SSMMRightArmBMIIndependant_Unit', 'Adult_SSMMLeftArmBMIIndependant', 'Adult_SSMMLeftArmBMIIndependant_Unit', 'Adult_SSMMRightLegBMIIndependant', 'Adult_SSMMRightLegBMIIndependant_Unit', 'Adult_SSMMLeftLegBMIIndependant', 'Adult_SSMMLeftLegBMIIndependant_Unit', 'Adult_SSMMTorsoBMIIndependant', 'Adult_SSMMTorsoBMIIndependant_Unit', 'Adult_ASMM', 'Adult_ASMM_Unit', 'Adult_ASMI', 'Adult_ASMI_Unit', 'Adult_ASMP', 'Adult_ASMP_Unit', 'Adult_R', 'Adult_R_Unit', 'Adult_XC', 'Adult_XC_Unit', 'Adult_BIVA_ZRh', 'Adult_BIVA_ZXcH', 'Adult_PhA', 'Adult_PhA_Unit', 'Adult_VAT', 'Adult_VAT_Unit', 'Adult_TBS', 'Adult_TBS_Unit', 'Adult_TBS_MuscleScore', 'Adult_TBS_MuscleScore_Unit', 'Adult_TBS_FatScore', 'Adult_TBS_FatScore_Unit', 'Adult_REE_Kcal', 'Adult_REE_MJ', 'Adult_TEE_Kcal', 'Adult_TEE_MJ', 'Child_BMI', 'Child_BMI_Unit', 'Child_FM', 'Child_FM_Unit', 'Child_FMP', 'Child_FMP_Unit', 'Child_FMI', 'Child_FMI_Unit', 'Child_ZFMI', 'Child_FFM', 'Child_FFM_Unit', 'Child_FFMP', 'Child_FFMP_Unit', 'Child_FFMI', 'Child_FFMI_Unit', 'Child_ZFFMI', 'Child_TBW', 'Child_TBW_Unit', 'Child_TBWP', 'Child_TBWP_Unit', 'Child_SMMByKim', 'Child_SMMByKim_Unit', 'Child_SMMP', 'Child_SMMP_Unit', 'Child_SMI', 'Child_SMI_Unit', 'Child_LSTLeftArm', 'Child_LSTLeftArm_Unit', 'Child_LSTRightArm', 'Child_LSTRightArm_Unit', 'Child_LSTLeftLeg', 'Child_LSTLeftLeg_Unit', 'Child_LSTRightLeg', 'Child_LSTRightLeg_Unit', 'Child_R', 'Child_R_Unit', 'Child_XC', 'Child_XC_Unit', 'Child_BIVA_ZRh', 'Child_BIVA_ZXcH', 'Child_PhA', 'Child_PhA_Unit', 'Child_REE_Kcal', 'Child_REE_MJ', 'Child_TEE_Kcal', 'Child_TEE_MJ']\n",
"\n",
"First few rows:\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>MeasurementDate</th>\n",
" <th>Comment</th>\n",
" <th>ExternalDeviceId</th>\n",
" <th>ExternalPatientId</th>\n",
" <th>FirstName</th>\n",
" <th>LastName</th>\n",
" <th>BirthDate</th>\n",
" <th>Age</th>\n",
" <th>Ethnicity</th>\n",
" <th>Gender</th>\n",
" <th>...</th>\n",
" <th>Child_XC</th>\n",
" <th>Child_XC_Unit</th>\n",
" <th>Child_BIVA_ZRh</th>\n",
" <th>Child_BIVA_ZXcH</th>\n",
" <th>Child_PhA</th>\n",
" <th>Child_PhA_Unit</th>\n",
" <th>Child_REE_Kcal</th>\n",
" <th>Child_REE_MJ</th>\n",
" <th>Child_TEE_Kcal</th>\n",
" <th>Child_TEE_MJ</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>2025-09-05T14:56:27.0000000Z</td>\n",
" <td>NaN</td>\n",
" <td>10000001583275_0055003f5631501320313557</td>\n",
" <td>LD5163301170</td>\n",
" <td>Lucy</td>\n",
" <td>Dibenedetto</td>\n",
" <td>1997-08-28T00:00:00.0000000Z</td>\n",
" <td>28</td>\n",
" <td>Caucasian</td>\n",
" <td>Female</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2025-09-03T13:16:22.0000000Z</td>\n",
" <td>NaN</td>\n",
" <td>10000001583275_0055003f5631501320313557</td>\n",
" <td>NS6479273340</td>\n",
" <td>Niyanta</td>\n",
" <td>Shah</td>\n",
" <td>1985-03-11T00:00:00.0000000Z</td>\n",
" <td>40</td>\n",
" <td>Other</td>\n",
" <td>Female</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2025-09-03T13:14:23.0000000Z</td>\n",
" <td>NaN</td>\n",
" <td>10000001583275_0055003f5631501320313557</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>1985-03-11T00:00:00.0000000Z</td>\n",
" <td>40</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>2025-08-27T20:57:32.0000000Z</td>\n",
" <td>NaN</td>\n",
" <td>10000001583275_0055003f5631501320313557</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>1996-04-05T00:00:00.0000000Z</td>\n",
" <td>29</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2025-08-20T14:01:13.0000000Z</td>\n",
" <td>NaN</td>\n",
" <td>10000001583275_0055003f5631501320313557</td>\n",
" <td>MW4167267833</td>\n",
" <td>Monica</td>\n",
" <td>Wong</td>\n",
" <td>1985-02-17T00:00:00.0000000Z</td>\n",
" <td>40</td>\n",
" <td>Asian</td>\n",
" <td>Female</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 147 columns</p>\n",
"</div>"
],
"text/plain": [
" MeasurementDate Comment \\\n",
"0 2025-09-05T14:56:27.0000000Z NaN \n",
"1 2025-09-03T13:16:22.0000000Z NaN \n",
"2 2025-09-03T13:14:23.0000000Z NaN \n",
"3 2025-08-27T20:57:32.0000000Z NaN \n",
"4 2025-08-20T14:01:13.0000000Z NaN \n",
"\n",
" ExternalDeviceId ExternalPatientId FirstName \\\n",
"0 10000001583275_0055003f5631501320313557 LD5163301170 Lucy \n",
"1 10000001583275_0055003f5631501320313557 NS6479273340 Niyanta \n",
"2 10000001583275_0055003f5631501320313557 NaN NaN \n",
"3 10000001583275_0055003f5631501320313557 NaN NaN \n",
"4 10000001583275_0055003f5631501320313557 MW4167267833 Monica \n",
"\n",
" LastName BirthDate Age Ethnicity Gender ... \\\n",
"0 Dibenedetto 1997-08-28T00:00:00.0000000Z 28 Caucasian Female ... \n",
"1 Shah 1985-03-11T00:00:00.0000000Z 40 Other Female ... \n",
"2 NaN 1985-03-11T00:00:00.0000000Z 40 NaN NaN ... \n",
"3 NaN 1996-04-05T00:00:00.0000000Z 29 NaN NaN ... \n",
"4 Wong 1985-02-17T00:00:00.0000000Z 40 Asian Female ... \n",
"\n",
" Child_XC Child_XC_Unit Child_BIVA_ZRh Child_BIVA_ZXcH Child_PhA \\\n",
"0 NaN NaN NaN NaN NaN \n",
"1 NaN NaN NaN NaN NaN \n",
"2 NaN NaN NaN NaN NaN \n",
"3 NaN NaN NaN NaN NaN \n",
"4 NaN NaN NaN NaN NaN \n",
"\n",
" Child_PhA_Unit Child_REE_Kcal Child_REE_MJ Child_TEE_Kcal Child_TEE_MJ \n",
"0 NaN NaN NaN NaN NaN \n",
"1 NaN NaN NaN NaN NaN \n",
"2 NaN NaN NaN NaN NaN \n",
"3 NaN NaN NaN NaN NaN \n",
"4 NaN NaN NaN NaN NaN \n",
"\n",
"[5 rows x 147 columns]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(\"Data shape:\", df.shape)\n",
"print(\"Columns:\", df.columns.tolist())\n",
"print(\"\\nFirst few rows:\")\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "77d3b19a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Looking for body composition related columns:\n",
"Relevant columns: ['Adult_TBS_FatScore', 'Adult_TBS_FatScore_Unit']\n",
"\n",
"Looking for patient data:\n",
"Patient column names: ['ExternalPatientId', 'FirstName', 'LastName']\n"
]
}
],
"source": [
"# Let's look for relevant columns for body composition\n",
"print(\"Looking for body composition related columns:\")\n",
"relevant_cols = [col for col in df.columns if any(word in col.lower() for word in ['fat', 'lean', 'mass', 'percent', 'composition'])]\n",
"print(\"Relevant columns:\", relevant_cols)\n",
"\n",
"# Let's also check if we have specific data for a patient like Keirstyn\n",
"print(\"\\nLooking for patient data:\")\n",
"if 'Name' in df.columns or 'Patient' in df.columns:\n",
" print(df[df.columns[df.columns.str.contains('name|patient', case=False, na=False)]].head())\n",
"else:\n",
" print(\"Patient column names:\", [col for col in df.columns if 'name' in col.lower() or 'patient' in col.lower()])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "0bd23e00",
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from matplotlib.patches import Rectangle\n",
"import seaborn as sns\n",
"\n",
"# Set the style for better-looking plots\n",
"plt.style.use('default')\n",
"sns.set_palette(\"husl\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "ebe2ef60",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Body composition visualization created!\n",
"Fat Mass: 27.6 lbs (22.4%)\n",
"Lean Mass: 95.4 lbs (77.6%)\n",
"Total Body Mass: 123.0 lbs\n",
"Body Fat Percentage: 22.4%\n"
]
},
{
"data": {
"image/png": "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1kMPPPCA2/4WLVpYlZWVlmVZ1vfff++2Lzg42Fq6dKnr3Hnz5lkOh6PWlmSVlZVuLahSU1PdWk0d3tIsISHBKikpqddz8u6771Z7/PU995A//vGPbuePHTvWKi4uduW+8sor3fafeuqpbucf2SrpzDPPdGX4+OOPq+WbNGmSVVVVZVmWZT3xxBNu+y677DK3ax/Zkiw5OdnavHmza//zzz/vtj86OtoqKCiwLMuy1q5d6/aaBAUFWYsXL3adu3r1ais2Ntbt/E8//dSyLMvKzMx02/6f//yn2vO2bds264UXXrD27Nnj2lZbS7L67q/reW3I16xXr17WgQMHLMuyrPz8fCsjI8Nt/+HPGwAAAACYREsy4BgcarG0cOFCt+1z5sxxW582bZqaNGniWr/99tuVkpLiWs/MzNQPP/wgSZo/f77buePHj9epp57qWh85cqSGDh1aa6aAgADddNNNrvVdu3bpgw8+kCRt3bpVS5Ysce2bNGmSQkNDj/Ioa2dZVr2Praqq0scff+y27ZFHHnG1sgoICNAjjzyikJAQ1/5ly5Zp3759tV7z7rvvduXv379/tf3333+/axysI5+zzMzMOvNOmTJFbdu2da1feeWVat++vWs9Pz9f3377rSRp7ty5bs/F+PHj3cat69q1q6688kq363/00UeSnC28IiMjXdufeeYZPf/88/r888+1fft2WZaltLQ0/fnPf1ZycnKdmT2tIV6zv/3tb2ratKkkKSoqSkOGDHHbf7TXBQAAAAC8hSIZUIOtW7fKsixVVVVp586dmjp1qmtfYWGhLr30UreuiId3s5Scg9gfLigoyK3b5aF7SNL27dvrPFdyFl3qcumllyopKcm1/uyzz0qSXn/9ddc2h8NR46D6tWnWrFm1bUc+zrocOHDAbeD5kJAQdezY0e2YJk2aqFWrVq51y7LqvMfhz010dLTbvpiYGLVs2bLW/Ud2HT1S9+7d3dYdDocyMjLcth16rY72ektSjx493NYPvd4hISG6++67Xdu/++47XXPNNTrzzDOVnp6uJk2aaMyYMa6imjc1xGvWp08ft/XY2Fi39aO9LgAAAADgLRTJgDo4HA6lpqbqqaeeUnp6umv7rl27XK2KpOotrGqbMbChhIWF6frrr3etL1q0SD///LPb2GdDhw5Vu3bt6n3N3r17V2t19sknn9T7/GNpdVZfh7fOCwhwf/uKi4vz+P1qc6Kv92233eaaFTMtLc3t/Ly8PM2dO1djx47VP//5T4/kra+GeM3i4+Pd1g8fKw4AAAAAfAlFMqCejmwBs2fPHtf3rVu3dtu3evVqt/WKigqtXbvWbduhcw5vlSNJa9asqXbvn3/++aj5rr32WrdufFdeeaU2bNjgWq/vgP2HREZGauzYsW7bpk+fXmfXOun3lkEJCQlug+uXlZVp48aNbsfm5ORox44drnWHw+FWjPSmI18zSdVes7S0NElHf70l6aeffnJbP/KcIUOG6PXXX9e2bdtUWFioDRs2aMaMGW7P2eOPP17v/J4ozDa21wwAAAAAPIkiGVAPixYtqla8OnyMsbPPPttt33333afc3FzX+vTp07V79263c3v16iVJGjZsmNu5s2bNcptNc/78+fr888+PmrFp06a67LLLXOuHj0WWkpKicePGHfUaR3rwwQf
"text/plain": [
"<Figure size 1500x1200 with 4 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Sample data based on the image (you can replace with actual data from your dataset)\n",
"fat_mass = 27.6 # lbs\n",
"lean_mass = 95.4 # lbs\n",
"body_fat_percent = 22.4\n",
"\n",
"# Calculate total body mass\n",
"total_mass = fat_mass + lean_mass\n",
"\n",
"# Data for pie chart\n",
"sizes = [fat_mass, lean_mass]\n",
"labels = [f'Fat Mass ({fat_mass}lbs)\\n{fat_mass/total_mass*100:.1f}%', \n",
" f'Lean Mass ({lean_mass}lbs)\\n{lean_mass/total_mass*100:.1f}%']\n",
"colors = ['#ff9999', '#ffcc99'] # Light red/orange colors\n",
"\n",
"# Create the figure\n",
"fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12))\n",
"\n",
"# 1. Body Composition Pie Chart\n",
"wedges, texts, autotexts = ax1.pie(sizes, labels=labels, colors=colors, autopct='', \n",
" startangle=90, pctdistance=0.85)\n",
"\n",
"# Add a circle at the center to create a donut chart\n",
"centre_circle = plt.Circle((0,0), 0.70, fc='white')\n",
"ax1.add_artist(centre_circle)\n",
"\n",
"ax1.set_title('Body Composition', fontsize=16, fontweight='bold', pad=20)\n",
"ax1.axis('equal')\n",
"\n",
"# 2. Body Fat Percentage Bar Chart\n",
"ax2.barh([0], [body_fat_percent], color='orange', height=0.3, alpha=0.7)\n",
"ax2.set_xlim(0, 50)\n",
"ax2.set_ylim(-0.5, 0.5)\n",
"ax2.set_xlabel('Body Fat Percentage (%)', fontsize=12)\n",
"ax2.set_title(f'Body Fat Percent - {body_fat_percent}%', fontsize=16, fontweight='bold')\n",
"ax2.set_yticks([])\n",
"\n",
"# Add percentage ranges for context\n",
"ranges = [(0, 15, 'red'), (15, 20, 'yellow'), (20, 25, 'lightgreen'), \n",
" (25, 30, 'yellow'), (30, 50, 'red')]\n",
"for i, (start, end, color) in enumerate(ranges):\n",
" ax2.axvspan(start, end, alpha=0.3, color=color, ymin=0.3, ymax=0.7)\n",
"\n",
"# Add a marker for current value\n",
"ax2.axvline(x=body_fat_percent, color='black', linestyle='--', linewidth=2)\n",
"ax2.text(body_fat_percent, 0.2, f'{body_fat_percent}%', ha='center', va='bottom', \n",
" fontsize=12, fontweight='bold')\n",
"\n",
"print(f\"Body composition visualization created!\")\n",
"print(f\"Fat Mass: {fat_mass} lbs ({fat_mass/total_mass*100:.1f}%)\")\n",
"print(f\"Lean Mass: {lean_mass} lbs ({lean_mass/total_mass*100:.1f}%)\")\n",
"print(f\"Total Body Mass: {total_mass} lbs\")\n",
"print(f\"Body Fat Percentage: {body_fat_percent}%\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "622f0788",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAMVCAYAAACm0EewAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjYsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvq6yFwwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAqDVJREFUeJzs3XmczXX///HnZ/ZhFmOMYcYYs5QRIkuWsrsSIZGURHK1klCXUly2SuVKqZBkKdFqu7paZG+xJFFJJruMhkxmxjZjZs7n94ev83PM4jDjc+YzHvfb7dw4n+28znnN5zjz9P68j2GapikAAAAAAADAQl6eLgAAAAAAAABXHkIpAAAAAAAAWI5QCgAAAAAAAJYjlAIAAAAAAIDlCKUAAAAAAABgOUIpAAAAAAAAWI5QCgAAAAAAAJYjlAIAAAAAAIDlCKUAAAAAAABgOUIpAECZYBhGgTcfHx+Fhobqmmuu0T333KMvvvjCI/WNGTPGpa45c+Z45HGLutWvX9+Smty1evXqIusNDg5WrVq19M9//lPff/+9p8u9IhXWowULFhS6T+fOnfNtX6NGDeuKLqOWLVumhx56SNdee60qVaokX19fBQcHO9/7PvjgA2VlZTm337t3r0sPWrdu7bniAQBXLEIpAECZlpeXp8zMTP32229677331KlTJ913332eLqtMmzNnjssvu2PGjLksj3P8+HFt375dM2fOVNOmTfXUU09dlscpiy53j1577bUCl+/YsUOff/55iT5WSbn33ntdXpPVq1d7uiS3bN++XY0bN9ZNN92k6dOn65dfflFaWppyc3N1/Phx53vfXXfdpaefftrT5V6SGjVquPQGAFB2+Hi6AAAALoeOHTuqXLlyysnJ0ZYtW7R//37nutmzZ6tnz57q2LGjByv0jNjYWDVq1KjAdXFxcRZXc3HKlSvn7NmxY8e0ceNGHT16VJJkmqZefPFFXX311YSOpcDXX3+tn376SfXq1XNZ/vrrr8s0TQ9VVfZs2LBB7dq104kTJ1yWx8fHKykpSQ6HQ7t27dKOHTskSQ6HwxNlAgBQKEIpAECZNHXqVOclQTk5ObrxxhtdLvFasWLFFRlKtW7d2rJLB0taRESEPvnkE+f9tLQ0tW7dWlu3bnUu+89//kMoVUq89tprmjlzpvN+ZmambX/2SqO///5bXbp0cQmkoqOj9e6776pt27Yu2+7Zs0evvvqqfH19rS4TAIAicfkeAKDM8/X1VcuWLV2WnTp1qsBtjx8/rtdff13t27dXZGSk/Pz8FBoaqmuvvVaDBw/Wb7/9Vujj/P333xo6dKhiY2Pl7++v6tWra+DAgTp8+HCh+6xdu9blspS77767wO26du3qst25Qczl8O2332ro0KFq06aNEhISFBYW5pyfq27dunr44Yf1008/uexz9pKw/v37uywfO3bsZblULDw8XMOGDXNZ9ttvv+n48eMuy06dOqU333xTHTp0UJUqVZw9bdSokcaOHau0tLQCj3/+nEenT5/WSy+9pGuvvVbly5fPdxmRaZr673//qzvvvFMJCQkKCgpSYGCgqlevro4dO2ratGkFPs4333yjfv366aqrrlJQUJACAgIUFxenfv36aePGjQXuU9ClZps3b9Ydd9yhypUry9/fX4mJiRo1apSys7Od+13uHkVFRTn/Pn/+fB05csR5f9asWTp27JikM+FJUbKzs/Xiiy/qrrvu0rXXXquoqCgFBAQoICBAUVFRuummmzRt2jSdPn26wP03bNigfv36qWbNmipfvrx8fX0VERGha665RnfccYcmTpyo1NRUSf//tXznnXdcjtGmTZsiL+f7888/NXr0aDVt2lQVK1aUr6+vKlWqpPbt22vmzJnKycnJV9f5c3Dde++9Onz4sB599FHFxcXJz8/P7bmdXnjhBf3111/O++XKldPy5cvzBVLSmVGQkydP1rPPPlvkMXNzczV58mRdd911KleunEJDQ3XzzTdr/fr1+bYtTo/cfR3OXra3b98+l/3Pn5MMAGBjJgAAZYAkl9uePXuc606fPm02adLEZf3s2bPzHWPLli1mjRo18h3r3JuPj4/5n//8J9++Bw4cMOPj4wvcp2rVqmbv3r0LffzmzZs7l/v5+Zmpqakuxz5y5Ijp6+vr3ObGG290+3UZPXq0y+P269fPrf0GDhxY5OsgyfT29jZnzpzp3Gf27NkX3EeSOXr0aLdqWLVqlct+sbGx+bb57LPP8h3/4MGDzvXbtm0zr7766iLrqVKlirl27dp8xz6/h+3atcu371mHDx82W7VqVeTjnF9/Tk6O2b9//yL3MQzDHDVqVL7a+vXr57Ld3XffbXp7exd4jG7dulnWo1atWpnt27d33n/uuedM0zTNvLw8l/PjueeeK/K1+euvv9yq87rrrjPT09Nd9v3www9NLy+vC+776aefFvhaFnZbtWqV8zEWLlxohoSEFLn99ddfn+9cPv/1atOmjVmtWrV8r6E7zt9v8ODBbu131p49e/K9li1btizwufj7+5vr168vsR65+zrExsa69RgAAPvi8j0AQJn0yCOPqFy5csrNzdWWLVtc/qe9RYsW6t27t8v2R44cUYcOHXTo0CHnsvDwcDVo0EApKSnatm2bpDMjCZ544glVqVLFZVTTvffeq927dzvv+/r6qkmTJsrNzdXGjRs1f/78Qmv917/+pdtuu02SdPr0ac2YMUMjR450rv/www9dRl089NBDF/tyOK1evVq33357gesGDRrkMkrDy8tLV199tSIiIhQWFqacnBzt3bvXOVosLy9PAwcOVMeOHVW1alXVqFFDPXr00L59+/TDDz84j1OrVi1dc801zvvn/r24fvzxR5f7vr6+Cg8PlyQdPXpUN910kw4cOOBcn5iYqJo1a+rQoUPOGlNTU9WlSxf9/PPPLiN9zvXnn3/qzz//VPny5dWgQQMFBAQ4RzHl5eWpU6dOLs9Zkq6++molJibq2LFj+dZJ0mOPPabZs2c77wcHB6tJkyby8vLS2rVrdfz4cZmmqfHjxysqKqrIvs+bN0/+/v664YYbdPToUf3yyy/OdYsXL9batWvVvHlzS3r02GOPafny5ZKkadOmafjw4frss8+c50fVqlXVs2dPPfPMMxc8Vnh4uOLj4xUWFqbAwEClp6dr8+bNyszMlCRt3rxZo0eP1quvvurcZ9SoUc65k7y8vNS4cWNFRkYqLS1NKSkp2rdvn8u8Vo0bN9bx48f1ww8/uLxPtGzZUhEREc77Z/++du1a9erVy3lOGoahhg0bqkqVKvrtt9+0a9cuSdL333+v2267Td99912ho3lWrVolSapcubLq16+vkydPys/P74Kvy/79+11+riWpU6dOF9yvKJs3b5Z0ZlLxq666Shs2bHC+ztnZ2Ro1apS++uqrfPtdSo/OV9jr0KlTJx0+fFhffPGFTp486dy+R48exXquAIBSxNOpGAAAJUFu/G+6JDMhIcHctWtXvv2feuopl+2aNGliHj161Ll+/PjxLuujo6PNvLw80zRN84cffnBZ5+vra65bt8657xdffGEahuGyzbkjpfLy8lxG81SrVs3Myclxrj93JFWlSpXMrKwst1+X80dKFXU7t6YdO3bkG91w1htvvOGy37Rp01zWnz8ax91RN+craqTUsWPHzI8++ijfaJWbb77Zuc3IkSNd1r3wwgsux58/f77L+kGDBrmsP//1qV+/vnngwAHn+rN9mDVrlst2gYGBzlE459b77rvvOu8nJye7jOa5/vrrzYyMDOf6Q4cOmTExMc714eHhZnZ2tnP9+aN7QkNDzS1bthS6fuzYsS71XK4etWrVyszLyzMTExOdyz788EOzTZs2zvvjx4/PN0rn/JFS2dnZ5s8//2w6HI58j5mZmWnGxcU5961SpYrL+nNHFY4bNy7f/qmpqea7775r/vbbby7Lz3/Nzh0Zda4bb7zRuY2Pj4/59ddfO9c5HA7zwQcfdDnOJ598UujrJcm85557XM5pd87v77//Pt9xtm/ffsH9znV+DySZ9913n5mbm2uapmlu377d9PP
"text/plain": [
"<Figure size 1200x800 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Body Fat Percent Master Chart created!\n",
"Patient's body fat percentage (22.4%) is marked on the chart.\n"
]
}
],
"source": [
"# Create the Body Fat Percent Master Chart\n",
"fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8))\n",
"\n",
"# Age groups and corresponding y-positions\n",
"age_groups = ['20-39', '40-59', '60-79']\n",
"y_positions = [2, 1, 0]\n",
"\n",
"# Body fat percentage ranges and colors (similar to the image)\n",
"# Red: 0-10%, 40-50% (high risk)\n",
"# Yellow: 10-15%, 15-20%, 35-40% (moderate risk) \n",
"# Green: 20-35% (healthy range)\n",
"\n",
"ranges_male = [\n",
" (0, 5, '#ff6b6b'), # Red - too low\n",
" (5, 10, '#ffd93d'), # Yellow - low\n",
" (10, 15, '#6bcf7f'), # Green - healthy\n",
" (15, 20, '#6bcf7f'), # Green - healthy\n",
" (20, 25, '#ffd93d'), # Yellow - moderate\n",
" (25, 30, '#ff6b6b'), # Red - high\n",
" (30, 35, '#ff6b6b'), # Red - very high\n",
" (35, 40, '#ff6b6b'), # Red - extremely high\n",
" (40, 45, '#ff6b6b'), # Red - extremely high\n",
" (45, 50, '#ff6b6b') # Red - extremely high\n",
"]\n",
"\n",
"ranges_female = [\n",
" (0, 10, '#ff6b6b'), # Red - too low\n",
" (10, 15, '#ffd93d'), # Yellow - low\n",
" (15, 20, '#ffd93d'), # Yellow - moderate\n",
" (20, 25, '#6bcf7f'), # Green - healthy\n",
" (25, 30, '#6bcf7f'), # Green - healthy\n",
" (30, 35, '#6bcf7f'), # Green - healthy\n",
" (35, 40, '#ffd93d'), # Yellow - moderate\n",
" (40, 45, '#ff6b6b'), # Red - high\n",
" (45, 50, '#ff6b6b') # Red - very high\n",
"]\n",
"\n",
"# Plot Male chart\n",
"ax1.set_title('Body Fat Percent Master Chart', fontsize=16, fontweight='bold', pad=20)\n",
"for i, age_group in enumerate(age_groups):\n",
" y = y_positions[i]\n",
" for start, end, color in ranges_male:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, edgecolor='black', linewidth=0.5)\n",
" ax1.add_patch(rect)\n",
"\n",
"ax1.set_xlim(0, 50)\n",
"ax1.set_ylim(-0.5, 2.5)\n",
"ax1.set_xlabel('Body Fat Percentage (%)', fontsize=12)\n",
"ax1.set_ylabel('Age (M)', fontsize=12)\n",
"ax1.set_yticks(y_positions)\n",
"ax1.set_yticklabels(age_groups)\n",
"ax1.set_xticks(range(0, 51, 5))\n",
"ax1.grid(True, alpha=0.3)\n",
"\n",
"# Add vertical lines for reference\n",
"for x in range(0, 51, 5):\n",
" ax1.axvline(x=x, color='black', linewidth=0.5, alpha=0.3)\n",
"\n",
"# Plot Female chart \n",
"for i, age_group in enumerate(age_groups):\n",
" y = y_positions[i]\n",
" for start, end, color in ranges_female:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, edgecolor='black', linewidth=0.5)\n",
" ax2.add_patch(rect)\n",
"\n",
"ax2.set_xlim(0, 50)\n",
"ax2.set_ylim(-0.5, 2.5)\n",
"ax2.set_xlabel('Body Fat Percentage (%)', fontsize=12)\n",
"ax2.set_ylabel('Age (F)', fontsize=12)\n",
"ax2.set_yticks(y_positions)\n",
"ax2.set_yticklabels(age_groups)\n",
"ax2.set_xticks(range(0, 51, 5))\n",
"ax2.grid(True, alpha=0.3)\n",
"\n",
"# Add vertical lines for reference\n",
"for x in range(0, 51, 5):\n",
" ax2.axvline(x=x, color='black', linewidth=0.5, alpha=0.3)\n",
"\n",
"# Mark the current patient's value (assuming female, 20-39 age group)\n",
"patient_age_group = 0 # 20-39 age group\n",
"ax2.axvline(x=body_fat_percent, color='black', linestyle='--', linewidth=2)\n",
"ax2.plot(body_fat_percent, y_positions[patient_age_group], 'v', color='black', markersize=10)\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"print(f\"Body Fat Percent Master Chart created!\")\n",
"print(f\"Patient's body fat percentage ({body_fat_percent}%) is marked on the chart.\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "732c3859",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_221522/2454516635.py:109: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.\n",
" plt.tight_layout()\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1200x1000 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Complete body composition analysis visualization created!\n"
]
}
],
"source": [
"# Create a combined visualization matching the original image more closely\n",
"fig = plt.figure(figsize=(12, 10))\n",
"\n",
"# Create custom grid layout\n",
"gs = fig.add_gridspec(3, 2, height_ratios=[2, 1, 2], width_ratios=[1, 1], hspace=0.3, wspace=0.3)\n",
"\n",
"# 1. Body Composition Pie Chart (top left)\n",
"ax1 = fig.add_subplot(gs[0, 0])\n",
"\n",
"# Create donut chart\n",
"sizes = [fat_mass, lean_mass]\n",
"colors = ['#ff9999', '#ffcc99'] # Light coral and peach colors\n",
"wedges, texts = ax1.pie(sizes, colors=colors, startangle=90, counterclock=False, \n",
" wedgeprops=dict(width=0.5))\n",
"\n",
"# Add labels inside the chart\n",
"ax1.text(0, 0.2, f'Fat Mass ({fat_mass}lbs)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
"ax1.text(0, 0, f'{fat_mass/total_mass*100:.1f}%', ha='center', va='center', fontsize=12, fontweight='bold')\n",
"ax1.text(0, -0.2, f'Lean Mass ({lean_mass}lbs)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
"ax1.text(0, -0.4, f'{lean_mass/total_mass*100:.1f}%', ha='center', va='center', fontsize=12, fontweight='bold')\n",
"\n",
"ax1.set_title('Body Composition', fontsize=14, fontweight='bold', pad=20)\n",
"\n",
"# 2. Body Fat Percentage indicator (top right)\n",
"ax2 = fig.add_subplot(gs[0, 1])\n",
"ax2.text(0.5, 0.7, f'Body Fat Percent - {body_fat_percent}%', ha='center', va='center', \n",
" fontsize=16, fontweight='bold', transform=ax2.transAxes)\n",
"\n",
"# Create horizontal bar for current age group (20-39 F)\n",
"bar_ranges = [(0, 10, '#ff6b6b'), (10, 15, '#ff6b6b'), (15, 20, '#ffd93d'), \n",
" (20, 25, '#6bcf7f'), (25, 30, '#6bcf7f'), (30, 35, '#6bcf7f'),\n",
" (35, 40, '#ffd93d'), (40, 45, '#ff6b6b'), (45, 50, '#ff6b6b')]\n",
"\n",
"y_pos = 0.4\n",
"bar_height = 0.1\n",
"for start, end, color in bar_ranges:\n",
" width = (end - start) / 50 # Normalize to 0-1 range\n",
" x_start = start / 50\n",
" rect = plt.Rectangle((x_start, y_pos), width, bar_height, facecolor=color, \n",
" alpha=0.7, edgecolor='black', linewidth=0.5, transform=ax2.transAxes)\n",
" ax2.add_patch(rect)\n",
"\n",
"# Add percentage labels\n",
"for pct in [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]:\n",
" x_pos = pct / 50\n",
" ax2.text(x_pos, 0.3, f'{pct}%', ha='center', va='top', fontsize=8, \n",
" transform=ax2.transAxes)\n",
"\n",
"# Add arrow pointing to current value\n",
"current_x = body_fat_percent / 50\n",
"ax2.arrow(current_x, 0.6, 0, -0.05, head_width=0.02, head_length=0.02, \n",
" fc='black', ec='black', transform=ax2.transAxes)\n",
"\n",
"ax2.text(0.1, 0.2, '20-39\\n(F)', ha='center', va='center', fontsize=10, \n",
" transform=ax2.transAxes)\n",
"ax2.set_xlim(0, 1)\n",
"ax2.set_ylim(0, 1)\n",
"ax2.axis('off')\n",
"\n",
"# 3. Full Body Fat Percent Master Chart (bottom)\n",
"ax3 = fig.add_subplot(gs[2, :])\n",
"\n",
"age_groups = ['20-39', '40-59', '60-79']\n",
"y_positions = [2, 1, 0]\n",
"\n",
"# Male ranges (top)\n",
"for i, age_group in enumerate(age_groups):\n",
" y = y_positions[i] + 3\n",
" for start, end, color in ranges_male:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, \n",
" edgecolor='black', linewidth=0.5)\n",
" ax3.add_patch(rect)\n",
"\n",
"# Female ranges (bottom)\n",
"for i, age_group in enumerate(age_groups):\n",
" y = y_positions[i]\n",
" for start, end, color in ranges_female:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, \n",
" edgecolor='black', linewidth=0.5)\n",
" ax3.add_patch(rect)\n",
"\n",
"ax3.set_xlim(0, 50)\n",
"ax3.set_ylim(-0.5, 5.5)\n",
"ax3.set_xlabel('Body Fat Percentage (%)', fontsize=12)\n",
"ax3.set_title('Body Fat Percent Master Chart', fontsize=14, fontweight='bold')\n",
"\n",
"# Set y-axis labels\n",
"y_labels = ['20-39', '40-59', '60-79', '20-39', '40-59', '60-79']\n",
"y_tick_positions = [0, 1, 2, 3, 4, 5]\n",
"ax3.set_yticks(y_tick_positions)\n",
"ax3.set_yticklabels(y_labels)\n",
"\n",
"# Add age group labels\n",
"ax3.text(-3, 1, 'Age (F)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
"ax3.text(-3, 4, 'Age (M)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
"\n",
"ax3.set_xticks(range(0, 51, 5))\n",
"ax3.grid(True, alpha=0.3)\n",
"\n",
"# Mark patient's position (assuming 20-39 female)\n",
"ax3.axvline(x=body_fat_percent, color='black', linestyle='--', linewidth=2, alpha=0.8)\n",
"ax3.plot(body_fat_percent, 2, 'v', color='black', markersize=12) # Triangle pointing down\n",
"\n",
"plt.suptitle('Nutrition Guidelines\\nUltrasound & Body Composition Assessment', \n",
" fontsize=16, fontweight='bold', y=0.95)\n",
"\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"print(\"Complete body composition analysis visualization created!\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "cff16154",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\\n==================================================\n",
"SAMPLE USAGE:\n",
"==================================================\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_221522/3354465480.py:138: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.\n",
" plt.tight_layout()\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1200x1000 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Results: {'total_mass': 123.0, 'body_fat_percent': 22.439024390243905, 'fat_mass_percent': 22.439024390243905, 'lean_mass_percent': 77.5609756097561}\n"
]
}
],
"source": [
"def create_body_composition_chart(fat_mass_lbs, lean_mass_lbs, age_group='20-39', gender='F'):\n",
" \"\"\"\n",
" Create a comprehensive body composition visualization\n",
" \n",
" Parameters:\n",
" - fat_mass_lbs: Fat mass in pounds\n",
" - lean_mass_lbs: Lean mass in pounds \n",
" - age_group: Age group ('20-39', '40-59', '60-79')\n",
" - gender: Gender ('M' or 'F')\n",
" \"\"\"\n",
" \n",
" # Calculate derived values\n",
" total_mass = fat_mass_lbs + lean_mass_lbs\n",
" body_fat_percent = (fat_mass_lbs / total_mass) * 100\n",
" \n",
" # Create the visualization\n",
" fig = plt.figure(figsize=(12, 10))\n",
" gs = fig.add_gridspec(3, 2, height_ratios=[2, 1, 2], width_ratios=[1, 1], \n",
" hspace=0.3, wspace=0.3)\n",
"\n",
" # 1. Body Composition Pie Chart\n",
" ax1 = fig.add_subplot(gs[0, 0])\n",
" sizes = [fat_mass_lbs, lean_mass_lbs]\n",
" colors = ['#ff9999', '#ffcc99']\n",
" wedges, texts = ax1.pie(sizes, colors=colors, startangle=90, counterclock=False, \n",
" wedgeprops=dict(width=0.5))\n",
"\n",
" # Add labels\n",
" ax1.text(0, 0.2, f'Fat Mass ({fat_mass_lbs}lbs)', ha='center', va='center', \n",
" fontsize=10, fontweight='bold')\n",
" ax1.text(0, 0, f'{fat_mass_lbs/total_mass*100:.1f}%', ha='center', va='center', \n",
" fontsize=12, fontweight='bold')\n",
" ax1.text(0, -0.2, f'Lean Mass ({lean_mass_lbs}lbs)', ha='center', va='center', \n",
" fontsize=10, fontweight='bold')\n",
" ax1.text(0, -0.4, f'{lean_mass_lbs/total_mass*100:.1f}%', ha='center', va='center', \n",
" fontsize=12, fontweight='bold')\n",
" ax1.set_title('Body Composition', fontsize=14, fontweight='bold', pad=20)\n",
"\n",
" # 2. Body Fat Percentage Bar\n",
" ax2 = fig.add_subplot(gs[0, 1])\n",
" ax2.text(0.5, 0.7, f'Body Fat Percent - {body_fat_percent:.1f}%', ha='center', va='center', \n",
" fontsize=16, fontweight='bold', transform=ax2.transAxes)\n",
"\n",
" # Color ranges for body fat percentage\n",
" if gender == 'F':\n",
" bar_ranges = [(0, 10, '#ff6b6b'), (10, 15, '#ff6b6b'), (15, 20, '#ffd93d'), \n",
" (20, 25, '#6bcf7f'), (25, 30, '#6bcf7f'), (30, 35, '#6bcf7f'),\n",
" (35, 40, '#ffd93d'), (40, 45, '#ff6b6b'), (45, 50, '#ff6b6b')]\n",
" else: # Male\n",
" bar_ranges = [(0, 5, '#ff6b6b'), (5, 10, '#ffd93d'), (10, 15, '#6bcf7f'), \n",
" (15, 20, '#6bcf7f'), (20, 25, '#ffd93d'), (25, 30, '#ff6b6b'),\n",
" (30, 35, '#ff6b6b'), (35, 40, '#ff6b6b'), (40, 50, '#ff6b6b')]\n",
"\n",
" y_pos = 0.4\n",
" bar_height = 0.1\n",
" for start, end, color in bar_ranges:\n",
" width = (end - start) / 50\n",
" x_start = start / 50\n",
" rect = plt.Rectangle((x_start, y_pos), width, bar_height, facecolor=color, \n",
" alpha=0.7, edgecolor='black', linewidth=0.5, transform=ax2.transAxes)\n",
" ax2.add_patch(rect)\n",
"\n",
" # Add percentage labels\n",
" for pct in [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]:\n",
" x_pos = pct / 50\n",
" ax2.text(x_pos, 0.3, f'{pct}%', ha='center', va='top', fontsize=8, \n",
" transform=ax2.transAxes)\n",
"\n",
" # Add arrow for current value\n",
" current_x = body_fat_percent / 50\n",
" ax2.arrow(current_x, 0.6, 0, -0.05, head_width=0.02, head_length=0.02, \n",
" fc='black', ec='black', transform=ax2.transAxes)\n",
"\n",
" ax2.text(0.1, 0.2, f'{age_group}\\\\n({gender})', ha='center', va='center', fontsize=10, \n",
" transform=ax2.transAxes)\n",
" ax2.set_xlim(0, 1)\n",
" ax2.set_ylim(0, 1)\n",
" ax2.axis('off')\n",
"\n",
" # 3. Master Chart\n",
" ax3 = fig.add_subplot(gs[2, :])\n",
" \n",
" age_groups = ['20-39', '40-59', '60-79']\n",
" y_positions = [2, 1, 0]\n",
" \n",
" # Male and female ranges\n",
" ranges_male = [(0, 5, '#ff6b6b'), (5, 10, '#ffd93d'), (10, 15, '#6bcf7f'), \n",
" (15, 20, '#6bcf7f'), (20, 25, '#ffd93d'), (25, 30, '#ff6b6b'),\n",
" (30, 35, '#ff6b6b'), (35, 40, '#ff6b6b'), (40, 50, '#ff6b6b')]\n",
" \n",
" ranges_female = [(0, 10, '#ff6b6b'), (10, 15, '#ff6b6b'), (15, 20, '#ffd93d'), \n",
" (20, 25, '#6bcf7f'), (25, 30, '#6bcf7f'), (30, 35, '#6bcf7f'),\n",
" (35, 40, '#ffd93d'), (40, 45, '#ff6b6b'), (45, 50, '#ff6b6b')]\n",
"\n",
" # Plot male ranges (top)\n",
" for i, age_group_name in enumerate(age_groups):\n",
" y = y_positions[i] + 3\n",
" for start, end, color in ranges_male:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, \n",
" edgecolor='black', linewidth=0.5)\n",
" ax3.add_patch(rect)\n",
"\n",
" # Plot female ranges (bottom)\n",
" for i, age_group_name in enumerate(age_groups):\n",
" y = y_positions[i]\n",
" for start, end, color in ranges_female:\n",
" width = end - start\n",
" rect = Rectangle((start, y-0.3), width, 0.6, facecolor=color, alpha=0.7, \n",
" edgecolor='black', linewidth=0.5)\n",
" ax3.add_patch(rect)\n",
"\n",
" ax3.set_xlim(0, 50)\n",
" ax3.set_ylim(-0.5, 5.5)\n",
" ax3.set_xlabel('Body Fat Percentage (%)', fontsize=12)\n",
" ax3.set_title('Body Fat Percent Master Chart', fontsize=14, fontweight='bold')\n",
"\n",
" # Set labels\n",
" y_labels = ['20-39', '40-59', '60-79', '20-39', '40-59', '60-79']\n",
" y_tick_positions = [0, 1, 2, 3, 4, 5]\n",
" ax3.set_yticks(y_tick_positions)\n",
" ax3.set_yticklabels(y_labels)\n",
"\n",
" ax3.text(-3, 1, 'Age (F)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
" ax3.text(-3, 4, 'Age (M)', ha='center', va='center', fontsize=10, fontweight='bold')\n",
"\n",
" ax3.set_xticks(range(0, 51, 5))\n",
" ax3.grid(True, alpha=0.3)\n",
"\n",
" # Mark patient's position\n",
" patient_y = age_groups.index(age_group) + (0 if gender == 'F' else 3)\n",
" ax3.axvline(x=body_fat_percent, color='black', linestyle='--', linewidth=2, alpha=0.8)\n",
" ax3.plot(body_fat_percent, patient_y, 'v', color='black', markersize=12)\n",
"\n",
" plt.suptitle('Nutrition Guidelines\\\\nUltrasound & Body Composition Assessment', \n",
" fontsize=16, fontweight='bold', y=0.95)\n",
"\n",
" plt.tight_layout()\n",
" plt.show()\n",
" \n",
" return {\n",
" 'total_mass': total_mass,\n",
" 'body_fat_percent': body_fat_percent,\n",
" 'fat_mass_percent': (fat_mass_lbs/total_mass)*100,\n",
" 'lean_mass_percent': (lean_mass_lbs/total_mass)*100\n",
" }\n",
"\n",
"# Example usage with the sample data\n",
"print(\"\\\\n\" + \"=\"*50)\n",
"print(\"SAMPLE USAGE:\")\n",
"print(\"=\"*50)\n",
"result = create_body_composition_chart(fat_mass_lbs=27.6, lean_mass_lbs=95.4, \n",
" age_group='20-39', gender='F')\n",
"print(f\"Results: {result}\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "report_generation",
"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
}