如何在Python图表中正确对时间值进行排序?
电影时长可视化的排序问题
我是Python初学者,想要制作一些简单的数据可视化图表。具体来说,我希望绘制一张展示电影时长的图表。以下是我当前的代码:
# import matplotlib import matplotlib.pyplot as plt # movie names x=['titanic','ironman','avengers','sholay','thor','caption america','dabang','bajarangi bhaijaan'] # movie runtime y=['2:32:23','2:23:5','2:6:45','3:10:23','2:3:23','1:23:5','2:16:42','2:10:23'] # use scatter plot for better visualisation plt.scatter(x,y,marker='*',s=200,color='r') # use this if you want to show in bar graph #plt.bar(x,y,color='r') plt.xlabel('movie_name',color='c') plt.ylabel('movie_runtime',color='c') # make grid plt.grid(True,color='y') # use for better show /tilt x axis values / movies names plt.gcf().autofmt_xdate() # show out graph plt.show()
当前图表中的时间值排序存在问题:时长最短的电影并未位于y轴最下方,而是按照列表中的顺序排列。请问该如何修改代码解决这个问题?
解决方案
问题根源是你把电影时长存成了字符串类型,Matplotlib会按照字符串的字典顺序排列,而非实际的时间长度。按以下步骤修改即可解决:
- 将时间字符串转为数值(秒数):编写一个函数,把类似
'1:23:5'的时间字符串拆分为小时、分钟、秒,计算总秒数。数值类型才能正确比较时长长短。 - 按时长排序电影与对应数据:把电影名和时长字符串配对,以转换后的秒数为依据进行排序,再拆分得到排序后的电影名列表和时长列表。
- 用秒数绘图,替换y轴标签为原时间格式:用秒数作为绘图的y轴数值保证排序正确,再将y轴刻度替换为原时间字符串,兼顾可读性和排序逻辑。
修改后的完整代码:
import matplotlib.pyplot as plt # 原始数据 movies = ['titanic','ironman','avengers','sholay','thor','caption america','dabang','bajarangi bhaijaan'] runtimes = ['2:32:23','2:23:5','2:6:45','3:10:23','2:3:23','1:23:5','2:16:42','2:10:23'] # 定义转换函数:时间字符串转总秒数 def time_to_seconds(time_str): hours, minutes, seconds = map(int, time_str.split(':')) return hours * 3600 + minutes * 60 + seconds # 配对数据并按时长排序 sorted_items = sorted(zip(movies, runtimes), key=lambda item: time_to_seconds(item[1])) sorted_movies = [item[0] for item in sorted_items] sorted_runtimes = [item[1] for item in sorted_items] sorted_seconds = [time_to_seconds(item[1]) for item in sorted_items] # 绘制散点图 plt.scatter(sorted_movies, sorted_seconds, marker='*', s=200, color='r') # 替换y轴刻度为原时间格式 plt.yticks(sorted_seconds, sorted_runtimes) # 如果需要柱状图,替换为以下两行: # plt.bar(sorted_movies, sorted_seconds, color='r') # plt.yticks(sorted_seconds, sorted_runtimes) plt.xlabel('movie_name', color='c') plt.ylabel('movie_runtime', color='c') plt.grid(True, color='y') plt.gcf().autofmt_xdate() plt.show()
运行这段代码后,y轴会按照电影实际时长从短到长排列,最下方是时长最短的《caption america》,最上方是最长的《sholay》,完全符合需求。
内容的提问来源于stack exchange,提问作者arc_rudnevs
相关产品推荐
相关产品推荐

