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 [ ]: