Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Mammal Data Correlations</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/regression"></script> | |
| <style> | |
| body { | |
| font-family: Arial, sans-serif; | |
| margin: 20px; | |
| background-color: #f9f9f9; | |
| } | |
| .chartContainer { | |
| width: 80%; | |
| margin: 20px auto; | |
| background-color: white; | |
| padding: 20px; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
| } | |
| .accuracy { | |
| text-align: center; | |
| margin-top: 20px; | |
| } | |
| table { | |
| width: 80%; | |
| margin: 20px auto; | |
| border-collapse: collapse; | |
| background-color: white; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
| } | |
| table, th, td { | |
| border: 1px solid black; | |
| } | |
| th, td { | |
| padding: 8px; | |
| text-align: center; | |
| } | |
| .background { | |
| width: 80%; | |
| margin: 20px auto; | |
| padding: 20px; | |
| background-color: white; | |
| border-radius: 10px; | |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); | |
| } | |
| .attribution { | |
| text-align: center; | |
| margin-top: 20px; | |
| font-style: italic; | |
| color: #555; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>Mammal Data Correlations</h1> | |
| <!-- Background Section --> | |
| <div class="background"> | |
| <h2>Background</h2> | |
| <p> | |
| This project investigates the relationship between gestation periods and various biological traits in mammals. | |
| The central question is: <strong>How does the time for gestation correlate with brain size, baby size, and baby volume?</strong> | |
| By analyzing data from a variety of mammals, we aim to uncover patterns and trends that can help us understand the evolutionary and biological significance of gestation periods. | |
| </p> | |
| </div> | |
| <!-- Chart 1: Gestation vs. Brain Size --> | |
| <div class="chartContainer"> | |
| <h2>Gestation Period vs. Brain Size</h2> | |
| <canvas id="chart1"></canvas> | |
| <div class="accuracy"> | |
| <p>Best Fit: <span id="bestFit1"></span> (R²: <span id="bestFitAccuracy1"></span>)</p> | |
| <p>Equation: <span id="equation1"></span></p> | |
| <p>Other Models:</p> | |
| <ul> | |
| <li>Linear: R² = <span id="linearAccuracy1"></span></li> | |
| <li>Exponential: R² = <span id="expAccuracy1"></span></li> | |
| <li>Quadratic: R² = <span id="quadAccuracy1"></span></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Chart 2: Gestation vs. Baby Size --> | |
| <div class="chartContainer"> | |
| <h2>Gestation Period vs. Baby Size</h2> | |
| <canvas id="chart2"></canvas> | |
| <div class="accuracy"> | |
| <p>Best Fit: <span id="bestFit2"></span> (R²: <span id="bestFitAccuracy2"></span>)</p> | |
| <p>Equation: <span id="equation2"></span></p> | |
| <p>Other Models:</p> | |
| <ul> | |
| <li>Linear: R² = <span id="linearAccuracy2"></span></li> | |
| <li>Exponential: R² = <span id="expAccuracy2"></span></li> | |
| <li>Quadratic: R² = <span id="quadAccuracy2"></span></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Chart 3: Gestation vs. Baby Volume --> | |
| <div class="chartContainer"> | |
| <h2>Gestation Period vs. Baby Volume</h2> | |
| <canvas id="chart3"></canvas> | |
| <div class="accuracy"> | |
| <p>Best Fit: <span id="bestFit3"></span> (R²: <span id="bestFitAccuracy3"></span>)</p> | |
| <p>Equation: <span id="equation3"></span></p> | |
| <p>Other Models:</p> | |
| <ul> | |
| <li>Linear: R² = <span id="linearAccuracy3"></span></li> | |
| <li>Exponential: R² = <span id="expAccuracy3"></span></li> | |
| <li>Quadratic: R² = <span id="quadAccuracy3"></span></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Chart 4: Gestation vs. Brain-to-Baby Size Ratio --> | |
| <div class="chartContainer"> | |
| <h2>Gestation Period vs. Brain-to-Baby Size Ratio</h2> | |
| <canvas id="chart4"></canvas> | |
| <div class="accuracy"> | |
| <p>Best Fit: <span id="bestFit4"></span> (R²: <span id="bestFitAccuracy4"></span>)</p> | |
| <p>Equation: <span id="equation4"></span></p> | |
| <p>Other Models:</p> | |
| <ul> | |
| <li>Linear: R² = <span id="linearAccuracy4"></span></li> | |
| <li>Exponential: R² = <span id="expAccuracy4"></span></li> | |
| <li>Quadratic: R² = <span id="quadAccuracy4"></span></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- Table --> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Mammal</th> | |
| <th>Gestation (Days)</th> | |
| <th>Brain Size (grams)</th> | |
| <th>Baby Size (kg)</th> | |
| <th>Baby Volume (liters)</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>African Elephant</td> | |
| <td>655</td> | |
| <td>2300</td> | |
| <td>120</td> | |
| <td>90</td> | |
| </tr> | |
| <tr> | |
| <td>Asian Elephant</td> | |
| <td>617</td> | |
| <td>2000</td> | |
| <td>100</td> | |
| <td>80</td> | |
| </tr> | |
| <tr> | |
| <td>Sperm Whale</td> | |
| <td>535</td> | |
| <td>7800</td> | |
| <td>1000</td> | |
| <td>1000</td> | |
| </tr> | |
| <tr> | |
| <td>Orca</td> | |
| <td>532</td> | |
| <td>3500</td> | |
| <td>180</td> | |
| <td>180</td> | |
| </tr> | |
| <tr> | |
| <td>Indian Rhinoceros</td> | |
| <td>478</td> | |
| <td>400</td> | |
| <td>60</td> | |
| <td>60</td> | |
| </tr> | |
| <tr> | |
| <td>White Rhinoceros</td> | |
| <td>467</td> | |
| <td>350</td> | |
| <td>50</td> | |
| <td>50</td> | |
| </tr> | |
| <tr> | |
| <td>Giraffe</td> | |
| <td>430</td> | |
| <td>500</td> | |
| <td>100</td> | |
| <td>100</td> | |
| </tr> | |
| <tr> | |
| <td>Bactrian Camel</td> | |
| <td>390</td> | |
| <td>300</td> | |
| <td>35</td> | |
| <td>35</td> | |
| </tr> | |
| <tr> | |
| <td>Bottlenose Dolphin</td> | |
| <td>364</td> | |
| <td>750</td> | |
| <td>15</td> | |
| <td>15</td> | |
| </tr> | |
| <tr> | |
| <td>Horse</td> | |
| <td>336</td> | |
| <td>400</td> | |
| <td>50</td> | |
| <td>50</td> | |
| </tr> | |
| <tr> | |
| <td>Human</td> | |
| <td>270</td> | |
| <td>350</td> | |
| <td>3.5</td> | |
| <td>3.5</td> | |
| </tr> | |
| <tr> | |
| <td>Gorilla</td> | |
| <td>257</td> | |
| <td>200</td> | |
| <td>2</td> | |
| <td>2</td> | |
| </tr> | |
| <tr> | |
| <td>Chimpanzee</td> | |
| <td>240</td> | |
| <td>150</td> | |
| <td>1.8</td> | |
| <td>1.8</td> | |
| </tr> | |
| <tr> | |
| <td>Polar Bear</td> | |
| <td>241</td> | |
| <td>25</td> | |
| <td>0.6</td> | |
| <td>0.6</td> | |
| </tr> | |
| <tr> | |
| <td>Domestic Cat</td> | |
| <td>64</td> | |
| <td>5</td> | |
| <td>0.1</td> | |
| <td>0.1</td> | |
| </tr> | |
| <tr> | |
| <td>Domestic Dog</td> | |
| <td>61</td> | |
| <td>10</td> | |
| <td>0.3</td> | |
| <td>0.3</td> | |
| </tr> | |
| <tr> | |
| <td>Mouse</td> | |
| <td>19</td> | |
| <td>0.1</td> | |
| <td>0.001</td> | |
| <td>0.001</td> | |
| </tr> | |
| <tr> | |
| <td>Rat</td> | |
| <td>22</td> | |
| <td>0.2</td> | |
| <td>0.005</td> | |
| <td>0.005</td> | |
| </tr> | |
| <tr> | |
| <td>Virginia Opossum</td> | |
| <td>12</td> | |
| <td>0.05</td> | |
| <td>0.002</td> | |
| <td>0.002</td> | |
| </tr> | |
| <tr> | |
| <td>Kangaroo</td> | |
| <td>42</td> | |
| <td>5</td> | |
| <td>0.8</td> | |
| <td>0.8</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <!-- Attribution --> | |
| <div class="attribution"> | |
| <p>Made by Julian Herrera for 2025 Bio Class - Jan 14</p> | |
| </div> | |
| <script> | |
| // Data from the table | |
| const data = { | |
| mammals: [ | |
| "African Elephant", "Asian Elephant", "Sperm Whale", "Orca", "Indian Rhinoceros", | |
| "White Rhinoceros", "Giraffe", "Bactrian Camel", "Bottlenose Dolphin", "Horse", | |
| "Human", "Gorilla", "Chimpanzee", "Polar Bear", "Domestic Cat", "Domestic Dog", | |
| "Mouse", "Rat", "Virginia Opossum", "Kangaroo" | |
| ], | |
| gestation: [ | |
| 655, 617, 535, 532, 478, 467, 430, 390, 364, 336, 270, 257, 240, 241, 64, 61, 19, 22, 12, 42 | |
| ], | |
| brainSize: [ | |
| 2300, 2000, 7800, 3500, 400, 350, 500, 300, 750, 400, 350, 200, 150, 25, 5, 10, 0.1, 0.2, 0.05, 5 | |
| ], | |
| babySize: [ | |
| 120, 100, 1000, 180, 60, 50, 100, 35, 15, 50, 3.5, 2, 1.8, 0.6, 0.1, 0.3, 0.001, 0.005, 0.002, 0.8 | |
| ], | |
| babyVolume: [ | |
| 90, 80, 1000, 180, 60, 50, 100, 35, 15, 50, 3.5, 2, 1.8, 0.6, 0.1, 0.3, 0.001, 0.005, 0.002, 0.8 | |
| ] | |
| }; | |
| // Function to remove outliers using IQR | |
| function removeOutliers(xData, yData) { | |
| const combinedData = xData.map((x, i) => ({ x, y: yData[i] })); | |
| // Calculate quartiles and IQR for yData | |
| const sortedY = yData.slice().sort((a, b) => a - b); | |
| const Q1 = sortedY[Math.floor(sortedY.length * 0.25)]; | |
| const Q3 = sortedY[Math.floor(sortedY.length * 0.75)]; | |
| const IQR = Q3 - Q1; | |
| const lowerBound = Q1 - 1.5 * IQR; | |
| const upperBound = Q3 + 1.5 * IQR; | |
| // Filter out outliers | |
| const filteredData = combinedData.filter(point => point.y >= lowerBound && point.y <= upperBound); | |
| // Separate x and y data | |
| const filteredX = filteredData.map(point => point.x); | |
| const filteredY = filteredData.map(point => point.y); | |
| return { filteredX, filteredY }; | |
| } | |
| // Function to format the equation | |
| function formatEquation(type, coefficients) { | |
| if (type === 'Linear') { | |
| return `y = ${coefficients[0].toFixed(2)}x + ${coefficients[1].toFixed(2)}`; | |
| } else if (type === 'Exponential') { | |
| return `y = ${coefficients[0].toFixed(2)}e^(${coefficients[1].toFixed(2)}x)`; | |
| } else if (type === 'Quadratic') { | |
| return `y = ${coefficients[0].toFixed(2)}x² + ${coefficients[1].toFixed(2)}x + ${coefficients[2].toFixed(2)}`; | |
| } | |
| return ''; | |
| } | |
| // Function to create a chart with best-fit regression | |
| function createChart(canvasId, xData, yData, xLabel, yLabel, bestFitId, bestFitAccuracyId, equationId, linearAccuracyId, expAccuracyId, quadAccuracyId) { | |
| // Remove outliers | |
| const { filteredX, filteredY } = removeOutliers(xData, yData); | |
| const chartData = filteredX.map((x, index) => ({ x, y: filteredY[index] })); | |
| // Perform regressions | |
| const linear = regression.linear(chartData.map(point => [point.x, point.y])); | |
| const exp = regression.exponential(chartData.map(point => [point.x, point.y])); | |
| const quad = regression.polynomial(chartData.map(point => [point.x, point.y]), { order: 2 }); | |
| // Determine the best fit (highest R²) | |
| const regressions = [ | |
| { type: 'Linear', r2: linear.r2, points: linear, coefficients: [linear.equation[1], linear.equation[0]] }, | |
| { type: 'Exponential', r2: exp.r2, points: exp, coefficients: [exp.equation[0], exp.equation[1]] }, | |
| { type: 'Quadratic', r2: quad.r2, points: quad, coefficients: [quad.equation[2], quad.equation[1], quad.equation[0]] } | |
| ]; | |
| const bestFit = regressions.reduce((best, current) => (current.r2 > best.r2 ? current : best)); | |
| // Generate points for the best-fit regression | |
| const bestFitPoints = chartData.map(point => ({ | |
| x: point.x, | |
| y: bestFit.points.predict(point.x)[1] | |
| })); | |
| // Render the chart | |
| const ctx = document.getElementById(canvasId).getContext('2d'); | |
| const chart = new Chart(ctx, { | |
| type: 'scatter', | |
| data: { | |
| datasets: [ | |
| { | |
| label: 'Data Points', | |
| data: chartData, | |
| backgroundColor: 'rgba(75, 192, 192, 0.6)', | |
| borderColor: 'rgba(75, 192, 192, 1)', | |
| pointRadius: 5 | |
| }, | |
| { | |
| label: `${bestFit.type} Regression`, | |
| data: bestFitPoints, | |
| backgroundColor: 'rgba(255, 99, 132, 0)', | |
| borderColor: 'rgba(255, 99, 132, 1)', | |
| type: 'line', | |
| pointRadius: 0 | |
| } | |
| ] | |
| }, | |
| options: { | |
| scales: { | |
| x: { | |
| type: 'linear', | |
| position: 'bottom', | |
| title: { | |
| display: true, | |
| text: xLabel | |
| } | |
| }, | |
| y: { | |
| type: 'linear', | |
| title: { | |
| display: true, | |
| text: yLabel | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| // Display best fit, accuracy, and equation | |
| document.getElementById(bestFitId).textContent = bestFit.type; | |
| document.getElementById(bestFitAccuracyId).textContent = bestFit.r2.toFixed(4); | |
| document.getElementById(equationId).textContent = formatEquation(bestFit.type, bestFit.coefficients); | |
| // Display accuracy for all models | |
| document.getElementById(linearAccuracyId).textContent = linear.r2.toFixed(4); | |
| document.getElementById(expAccuracyId).textContent = exp.r2.toFixed(4); | |
| document.getElementById(quadAccuracyId).textContent = quad.r2.toFixed(4); | |
| } | |
| // Create charts | |
| createChart('chart1', data.gestation, data.brainSize, 'Gestation Period (Days)', 'Brain Size (grams)', 'bestFit1', 'bestFitAccuracy1', 'equation1', 'linearAccuracy1', 'expAccuracy1', 'quadAccuracy1'); | |
| createChart('chart2', data.gestation, data.babySize, 'Gestation Period (Days)', 'Baby Size (kg)', 'bestFit2', 'bestFitAccuracy2', 'equation2', 'linearAccuracy2', 'expAccuracy2', 'quadAccuracy2'); | |
| createChart('chart3', data.gestation, data.babyVolume, 'Gestation Period (Days)', 'Baby Volume (liters)', 'bestFit3', 'bestFitAccuracy3', 'equation3', 'linearAccuracy3', 'expAccuracy3', 'quadAccuracy3'); | |
| createChart('chart4', data.gestation, data.brainSize.map((brain, i) => brain / data.babySize[i]), 'Gestation Period (Days)', 'Brain-to-Baby Size Ratio', 'bestFit4', 'bestFitAccuracy4', 'equation4', 'linearAccuracy4', 'expAccuracy4', 'quadAccuracy4'); | |
| </script> | |
| </body> | |
| </html> |