赞
踩
前言:在小组老师的领导下,我开始学习数据可视化分析,学着做项目,老师给了我一个月的时间来做,我会一周写一次实战总结。主要记载实战过程中遇到的问题和解决办法
python版本:3.7
matplotlib版本:3.3.2
pandas版本:1.1.2
numpy版本:1.19.2
import csv txt_list = [] with open('数据/数据.txt', 'r', encoding='utf-8') as filein: for line in filein: line_list = line.strip('\n').split('\t') # 我这里的数据之间是以 tab 间隔的 txt_list.append(line_list) # csv_writer.writerow(line_list) with open('数据/数据.csv', 'w', newline='', encoding='utf-8-sig') as csvfile: csv_writer = csv.writer(csvfile) head = ["序号", "电影名", "导演", "主演", "上映时间", "国家", "电影类型", "评分", "播放量", "主要内容", "链接"] csv_writer.writerow(head) for row in txt_list: row_list = row[0].split(',') csv_writer.writerow(row_list)
数据是网上找的,转换代码也是网上的,但是有错,这是我改后的代码。
附上数据链接:https://blog.csdn.net/qq_41479464/article/details/97019057
# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
我的导入包是
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
movie_country = movie_df.pivot_table(index=["国家"], values=["电影名"], aggfunc=len)
上面这行代码实现创造一个以index为分组依据,求电影名的总数的透视表
这里附上我收藏的一篇比较好的pandas透视表的讲解链接https://www.cnblogs.com/onemorepoint/p/8425300.html
movie_df来自这里:
head = ["序号", "电影名", "上映时间", "国家", "电影类型", "评分", "播放量"]
movie_df = pd.read_csv("数据/数据.csv", index_col=False, usecols=lambda x: x in head)
index_col意思是不让我的第一列作为dataframe的行号,usecols是为了添加每一列的标题
然后我想求每个国家上映量的占比,代码如下:
movie_country.eval('国家占比=电影名/250', inplace=True)
这行代码给movie_country这个数据框添加了一个“国家占比”的一列,这列的值=电影名/250
plt.pie(movie_country["国家占比"], # 每个饼块的实际数据,如果大于1,会进行归一化,计算percentage
explode=explode_list, # 每个饼块离中心的距离
colors=colors_list, # 每个饼块的颜色
labels=country_list, # 每个饼块的标签
labeldistance=None, # 每个饼块标签到中心的距离
autopct='%1.1f%%', # 百分比的显示格式
pctdistance=1.1, # 百分比到中心的距离
shadow=True, # 每个饼块是否显示阴影
startangle=0, # 默认从x轴正半轴逆时针起
radius=3.8, # 饼块的半径
textprops={'fontsize': 8}, # 字体大小
)
在这里面有个参数是explode,我们让相近值的饼块离中心的距离不同就行了
我的explode_list值如下:
explode_list = [0.0]*22
explode_list[16] = 0.1
explode_list[19] = 0.3
explode_list[18] = 0.4
explode_list[15] = 0.2
explode_list[14] = 0.3
explode_list[13] = 0.4
展示图例代码:
plt.legend(loc='upper right')
显示效果如下:
movie_country = movie_df.pivot_table(index=["国家"], values=["播放量", "评分"])
movie_country['播放量'] = movie_country['播放量'].astype("int")
movie_country['评分'] = movie_country['评分'].round(3)
我想像饼图那样,加上数据显示,代码如下:
for x, y in enumerate(movie_country['评分'].values):
plt.text(x-0.5, y, "%s" % y, fontsize=6)
然后我想实现双y轴画法,这个比较麻烦,网上的也很少,好在最终还是找到了解决办法:
plt1 = plt.bar(x=country_list, height=movie_country["评分"], width=-0.4, align='edge', color='y', label='电影平均评分')
ax2 = plt.twinx()
plt2 = ax2.bar(x=country_list, height=movie_country["播放量"], width=0.4, align='edge', label='电影平均播放量')
关键在于plt.twinx()函数,这个函数实现了让ax2共享plt的x轴
显示效果如下:
def search_year(x): """根据上映时间确定属于哪个年代段""" if 1930 <= x < 1940: return '1930' elif 1940 <= x < 1950: return '1940' elif 1950 <= x < 1960: return '1950' elif 1960 <= x < 1970: return '1960' elif 1970 <= x < 1980: return '1970' elif 1980 <= x < 1990: return '1980' elif 1990 <= x < 2000: return '1990' elif 2000 <= x < 2010: return '2000' elif 2010 <= x < 2020: return '2010' movie_df['年代段'] = movie_df['上映时间'].apply(func=search_year)
创建一个新的名为"年代段"列,它里面的值是把movie_df[‘上映时间’]传到search_year()函数 返回的结果
然后我就跟据这个列创建了一个透视表,接着就开始画图,然后我发现x轴的年代不连续,并且显示不全,解决代码如下:
year_list = [1930, 1940, 1950, 1960, 1970, 1980, 1990, 2000, 2010, 2020]
movie_df.sort_values('上映时间', inplace=True)
max_year = max(year_list)
min_year = min(year_list)
plt.hist(movie_df['上映时间'], bins=range(min_year, max_year+10, 10))
plt.xticks(year_list, rotation=45, fontsize=10)
这里要注意,直方图的x轴只接受整型,plt.hist()的第一个参数是数据,第二个参数是为了解决画图没有对齐刻度的问题,个人理解它是条形的左边刻度。plt.xticks()函数可以调整x轴
加网格代码:
plt.grid(True, linestyle='--', alpha=0.4)
画布调整代码:
plt.figure(figsize=(6.4, 5.0))
展示效果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。