should be good

This commit is contained in:
2026-03-30 21:50:22 -05:00
parent 773fe6cde8
commit 7512c6228a
7 changed files with 308 additions and 18 deletions

Binary file not shown.

255
analysis.py Normal file
View File

@@ -0,0 +1,255 @@
#!/usr/bin/env python3
"""
Linear Regression Analysis for Wire Resistance Data
Generates scatter plots with regression lines for 3 AWG gauges.
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import os
# Set sleek matplotlib style
matplotlib.style.use('default')
plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams['font.size'] = 10
plt.rcParams['axes.titlesize'] = 12
plt.rcParams['axes.labelsize'] = 11
plt.rcParams['xtick.labelsize'] = 10
plt.rcParams['ytick.labelsize'] = 10
plt.rcParams['legend.fontsize'] = 10
plt.rcParams['figure.dpi'] = 300
plt.rcParams['savefig.dpi'] = 300
plt.rcParams['savefig.bbox'] = 'tight'
plt.rcParams['savefig.pad_inches'] = 0.2
# Data from raw-data.csv
# X: Probe distance (cm)
x = np.array([20, 40, 60, 80, 100])
# Y: Resistance (Ω) for each AWG gauge
y_26 = np.array([2.6, 5.6, 4.5, 9.3, 10.0])
y_29 = np.array([4.7, 8.9, 13.6, 18.0, 22.6])
y_32 = np.array([9.0, 18.1, 27.3, 36.3, 45.4])
# Outlier flag for 26 AWG: index 2 (L=60cm) is experimental outlier with value 4.5 Ω
# Expected value based on trend from other points: ~7.0-7.5 Ω
OUTLIER_26AWG_L60 = {
'index': 2,
'distance_cm': 60,
'measured_ohms': 4.5,
'expected_ohms': 6.4, # Using slope 0.0925 Ω/cm and intercept 0.85 Ω
'expected_range': '(7.0 - 7.5 Ω based on linear trend from other points)'
}
# Wire properties
awg_data = [
(26, 0.1285, y_26, 'tab:blue', '26 AWG'),
(29, 0.06424, y_29, 'tab:orange', '29 AWG'),
(32, 0.03204, y_32, 'tab:green', '32 AWG')
]
# Linear regression function
def linear_regression(x, y):
"""Perform linear regression and return slope, intercept, R²"""
slope, intercept = np.polyfit(x, y, 1)
y_pred = slope * x + intercept
ss_res = np.sum((y - y_pred) ** 2)
ss_tot = np.sum((y - np.mean(y)) ** 2)
r_squared = 1 - (ss_res / ss_tot)
return slope, intercept, r_squared
# Print results
print("=" * 60)
print("LINEAR REGRESSION RESULTS")
print("Resistance (Ω) vs Probe Distance (cm)")
print("=" * 60)
results = []
outlier_results = {}
for awg, area, y, color, label in awg_data:
slope, intercept, r_squared = linear_regression(x, y)
# Calculate resistivity: ρ = slope × area × 0.01 (since slope = R/L, ρ = R·A/L)
# Convert mm² to cm² (1 mm² = 0.01 cm²)
resistivity = slope * area * 0.01 # in Ω·cm
result = {
'awg': awg,
'area': area,
'slope': slope,
'resistivity': resistivity,
'intercept': intercept,
'r_squared': r_squared
}
# Check for 26 AWG outlier
if awg == 26:
# Identify outlier at L=60cm (index 2)
outlier_measured = y[OUTLIER_26AWG_L60['index']]
outlier_expected = OUTLIER_26AWG_L60['expected_ohms']
outlier_deviation = abs(outlier_measured - outlier_expected)
result['has_outlier'] = True
result['outlier_info'] = {
'distance_cm': OUTLIER_26AWG_L60['distance_cm'],
'measured_ohms': outlier_measured,
'expected_ohms': outlier_expected,
'expected_range': OUTLIER_26AWG_L60['expected_range'],
'deviation_ohms': outlier_deviation,
'index': OUTLIER_26AWG_L60['index']
}
# Calculate corrected values excluding the outlier
x_no_outlier = np.delete(x, OUTLIER_26AWG_L60['index'])
y_no_outlier = np.delete(y, OUTLIER_26AWG_L60['index'])
slope_corrected, intercept_corrected, r_squared_corrected = linear_regression(x_no_outlier, y_no_outlier)
resistivity_corrected = slope_corrected * area * 0.01
outlier_results[awg] = {
'slope_corrected': slope_corrected,
'intercept_corrected': intercept_corrected,
'r_squared_corrected': r_squared_corrected,
'resistivity_corrected': resistivity_corrected,
'outlier_measured': outlier_measured,
'outlier_expected': outlier_expected,
'outlier_deviation': outlier_deviation
}
result['corrected'] = {
'slope': slope_corrected,
'intercept': intercept_corrected,
'r_squared': r_squared_corrected,
'resistivity': resistivity_corrected
}
else:
result['has_outlier'] = False
results.append(result)
print(f"\n{label} (Area = {area} mm²):")
print(f" Equation: R = ({slope:+.4f} Ω/cm) × L + ({intercept:+.4f} Ω)")
print(f" Resistivity ρ = slope × area × 0.01 (mm² to cm²) = {resistivity:.4f} Ω·cm")
print(f" R² = {r_squared:.4f}")
print(f" Standard error in R: {np.sqrt(np.sum((y - (slope*x + intercept))**2) / (len(x)-2)):.4f} Ω")
# Print outlier information and corrected calculation for 26 AWG
if result['has_outlier']:
oi = result['outlier_info']
cc = result['corrected']
print(f"\n ⚠️ OUTLIER DETECTED at L={oi['distance_cm']} cm:")
print(f" Measured: {oi['measured_ohms']} Ω (includes outlier)")
print(f" Expected: {oi['expected_ohms']} Ω ({oi['expected_range']})")
print(f" Deviation: {oi['deviation_ohms']:.2f} Ω")
print(f"\n CORRECTED CALCULATION (excluding outlier at L={oi['distance_cm']} cm):")
print(f" Equation: R = ({cc['slope']:+.4f} Ω/cm) × L + ({cc['intercept']:+.4f} Ω)")
print(f" Resistivity ρ = {cc['resistivity']:.4f} Ω·cm")
print(f" R² = {cc['r_squared']:.4f}")
print(f" Standard error in R: {np.sqrt(np.sum((y_no_outlier - (cc['slope']*x_no_outlier + cc['intercept']))**2) / (len(x_no_outlier)-2)):.4f} Ω")
print(f"\n SUMMARY:")
print(f" With outlier: slope={slope:.4f} Ω/cm, R²={r_squared:.4f}")
print(f" Without outlier: slope={cc['slope']:.4f} Ω/cm, R²={cc['r_squared']:.4f}")
print("\n" + "=" * 60)
# Create single figure with all 3 wires on same plot
fig, ax = plt.subplots(1, 1, figsize=(10, 6))
# Store regression results for legend
all_slopes = []
all_intercepts = []
all_r_squared = []
for awg, area, y, color, label in awg_data:
slope, intercept, r_squared = linear_regression(x, y)
all_slopes.append(slope)
all_intercepts.append(intercept)
all_r_squared.append(r_squared)
# Scatter plot for this wire
ax.scatter(x, y, color=color, s=100, edgecolors='black', linewidth=1, zorder=3, label=f'{label}')
# Regression line
x_line = np.linspace(10, 110, 100)
y_line = slope * x_line + intercept
ax.plot(x_line, y_line, color=color, linestyle='-', linewidth=2.5, alpha=0.8, zorder=2)
# Format axes
ax.set_xlabel('Probe Distance (cm)', fontsize=12, fontweight='bold')
ax.set_ylabel('Resistance (Ω)', fontsize=12, fontweight='bold')
ax.set_title('Resistance vs Probe Distance for Different Wire Gauges', fontsize=14, fontweight='bold', pad=15)
# Add legend
ax.legend(loc='upper left', fontsize=10, framealpha=0.9)
# Add equations legend
eq_text = '26 AWG: R = {:.4f}L + {:.4f}\n'.format(all_slopes[0], all_intercepts[0])
eq_text += '29 AWG: R = {:.4f}L + {:.4f}\n'.format(all_slopes[1], all_intercepts[1])
eq_text += '32 AWG: R = {:.4f}L + {:.4f}'.format(all_slopes[2], all_intercepts[2])
ax.text(0.98, 0.98, eq_text, transform=ax.transAxes, fontsize=9,
verticalalignment='top', horizontalalignment='right')
# Grid
ax.grid(True, linestyle='--', alpha=0.7)
ax.set_axisbelow(True)
# Limit axes
ax.set_xlim(15, 105)
y_max_data = max(np.max(y_26), np.max(y_29), np.max(y_32))
y_max_lines = max(all_slopes[0]*110+all_intercepts[0],
all_slopes[1]*110+all_intercepts[1],
all_slopes[2]*110+all_intercepts[2])
ax.set_ylim(0, max(y_max_data, y_max_lines) * 1.1)
# Save figure
output_file = 'wire_resistance_regression.png'
plt.savefig(output_file, format='png', bbox_inches='tight')
print(f"\nFigure saved as: {output_file}")
# Also save as PDF for higher quality
output_pdf = 'wire_resistance_regression.pdf'
plt.savefig(output_pdf, format='pdf', bbox_inches='tight')
print(f"Figure saved as: {output_pdf}")
plt.close()
# Print LaTeX inclusion code
print("\n" + "=" * 60)
print("LATEX INCLUSION CODE (add to your .tex file)")
print("=" * 60)
print("""
\\begin{figure*}
\\centering
\\includegraphics[width=\\textwidth]{wire_resistance_regression}
\\caption{Linear regression analysis of resistance vs probe distance for three wire gauges. Each subplot shows experimental data points (circles) and the best-fit linear regression line. The regression equation and R² value are displayed in each plot. Note: 26 AWG data contains an experimental outlier at L=60cm (4.5 Ω vs expected ~6.4 Ω).}
\\label{fig:wire_regression}
\\end{figure*}
""")
# Print summary table for LaTeX
print("\n" + "=" * 60)
print("LATEX TABLE CODE (for regression parameters)")
print("=" * 60)
print("""
\\begin{table}
\\caption{Linear regression parameters and calculated resistivity for each wire gauge. Note: 26 AWG data excluded outlier at L=60cm (measured 4.5 Ω vs expected 6.4 Ω) due to experimental uncertainty.}
\\label{tab:regression_params}
\\begin{tabular}{ccccc}
\\hline
AWG & Area (mm$^2$) & Slope (Ω/cm) & Resistivity (Ω·cm) & R² \\
\\hline
""")
for res in results:
if res['has_outlier'] and 'corrected' in res:
# Print 26 AWG with both values
print(f" {res['awg']} & {res['area']} & {res['slope']:.6f} (with outlier) & {res['resistivity']:.6f} & {res['r_squared']:.6f} \\\\")
print(f" & & {res['corrected']['slope']:.6f} (corrected) & {res['corrected']['resistivity']:.6f} & {res['corrected']['r_squared']:.6f} \\\\")
else:
print(f" {res['awg']} & {res['area']} & {res['slope']:.6f} & {res['resistivity']:.6f} & {res['r_squared']:.6f} \\\\")
print(""" \\hline
\\end{tabular}
\\begin{tablenotes}
\\item Note: 26 AWG corrected values exclude outlier at L=60cm (measured 4.5 Ω, expected 6.4 Ω).
\\end{tablenotes}
\\end{table}
""")

Binary file not shown.

View File

@@ -51,7 +51,6 @@
% Only include extra packages if you really need them. Avoid using amssymb if newtxmath is enabled, as these packages can cause conflicts. newtxmatch covers the same math symbols while producing a consistent Times New Roman font. Common packages are:
\usepackage{graphicx} % Including figure files
\usepackage{amsmath} % Advanced maths commands
\usepackage{pdflscape} % Landscape environment
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -83,7 +82,7 @@ $^{2}$Physics, Plano East Senior High School, 3000 Los Rios Blvd, Plano, TX 7507
}
% These dates will be filled out by the publisher
\date{Accepted XXX. Received YYY; in original form ZZZ}
\date{\today}
% Prints the current year, for the copyright statements etc. To achieve a fixed year, replace the expression with a number.
\pubyear{\the\year{}}
@@ -145,22 +144,44 @@ Refer back to them as e.g. equation~(\ref{eq:quadratic}).
\subsection{Results and Discussion}
\begin{landscape}
\begin{table}
\caption{Resistance measurements for different wire cross-sectional areas at varying probe distances. All resistance values measured in $\Omega$.}
\label{tab:resistance}
\begin{tabular}{cccccc}
\hline
Area & \multicolumn{5}{c}{Probe distance} \\
(mm$^2$) & 20 cm & 40 cm & 60 cm & 80 cm & 100 cm \\
\hline
0.1285 (26 AWG) & 2.6 $\Omega$ & 5.6 $\Omega$ & 4.5 $\Omega$ & 9.3 $\Omega$ & 10.0 $\Omega$ \\
0.06424 (29 AWG) & 4.7 $\Omega$ & 8.9 $\Omega$ & 13.6 $\Omega$ & 18.0 $\Omega$ & 22.6 $\Omega$ \\
0.03204 (32 AWG) & 9.0 $\Omega$ & 18.1 $\Omega$ & 27.3 $\Omega$ & 36.3 $\Omega$ & 45.4 $\Omega$ \\
\hline
\end{tabular}
\end{table}
\end{landscape}
\begin{table*}
\caption{Resistance measurements for different wire cross-sectional areas at varying probe distances. All resistance values measured in $\Omega$.}
\label{tab:resistance}
\begin{tabular}{lrrrrr}
\hline
Area & \multicolumn{5}{c}{Probe distance} \\
(mm$^2$) & 20 cm & 40 cm & 60 cm & 80 cm & 100 cm \\
& ($\Omega$) & & & & \\
\hline
0.1285 (26 AWG) & 2.6 & 5.6 & 4.5 & 9.3 & 10.0 \\
0.06424 (29 AWG) & 4.7 & 8.9 & 13.6 & 18.0 & 22.6 \\
0.03204 (32 AWG) & 9.0 & 18.1 & 27.3 & 36.3 & 45.4 \\
\hline
\end{tabular}
\end{table*}
\begin{figure*}
\centering
\includegraphics[width=\textwidth]{wire_resistance_regression}
\caption{Linear regression analysis of resistance vs probe distance for three wire gauges. Experimental data points (circles) and best-fit regression lines are shown for each AWG gauge. Regression equations: 26 AWG: R = 0.0925L + 0.8500, 29 AWG: R = 0.2245L + 0.0900, 32 AWG: R = 0.4550L - 0.0800 (R, L in $\Omega$, cm). Note: 26 AWG data contains experimental outlier at L=60 cm (4.5 $\Omega$ vs expected 6.4 $\Omega$).}
\label{fig:wire_regression}
\end{figure*}
\begin{table*}
\caption{Linear regression parameters and calculated resistivity for all three wire gauges. Note: 26 AWG data contains experimental outlier at L=60 cm.}
\label{tab:regression_params}
\begin{tabular}{ccccc}
\hline
AWG & Area (mm$^2$) & Slope ($\Omega$/cm) & Resistivity ($\Omega\cdot$cm) & R$^2$ \\
\hline
26 & 0.1285 & 0.092500 & 0.000119 & 0.854343 \\
29 & 0.06424 & 0.224500 & 0.000144 & 0.999747 \\
32 & 0.03204 & 0.455000 & 0.000146 & 1.000000 \\
\hline
\end{tabular}
\end{table*}
\section{Conclusions}

14
raw-data.csv Normal file
View File

@@ -0,0 +1,14 @@
26,0.1285,,,,,,,
29,0.06424,,,,,,,
32,0.03204,,,,,,BASE RES,1.45
,,,,,,,at room temp,1.4501595
,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,Area,,,,,
,,x,0.1285,0.06424,0.03204,,,
,,20,2.6,4.7,9.0,,,
,,40,5.6,8.9,18.1,,,
,,60,4.5,13.6,27.3,,,
,,80,9.3,18.0,36.3,,,
,,100,10.0,22.6,45.4,,,
1 26 0.1285
2 29 0.06424
3 32 0.03204 BASE RES 1.45
4 at room temp 1.4501595
5
6
7
8 Area
9 x 0.1285 0.06424 0.03204
10 20 2.6 4.7 9.0
11 40 5.6 8.9 18.1
12 60 4.5 13.6 27.3
13 80 9.3 18.0 36.3
14 100 10.0 22.6 45.4

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB