Matplotlib plt.scatter生成空白散点图问题求助
解决Python散点图空白问题(同数据集在R中可正常绘图)
以下Python代码运行后返回空白散点图,但相同数据集与变量在R中使用
geom_point()可正常绘图:
# import libraries import pandas as pd import os import matplotlib.pyplot as plt import numpy as np os.chdir('file path') # import data files activity = pd.read_csv('file path\\dailyActivity_merged.csv') intensity = pd.read_csv('file path\\hourlyIntensities_merged.csv') steps = pd.read_csv('file path\\hourlySteps_merged.csv') sleep = pd.read_csv('file path\\sleepDay_merged.csv') # ActivityDate in activity df only includes dates (no time). Rename it Dates activity = activity.rename(columns={'ActivityDate': 'Dates'}) # ActivityHour in intensity df and steps df includes date-time. Split date-time column into dates and times in intensity. Drop the date-time column intensity['Dates'] = pd.to_datetime(intensity['ActivityHour']).dt.date intensity['Times'] = pd.to_datetime(intensity['ActivityHour']).dt.time intensity = intensity.drop(columns=['ActivityHour']) # split date-time column into dates and times in steps. Drop the date-time column steps['Dates'] = pd.to_datetime(steps['ActivityHour']).dt.date steps['Times'] = pd.to_datetime(steps['ActivityHour']).dt.time steps = steps.drop(columns=['ActivityHour']) # split date-time column into dates and times in sleep. Drop the date-time column sleep['Dates'] = pd.to_datetime(sleep['SleepDate']).dt.date sleep['Times'] = pd.to_datetime(sleep['SleepDate']).dt.time sleep = sleep.drop(columns=['SleepDate', 'TotalSleepRecords']) # add a column & calculate time_awake_in_bed before falling asleep sleep['time_awake_in_bed'] = sleep['TotalTimeInBed'] - sleep['TotalMinutesAsleep'] # merge activity and sleep list = ['Id', 'Dates'] activity_sleep = sleep.merge(activity, on = list, how = 'outer') # plot relation between calories used daily vs how long it takes users to fall asleep plt.scatter(activity_sleep['time_awake_in_bed'], activity_sleep['Calories'], s=20, c='b', marker='o') plt.axis([0, 200, 0, 5000]) plt.show()
注:max(Calories) = 4900,min(Calories) =0;修正笔误:max(time_awake_in_bed) = 150,min(time_awake_in_bed) = 0
问题根源
- 日期类型不匹配导致合并失效:
原代码仅重命名了activity的ActivityDate列,但未将其转换为datetime.date类型;而sleep的Dates是通过pd.to_datetime().dt.date生成的日期对象。两者类型不一致,outer join后大部分行无法匹配,产生大量含NaN的无效行。 - 未过滤缺失值:
合并后的activity_sleep中,time_awake_in_bed或Calories列存在大量NaN值,plt.scatter会自动忽略这些缺失值,导致无点可绘。
修复步骤及完整代码
1. 统一日期列类型
处理activity数据时,将ActivityDate转换为与sleep一致的datetime.date类型:
# 替换原activity重命名列的代码 activity['Dates'] = pd.to_datetime(activity['ActivityDate']).dt.date activity = activity.drop(columns=['ActivityDate'])
2. 过滤合并后的无效数据
合并后筛选出time_awake_in_bed和Calories均不为空的行:
# 合并数据后添加过滤步骤 activity_sleep = activity_sleep.dropna(subset=['time_awake_in_bed', 'Calories'])
完整修正代码
# import libraries import pandas as pd import os import matplotlib.pyplot as plt import numpy as np os.chdir('file path') # import data files activity = pd.read_csv('file path\\dailyActivity_merged.csv') intensity = pd.read_csv('file path\\hourlyIntensities_merged.csv') steps = pd.read_csv('file path\\hourlySteps_merged.csv') sleep = pd.read_csv('file path\\sleepDay_merged.csv') # 统一activity的日期格式为datetime.date activity['Dates'] = pd.to_datetime(activity['ActivityDate']).dt.date activity = activity.drop(columns=['ActivityDate']) # intensity数据处理(原代码无需修改) intensity['Dates'] = pd.to_datetime(intensity['ActivityHour']).dt.date intensity['Times'] = pd.to_datetime(intensity['ActivityHour']).dt.time intensity = intensity.drop(columns=['ActivityHour']) # steps数据处理(原代码无需修改) steps['Dates'] = pd.to_datetime(steps['ActivityHour']).dt.date steps['Times'] = pd.to_datetime(steps['ActivityHour']).dt.time steps = steps.drop(columns=['ActivityHour']) # sleep数据处理 sleep['Dates'] = pd.to_datetime(sleep['SleepDate']).dt.date sleep['Times'] = pd.to_datetime(sleep['SleepDate']).dt.time sleep = sleep.drop(columns=['SleepDate', 'TotalSleepRecords']) # 计算醒着的时间 sleep['time_awake_in_bed'] = sleep['TotalTimeInBed'] - sleep['TotalMinutesAsleep'] # 合并数据并过滤无效行 activity_sleep = sleep.merge(activity, on=['Id', 'Dates'], how='outer') activity_sleep = activity_sleep.dropna(subset=['time_awake_in_bed', 'Calories']) # 绘制散点图 plt.scatter(activity_sleep['time_awake_in_bed'], activity_sleep['Calories'], s=20, c='b', marker='o') plt.axis([0, 200, 0, 5000]) plt.xlabel('Time Awake in Bed') plt.ylabel('Calories') plt.title('Calories vs Time Awake in Bed') plt.show()
验证建议
绘图前可打印数据基本信息,确认有效数据量:
print(activity_sleep[['time_awake_in_bed', 'Calories']].info()) print(activity_sleep[['time_awake_in_bed', 'Calories']].describe())
内容的提问来源于stack exchange,提问作者Bashir
相关产品推荐
相关产品推荐

