当前位置:   article > 正文

数据可视化学习(一)_numpy1.19.2对应的matplotlib版本

numpy1.19.2对应的matplotlib版本

前言:在小组老师的领导下,我开始学习数据可视化分析,学着做项目,老师给了我一个月的时间来做,我会一周写一次实战总结。主要记载实战过程中遇到的问题和解决办法

python版本:3.7
matplotlib版本:3.3.2
pandas版本:1.1.2
numpy版本:1.19.2

1.我在网上找了数据,但它是txt格式的,我需要转换成csv格式,代码如下
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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

数据是网上找的,转换代码也是网上的,但是有错,这是我改后的代码。
附上数据链接:https://blog.csdn.net/qq_41479464/article/details/97019057

2.csv文件读取到pandas后行列显示不全,解决办法如下
	# 显示所有列
    pd.set_option('display.max_columns', None)

    # 显示所有行
    pd.set_option('display.max_rows', None)
  • 1
  • 2
  • 3
  • 4
  • 5

我的导入包是

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
  • 1
  • 2
  • 3
3.需求一:分析各个国家的电影的上映量占比,并以饼图方式展现。那么如何能够按照各个国家对电影上映量求总和呢,经过上网搜索,我发现了pandas透视表是个好东西,代码如下:
movie_country = movie_df.pivot_table(index=["国家"], values=["电影名"], aggfunc=len)
  • 1

上面这行代码实现创造一个以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)
  • 1
  • 2

index_col意思是不让我的第一列作为dataframe的行号,usecols是为了添加每一列的标题
然后我想求每个国家上映量的占比,代码如下:

movie_country.eval('国家占比=电影名/250', inplace=True)
  • 1

这行代码给movie_country这个数据框添加了一个“国家占比”的一列,这列的值=电影名/250

4.绘制饼图时由于变量太多,加上有些只占到4%导致数据重合,解决办法:
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},          # 字体大小
            )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里面有个参数是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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

展示图例代码:
plt.legend(loc='upper right')
显示效果如下:
在这里插入图片描述

5.需求二:分析各国家电影的平均观看量和平均评分,并以双y轴柱状图的形式展现。通过透视表我想要的数据得到了,但是一般播放量都是整数,并且平均评分太长,我想让它保留3位小数,解决代码如下:
	movie_country = movie_df.pivot_table(index=["国家"], values=["播放量", "评分"])
    movie_country['播放量'] = movie_country['播放量'].astype("int")
    movie_country['评分'] = movie_country['评分'].round(3)
  • 1
  • 2
  • 3

我想像饼图那样,加上数据显示,代码如下:

    for x, y in enumerate(movie_country['评分'].values):
        plt.text(x-0.5, y, "%s" % y, fontsize=6)
  • 1
  • 2

然后我想实现双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='电影平均播放量')
  • 1
  • 2
  • 3

关键在于plt.twinx()函数,这个函数实现了让ax2共享plt的x轴
显示效果如下:
在这里插入图片描述

6.需求三:分析各年段电影上映数量并绘制直方图,我首先面临的问题是怎样获得各年段,pandas中没有一个比较方便的函数能直接达到这个目的,我只能自己编写函数:
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

创建一个新的名为"年代段"列,它里面的值是把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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里要注意,直方图的x轴只接受整型,plt.hist()的第一个参数是数据,第二个参数是为了解决画图没有对齐刻度的问题,个人理解它是条形的左边刻度。plt.xticks()函数可以调整x轴

加网格代码:
plt.grid(True, linestyle='--', alpha=0.4)

画布调整代码:
plt.figure(figsize=(6.4, 5.0))

展示效果如下:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/759565
推荐阅读
相关标签
  

闽ICP备14008679号