In [1]:
import pandas as pd
import plotly.express
In [2]:
import pathlib
module_dir = next((parent for parent in pathlib.Path.cwd().resolve().parents if (parent / "pyproject.toml").is_file()), None)
In [3]:
df = pd.read_csv(module_dir / "data_files" / "WiFi Strength Vs Distance - 2.4GHz.csv")
In [4]:
df = pd.concat([df, pd.read_csv(module_dir / "data_files" / "WiFi Strength Vs Distance - 5GHz.csv")])
In [5]:
df.head()
Out[5]:
Distance (ft) | Signal strength (dBm) - 2.4GHz | Signal strength (dBm) - 5GHz | |
---|---|---|---|
0 | 1 | -22.0 | NaN |
1 | 2 | -30.0 | NaN |
2 | 3 | -28.0 | NaN |
3 | 3 | -34.0 | NaN |
4 | 4 | -28.0 | NaN |
In [6]:
df.tail()
Out[6]:
Distance (ft) | Signal strength (dBm) - 2.4GHz | Signal strength (dBm) - 5GHz | |
---|---|---|---|
27 | 50 | NaN | -87.0 |
28 | 60 | NaN | -80.0 |
29 | 70 | NaN | -79.0 |
30 | 80 | NaN | -92.0 |
31 | 90 | NaN | -92.0 |
In [7]:
import itertools
In [8]:
keys = list(df.keys())
index = keys[0]
keys = keys[1:]
columns = [index] + [x for y in zip(keys, ['2.4Error', '5Error']) for x in y]
merged_with_error = pd.DataFrame(columns=columns)
In [9]:
merged_with_error.head()
Out[9]:
Distance (ft) | Signal strength (dBm) - 2.4GHz | 2.4Error | Signal strength (dBm) - 5GHz | 5Error |
---|
In [10]:
distances = sorted(df['Distance (ft)'].unique())
In [11]:
for distance in distances:
row = {'Distance (ft)': distance}
for (key, error_key) in [('Signal strength (dBm) - 2.4GHz', '2.4Error'), ('Signal strength (dBm) - 5GHz', '5Error')]:
values = df.loc[df['Distance (ft)'] == distance][key]
median = values.median()
error = max(values.max() - median, median - values.min())
row[key] = median
row[error_key] = error
print(distance, row)
merged_with_error.loc[distance] = pd.Series(row)
# merged_with_error.append({k: v for k, v in zip([index] + columns, row)})
# merged_with_error.loc[distance] = pd.Series({k: v for k, v in zip(columns, row)})
1 {'Distance (ft)': 1, 'Signal strength (dBm) - 2.4GHz': -22.0, '2.4Error': 0.0, 'Signal strength (dBm) - 5GHz': -38.5, '5Error': 0.5} 2 {'Distance (ft)': 2, 'Signal strength (dBm) - 2.4GHz': -30.0, '2.4Error': 0.0, 'Signal strength (dBm) - 5GHz': -54.0, '5Error': 0.0} 3 {'Distance (ft)': 3, 'Signal strength (dBm) - 2.4GHz': -31.0, '2.4Error': 3.0, 'Signal strength (dBm) - 5GHz': -53.0, '5Error': 0.0} 4 {'Distance (ft)': 4, 'Signal strength (dBm) - 2.4GHz': -27.5, '2.4Error': 0.5, 'Signal strength (dBm) - 5GHz': -58.0, '5Error': 0.0} 5 {'Distance (ft)': 5, 'Signal strength (dBm) - 2.4GHz': -31.5, '2.4Error': 0.5, 'Signal strength (dBm) - 5GHz': -58.0, '5Error': 0.0} 6 {'Distance (ft)': 6, 'Signal strength (dBm) - 2.4GHz': -34.5, '2.4Error': 1.5, 'Signal strength (dBm) - 5GHz': -72.0, '5Error': 0.0} 7 {'Distance (ft)': 7, 'Signal strength (dBm) - 2.4GHz': -39.0, '2.4Error': 1.0, 'Signal strength (dBm) - 5GHz': -70.0, '5Error': 0.0} 8 {'Distance (ft)': 8, 'Signal strength (dBm) - 2.4GHz': -42.0, '2.4Error': 4.0, 'Signal strength (dBm) - 5GHz': -64.5, '5Error': 3.5} 9 {'Distance (ft)': 9, 'Signal strength (dBm) - 2.4GHz': -46.0, '2.4Error': 4.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 10 {'Distance (ft)': 10, 'Signal strength (dBm) - 2.4GHz': -44.0, '2.4Error': 3.0, 'Signal strength (dBm) - 5GHz': -66.5, '5Error': 2.5} 15 {'Distance (ft)': 15, 'Signal strength (dBm) - 2.4GHz': -47.0, '2.4Error': 2.0, 'Signal strength (dBm) - 5GHz': -70.0, '5Error': 4.0} 20 {'Distance (ft)': 20, 'Signal strength (dBm) - 2.4GHz': -53.0, '2.4Error': 1.0, 'Signal strength (dBm) - 5GHz': -72.5, '5Error': 2.5} 25 {'Distance (ft)': 25, 'Signal strength (dBm) - 2.4GHz': -51.0, '2.4Error': 3.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 30 {'Distance (ft)': 30, 'Signal strength (dBm) - 2.4GHz': -53.5, '2.4Error': 6.5, 'Signal strength (dBm) - 5GHz': -89.0, '5Error': 0.0} 35 {'Distance (ft)': 35, 'Signal strength (dBm) - 2.4GHz': -65.0, '2.4Error': 6.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 40 {'Distance (ft)': 40, 'Signal strength (dBm) - 2.4GHz': -62.5, '2.4Error': 3.5, 'Signal strength (dBm) - 5GHz': -91.0, '5Error': 0.0} 45 {'Distance (ft)': 45, 'Signal strength (dBm) - 2.4GHz': -64.5, '2.4Error': 3.5, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 50 {'Distance (ft)': 50, 'Signal strength (dBm) - 2.4GHz': -65.5, '2.4Error': 5.5, 'Signal strength (dBm) - 5GHz': -87.0, '5Error': 11.0} 60 {'Distance (ft)': 60, 'Signal strength (dBm) - 2.4GHz': -68.0, '2.4Error': 4.0, 'Signal strength (dBm) - 5GHz': -80.0, '5Error': 0.0} 70 {'Distance (ft)': 70, 'Signal strength (dBm) - 2.4GHz': -73.0, '2.4Error': 8.0, 'Signal strength (dBm) - 5GHz': -79.0, '5Error': 0.0} 80 {'Distance (ft)': 80, 'Signal strength (dBm) - 2.4GHz': -73.5, '2.4Error': 4.5, 'Signal strength (dBm) - 5GHz': -92.0, '5Error': 0.0} 90 {'Distance (ft)': 90, 'Signal strength (dBm) - 2.4GHz': -71.0, '2.4Error': 2.0, 'Signal strength (dBm) - 5GHz': -92.0, '5Error': 0.0} 100 {'Distance (ft)': 100, 'Signal strength (dBm) - 2.4GHz': -76.5, '2.4Error': 3.5, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 125 {'Distance (ft)': 125, 'Signal strength (dBm) - 2.4GHz': -78.5, '2.4Error': 3.5, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 150 {'Distance (ft)': 150, 'Signal strength (dBm) - 2.4GHz': -84.0, '2.4Error': 12.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 175 {'Distance (ft)': 175, 'Signal strength (dBm) - 2.4GHz': -97.0, '2.4Error': 4.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan} 200 {'Distance (ft)': 200, 'Signal strength (dBm) - 2.4GHz': -95.0, '2.4Error': 0.0, 'Signal strength (dBm) - 5GHz': nan, '5Error': nan}
/home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims) /home/administrator/github/wifi-v-distance-strength-testing/.venv/lib/python3.10/site-packages/numpy/lib/nanfunctions.py:1215: RuntimeWarning: Mean of empty slice return np.nanmean(a, axis, out=out, keepdims=keepdims)
In [12]:
merged_with_error.head()
Out[12]:
Distance (ft) | Signal strength (dBm) - 2.4GHz | 2.4Error | Signal strength (dBm) - 5GHz | 5Error | |
---|---|---|---|---|---|
1 | 1.0 | -22.0 | 0.0 | -38.5 | 0.5 |
2 | 2.0 | -30.0 | 0.0 | -54.0 | 0.0 |
3 | 3.0 | -31.0 | 3.0 | -53.0 | 0.0 |
4 | 4.0 | -27.5 | 0.5 | -58.0 | 0.0 |
5 | 5.0 | -31.5 | 0.5 | -58.0 | 0.0 |
In [13]:
merged_with_error.set_index('Distance (ft)')
Out[13]:
Signal strength (dBm) - 2.4GHz | 2.4Error | Signal strength (dBm) - 5GHz | 5Error | |
---|---|---|---|---|
Distance (ft) | ||||
1.0 | -22.0 | 0.0 | -38.5 | 0.5 |
2.0 | -30.0 | 0.0 | -54.0 | 0.0 |
3.0 | -31.0 | 3.0 | -53.0 | 0.0 |
4.0 | -27.5 | 0.5 | -58.0 | 0.0 |
5.0 | -31.5 | 0.5 | -58.0 | 0.0 |
6.0 | -34.5 | 1.5 | -72.0 | 0.0 |
7.0 | -39.0 | 1.0 | -70.0 | 0.0 |
8.0 | -42.0 | 4.0 | -64.5 | 3.5 |
9.0 | -46.0 | 4.0 | NaN | NaN |
10.0 | -44.0 | 3.0 | -66.5 | 2.5 |
15.0 | -47.0 | 2.0 | -70.0 | 4.0 |
20.0 | -53.0 | 1.0 | -72.5 | 2.5 |
25.0 | -51.0 | 3.0 | NaN | NaN |
30.0 | -53.5 | 6.5 | -89.0 | 0.0 |
35.0 | -65.0 | 6.0 | NaN | NaN |
40.0 | -62.5 | 3.5 | -91.0 | 0.0 |
45.0 | -64.5 | 3.5 | NaN | NaN |
50.0 | -65.5 | 5.5 | -87.0 | 11.0 |
60.0 | -68.0 | 4.0 | -80.0 | 0.0 |
70.0 | -73.0 | 8.0 | -79.0 | 0.0 |
80.0 | -73.5 | 4.5 | -92.0 | 0.0 |
90.0 | -71.0 | 2.0 | -92.0 | 0.0 |
100.0 | -76.5 | 3.5 | NaN | NaN |
125.0 | -78.5 | 3.5 | NaN | NaN |
150.0 | -84.0 | 12.0 | NaN | NaN |
175.0 | -97.0 | 4.0 | NaN | NaN |
200.0 | -95.0 | 0.0 | NaN | NaN |
In [14]:
fig = plotly.express.scatter(merged_with_error, x='Distance (ft)', y='Signal strength (dBm) - 2.4GHz', error_y=merged_with_error.columns[2], log_x=True,
trendline="ols", trendline_options=dict(log_x=True),
)
fig.show()
In [15]:
fig = plotly.express.scatter(
merged_with_error, x='Distance (ft)', y='Signal strength (dBm) - 5GHz',
error_y=merged_with_error.columns[4], log_x=True,
trendline="ols", trendline_options=dict(log_x=True),
)
fig.show()
In [16]:
import pathlib
def make_plot(df: pd.DataFrame, x: str, y: str, error_index: int, out_file: pathlib.Path, first: bool, series_title: str):
fig = plotly.express.scatter(df, x=x, y=y, error_y=df.columns[error_index],
# log_x=True,
trendline="ols", trendline_options=dict(log_x=True),
title=f"Median Wi-Fi Strength (dBm) Vs Distance (ft) - {series_title}",
)
fig.show()
if first:
out_file.write_text("")
with out_file.open("a", encoding="UTF-8") as fout:
fout.write(fig.to_html(out_file, full_html=first))
In [17]:
out_file = pathlib.Path("report.html")
import numpy
make_plot(merged_with_error, x='Distance (ft)', y='Signal strength (dBm) - 2.4GHz', error_index=2, out_file=out_file, first=True, series_title="2.4 GHz")
make_plot(merged_with_error.loc[merged_with_error['Distance (ft)'] < 100], x='Distance (ft)', y='Signal strength (dBm) - 5GHz', error_index=4, out_file=out_file, first=False, series_title="5 GHz")
In [ ]:
In [ ]: