Thanks for this suggestion. It isn’t quite working for my data, I’m not sure why.
Here’s my code based on your solution, with my data for two days only.
import pandas as pd
from pandas.core.frame import DataFrame
import plotly.express as px
from datetime import datetime
df_prep = [
{"timestamp": datetime.strptime("2024-08-07 09:10:38", "%Y-%m-%d %H:%M:%S"), "download_mbps": "14.671552", "upload_mbps": "6.439295"},
{"timestamp": datetime.strptime("2024-08-07 10:50:29", "%Y-%m-%d %H:%M:%S"), "download_mbps": "12.499064", "upload_mbps": "10.97903"},
{"timestamp": datetime.strptime("2024-08-07 12:20:28", "%Y-%m-%d %H:%M:%S"), "download_mbps": "20.843644", "upload_mbps": "8.760801"},
{"timestamp": datetime.strptime("2024-08-07 14:20:32", "%Y-%m-%d %H:%M:%S"), "download_mbps": "8.1798401", "upload_mbps": "11.22654"},
{"timestamp": datetime.strptime("2024-08-07 16:40:14", "%Y-%m-%d %H:%M:%S"), "download_mbps": "18.089695", "upload_mbps": "11.10735"},
{"timestamp": datetime.strptime("2024-08-07 18:10:29", "%Y-%m-%d %H:%M:%S"), "download_mbps": "16.945190", "upload_mbps": "8.352405"},
{"timestamp": datetime.strptime("2024-08-07 20:00:35", "%Y-%m-%d %H:%M:%S"), "download_mbps": "13.164570", "upload_mbps": "7.036316"},
{"timestamp": datetime.strptime("2024-08-07 21:50:28", "%Y-%m-%d %H:%M:%S"), "download_mbps": "24.871938", "upload_mbps": "11.10282"},
{"timestamp": datetime.strptime("2024-08-07 22:30:24", "%Y-%m-%d %H:%M:%S"), "download_mbps": "362.50311", "upload_mbps": "11.16578"},
{"timestamp": datetime.strptime("2024-08-07 22:50:23", "%Y-%m-%d %H:%M:%S"), "download_mbps": "363.83068", "upload_mbps": "11.40599"},
{"timestamp": datetime.strptime("2024-08-07 23:10:21", "%Y-%m-%d %H:%M:%S"), "download_mbps": "361.20357", "upload_mbps": "11.16105"},
{"timestamp": datetime.strptime("2024-08-07 23:50:21", "%Y-%m-%d %H:%M:%S"), "download_mbps": "362.03622", "upload_mbps": "11.29156"},
{"timestamp": datetime.strptime("2024-08-12 09:10:13", "%Y-%m-%d %H:%M:%S"), "download_mbps": "94.002145", "upload_mbps": "93.96362"},
{"timestamp": datetime.strptime("2024-08-12 10:23:14", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.949398", "upload_mbps": "93.95668"},
{"timestamp": datetime.strptime("2024-08-12 12:30:15", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.953006", "upload_mbps": "93.95661"},
{"timestamp": datetime.strptime("2024-08-12 14:43:18", "%Y-%m-%d %H:%M:%S"), "download_mbps": "94.036565", "upload_mbps": "93.94661"},
{"timestamp": datetime.strptime("2024-08-12 16:50:22", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.960951", "upload_mbps": "93.88965"},
{"timestamp": datetime.strptime("2024-08-12 18:03:13", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.893522", "upload_mbps": "93.74555"},
{"timestamp": datetime.strptime("2024-08-12 20:10:26", "%Y-%m-%d %H:%M:%S"), "download_mbps": "92.649269", "upload_mbps": "93.77410"},
{"timestamp": datetime.strptime("2024-08-12 21:23:14", "%Y-%m-%d %H:%M:%S"), "download_mbps": "94.021073", "upload_mbps": "93.75004"},
{"timestamp": datetime.strptime("2024-08-12 22:30:17", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.765045", "upload_mbps": "93.57514"},
{"timestamp": datetime.strptime("2024-08-12 22:43:36", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.995060", "upload_mbps": "93.80222"},
{"timestamp": datetime.strptime("2024-08-12 23:00:17", "%Y-%m-%d %H:%M:%S"), "download_mbps": "93.767352", "upload_mbps": "93.78429"},
{"timestamp": datetime.strptime("2024-08-12 23:53:29", "%Y-%m-%d %H:%M:%S"), "download_mbps": "89.606162", "upload_mbps": "89.81360"}]
for i in range(len(df_prep)):
df_prep[i]['date'] = df_prep[i]['timestamp'].date()
df_prep[i]['time'] = df_prep[i]['timestamp'].time()
df = pd.DataFrame(df_prep)
print('df before melt')
print(df)
df = pd.melt(df, id_vars=['timestamp', 'time', 'date'], value_vars=['download_mbps', 'upload_mbps'])
print("df after melt")
print(df)
df['category'] = df['date'].astype(str) + " " + df['variable']
print("df add new column 'category'")
print(df)
df = pd.pivot(df, values='value', index=['time'], columns='category')
print("df after pivot")
print(df)
fig = px.line(df)
fig.show()
resulting in this…