数据分析:Matplotlib常用图表

数据分析

image-20210703143511609

jupyter notebook

  • jupyter notebook:一款编程/文档/笔记/展示软件

启动命令:

jupyter notebook

image-20210703143819962

matplotlib

设置中文格式:plt.rcParams['font.sans-serif'] = ['KaiTi']

# 查看本地所有字体
import matplotlib.font_manager
a = sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])
for i in a:
print(i)

常用数据图

折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)

image-20210703184321254

直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。
一般用横轴表示数据范围,纵轴表示分布情况。
特点:绘制连**续性**的数据,展示一组或者多组数据的分布状况(统计)

image-20210703184338076

条形图:排列在工作表的列或行中的数据可以绘制到条形图中。
特点:绘制连**离散**的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计)

image-20210703184402215

散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量
之间是否存在某种关联或总结坐标点的分布模式。
特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)

image-20210703184411504

折线图

image-20210703144017152

每个红色的点是坐标,把5个点的坐标连接成一条线,组成了一个折线图

image-20210703144249230

但是目前存在以下几个问题:

1.设置图片大小(想要一个高清无码大图)
2.保存到本地
3.描述信息,比如x轴和y轴表示什么,这个图表示什么
4.调整x或者y的刻度的间距
5.线条的样式(比如颜色,透明度等)
6.标记出特殊的点(比如告诉别人最高点和最低点在哪里)
7.给图片添加一个水印(防伪,防止盗用)

Test1

'''
假设一天中每隔两个小时(range(2,26,2))的气温(℃)分别是
'''
# 导包
from matplotlib import pyplot as plt

# 设置图片大小
fig = plt.figure(figsize=(20, 8), dpi=80)

# 设置x,y轴的值
x = range(2, 26, 2)
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 27, 22, 18, 15]

# 绘图
plt.plot(x, y)

# 设置x轴刻度
plt.xticks(range(2,26,2))
plt.yticks(range(min(y), max(y) + 1))

# 保存图片
# plt.savefig("./image.png") # .svg格式,放大无锯齿

# 展示图形
plt.show()

image-20210703144749818

Test2

import random
from matplotlib import pyplot as plt

# 设置字体为楷体
plt.rcParams['font.sans-serif'] = ['KaiTi']

x = range(0, 120)
y = [random.randint(20, 35) for i in range(120)]

# 设置图片大小
fig = plt.figure(figsize=(20, 10), dpi=180)

# 绘图
plt.plot(x, y)

# 调整x轴的刻度
xl = ["10点{}分".format(i) for i in range(60)]
xl += ["11点{}分".format(i) for i in range(60)]
# 取步长,数字和字符串一一对应,数据的长度一样。只有列表list 可以取步长
plt.xticks(list(x)[::5], xl[::5], rotation=45)  # rotation 旋转的度数

# 添加描述信息
plt.xlabel("时间", size=20)
plt.ylabel("温度(℃)", size=20)
plt.title("10点到12点每分钟的气温变化情况", size=40)
# 展示图形
plt.show()

image-20210703144943971

image-20210703150201814

多条折线

多次 plt.plot()

'''
统计出童某从11岁到30岁每年交的女朋友数量列表,将数据绘制成折线图
以及同桌从11岁到30岁交往数量做出数据折线图对比差距
'''

from matplotlib import pyplot as plt

fig = plt.figure(figsize=(20, 10), dpi=180)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title("童某与其同桌从11岁到30岁每年交的女朋友数量图", size=30)

x = range(11, 31)
y = [1, 3, 2, 3, 4, 4, 5, 6, 5, 4, 3, 3, 1, 1, 1, 4, 6, 4, 5, 3]
z = [1, 0, 3, 1, 2, 2, 3, 3, 2, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1]

# label默认不展示,需要legend()显示图例
# color='red' 线条颜色
# linestyle='--' 线条风格
# linewidth=2 线条粗细
plt.plot(x, y, label="童某", color='red', linestyle='--', linewidth=2)
plt.plot(x, z, label="同桌", color='blue', linestyle='-.', linewidth=5)

plt.ylabel("交往数量(个)", size=20)
plt.xlabel("年龄", size=20)
xl = ["{}岁".format(i) for i in x]
plt.xticks(x, xl)

# 添加图例
plt.legend(loc=2)
'''
        'best'            0
        'upper right'     1
        'upper left'      2
        'lower left'      3
        'lower right'     4
        'right'           5
        'center left'     6
        'center right'    7
        'lower center'    8
        'upper center'    9
        'center'          10
'''

# 绘制网格
plt.grid(alpha=0.8, linestyle=':', linewidth=1, color='k')  # alpha设置网格透明度(0~1)
plt.show()

image-20210703164107513

总结

1.绘制了折线图(plt.plot)
2.设置了图片的大小和分辨率(plt.figure)
3.实现了图片的保存(plt.savefig)
4.设置了xy轴上的刻度和字符串(xticks)
5.解决了刻度稀疏和密集的问题(xticks)
6.设置了标题,xy轴的lable(title,xlable,ylable)
7.设置了字体(font_manager. fontProperties,matplotlib.rc)
8.在一个图上绘制多个图形(plt多次plot即可)
9.为不同的图形添加图例

image-20210703230413735


散点图

'''
散点图

假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),
那么此时如何寻找出气温和随时间(天)变化的某种规律?
'''
from matplotlib import pyplot as plt

y_3 = [11, 17, 16, 11, 12, 11, 12, 6, 6, 7, 8, 9, 12, 15, 14, 17, 18, 21, 16, 17, 20, 14, 15, 15, 15, 19, 21, 22, 22,
       22, 23]
y_10 = [26, 26, 28, 19, 21, 17, 16, 19, 18, 20, 20, 19, 22, 23, 17, 20, 21, 20, 22, 15, 11, 15, 5, 13, 17, 10, 11, 13,
        12, 13, 6]
x_3 = range(1, 32)
x_10 = range(41, 72)

# 设置中文
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置图片大小
plt.figure(figsize=(20, 10), dpi=100)

# 使用scatter方法绘制散点图
plt.scatter(x_3, y_3, label="3月份")
plt.scatter(x_10, y_10, label="10月份")

# 调整x轴的刻度
xl = list(x_3) + list(x_10)  # 总数应当是两个月的天数而不是72
xlabels = ["3月{}日".format(i) for i in x_3]
xlabels += ["10月{}日".format(i) for i in x_10]
plt.xticks(xl[::3], xlabels[::3])

# 添加描述信息
plt.xlabel("时间", size=20)
plt.ylabel("温度", size=20)
plt.title("北京2016年3,10月份每天白天的最高气温", size=30)

# 添加图例
plt.legend()

# 展示
plt.show()

image-20210704202855260

不同条件(维度)之间的内在关联关系
观察数据的离散聚合程度


条形图

image-20210704203128786

'''
柱状图

假设你获取到了2017年内地电影票房前20的电影(列表a)和电影票房数据(列表b),那么如何更加直观的展示该数据?
'''
from matplotlib import pyplot as plt

# 设置中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(20,10), dpi=100)

a = ["战狼2", "速度与激情8", "功夫瑜伽", "西游伏妖篇", "变形金刚5:最后的骑士", "摔跤吧!爸爸", "加勒比海盗5:死无对证", 
     "金刚:骷髅岛", "极限特工:终极回归", "生化危机6:终章", "乘风破浪", "神偷奶爸3", "智取威虎山", "大闹天竺", 
     "金刚狼3:殊死一战", "蜘蛛侠:英雄归来", "悟空传", "银河护卫队2", "情圣", "新木乃伊", ]
b = [56.01, 26.94, 17.53, 16.49, 15.45, 12.96, 11.8, 11.61, 11.28, 11.12, 10.49, 10.3, 8.75, 7.55, 7.32, 6.99, 6.88,
     6.86, 6.58, 6.23]

# 通过bar方法绘制柱状图
plt.bar(a, b, width=0.5)

# 调整x轴刻度
plt.xticks(rotation=35)

plt.show()

绘制横排条形图

from matplotlib import pyplot as plt

# 设置中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(20,10), dpi=100)

a = ["战狼2", "速度与激情8", "功夫瑜伽", "西游伏妖篇", "变形金刚5:最后的骑士", "摔跤吧!爸爸",
     "加勒比海盗5:死无对证", "金刚:骷髅岛", "极限特工:终极回归", "生化危机6:终章", "乘风破浪", 
     "神偷奶爸3", "智取威虎山", "大闹天竺", "金刚狼3:殊死一战", "蜘蛛侠:英雄归来", "悟空传", "银河护卫队2", "情圣", "新木乃伊", ]
b = [56.01, 26.94, 17.53, 16.49, 15.45, 12.96, 11.8, 11.61, 11.28, 11.12, 10.49, 10.3, 8.75, 7.55, 7.32, 6.99, 6.88,
     6.86, 6.58, 6.23]

# 通过barh方法绘制条形图
plt.barh(a, b, height=0.5, color='c') # 粗细的调节和柱状图的不一样
plt.grid(alpha=0.5)

plt.show()

image-20210704203406650

绘制分组条形图

'''
分组条形图

假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)
三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?
'''
from matplotlib import pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.title("四部电影在如下三天内的票房统计表", size=10)

a = ["猩球崛起3:终极之战", "敦刻尔克", "蜘蛛侠:英雄归来", "战狼2"]
b_14 = [2358, 399, 2358, 362]
b_15 = [12357, 156, 2045, 168]
b_16 = [15746, 312, 4497, 319]

bar_width = 0.2
x_14 = range(len(a)) #可迭代
x_15 = [i+bar_width for i in x_14] #遍历循环,每次位移bar_width
x_16 = [i+bar_width*2 for i in x_14]

plt.bar(a, b_14, width=bar_width, label="9月14日")
plt.bar(x_15, b_15, width=bar_width, label="9月15日")
plt.bar(x_16, b_16, width=bar_width, label="9月16日")
# 设置图例
plt.legend()
# 设置网格线
plt.grid(alpha=0.5, linestyle=":")
plt.show()

image-20210704203522950

数量统计
频率统计(市场饱和度)


绘制直方图

image-20210704203834997

'''
直方图

假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态
(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?
'''
from matplotlib import pyplot as plt

a = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124,
     101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111, 78, 132, 124, 113, 150, 110, 117, 86,
     95, 144, 105, 126, 130, 126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136, 123, 117, 119, 105, 137,
     123, 128, 125, 104, 109, 134, 125, 127, 105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114, 105, 115,
     132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134, 156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,
     123, 107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133, 112, 114, 122, 109, 106, 123, 116, 131, 127,
     115, 118, 112, 135, 115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154, 136, 100, 118, 119, 133, 134,
     106, 129, 126, 110, 111, 109, 141, 120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126, 114, 140, 103,
     130, 141, 117, 106, 114, 121, 114, 133, 137, 92, 121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113, 134,
     106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110, 105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146,
     133, 101, 131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111, 111, 133, 150]
plt.figure(figsize=(10, 10))

# 计算组数
d = 3 #组距
nums_bin = (max(a)-min(a))//d
print(nums_bin)

# 通过hist(数据,分成的组数)绘制直方图
plt.hist(a, nums_bin, density=True) # density统计频率分布

plt.xticks(range(min(a), max(a)+d,d))
plt.grid(linestyle=":", alpha=0.8)
plt.show()

image-20210704204013222

'''
在美国2004年人口普查发现有124 million的人在离家相对较远的地方工作。
根据他们从家到上班地点所需要的时间,通过抽样统计(最后一列)出了下表的数据,这些数据能够绘制成直方图么?
'''
from matplotlib import pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(15, 10),dpi=100)
interval = [0,5,10,15,20,25,30,35,40,45,60,90]
width = [5,5,5,5,5,5,5,5,5,15,30,60]
quantity = [836,2737,3723,3926,3596,1438,3273,642,824,613,215,47]

plt.bar(range(len(quantity)), quantity, width=1)
# 设置x轴的刻度
_x = [i-0.5 for i in range(13)]
xl = interval+[150]
plt.xticks(_x, xl)

plt.grid()
plt.show()

image-20210704204119175

img



通用配置

基本线条

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

最基本的线条

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.plot([1,2,3,4,5],[2,5,1,5,7])
plt.xlabel('x轴',size=15,color='red')
plt.ylabel('y轴',size=15,color='blue')

image-20210922095248805

不同的线条样式和颜色

plt.plot([1,2,3,4,5],[1,2,3,4,5],'-.')
plt.plot([1,2,3,4,5],[2,3,4,5,6],'--')
plt.plot([1,2,3,4,5],[3,4,5,6,7],': ')
plt.plot([1,2,3,4,5],[4,5,6,7,8],"o")
plt.title('测试',size=20)
plt.xlabel('x轴',size=15,color='r')
plt.ylabel('y轴',size=15,color='b')

image-20210922095429711

风格设置

import matplotlib.pyplot as plt
import numpy as np
plt.style.available

['Solarize_Light2',
 '_classic_test_patch',
 'bmh',
 'classic',
 'dark_background',
 'fast',
 'fivethirtyeight',
 'ggplot',
 'grayscale',
 'seaborn',
 'seaborn-bright',
 'seaborn-colorblind',
 'seaborn-dark',
 'seaborn-dark-palette',
 'seaborn-darkgrid',
 'seaborn-deep',
 'seaborn-muted',
 'seaborn-notebook',
 'seaborn-paper',
 'seaborn-pastel',
 'seaborn-poster',
 'seaborn-talk',
 'seaborn-ticks',
 'seaborn-white',
 'seaborn-whitegrid',
 'tableau-colorblind10']
x = np.linspace(-10,10)
y = np.sin(x)
plt.style.use('Solarize_Light2')
plt.plot(x,y)

image-20210922103505759

条形图

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

np.random.seed(0) # 设置种子:起始值为0
x = np.arange(5)
y = np.random.randint(-5,5,5)
print(y)
fig,axes = plt.subplots(ncols=2)
v_bars = axes[0].bar(x,y,color='red')
h_bars = axes[1].barh(x,y,color='blue')

axes[0].axhline(0,color='grey',linewidth=2)
axes[1].axvline(0,color='grey',linewidth=2)
plt.show()

image-20210922104700633

fig,ax = plt.subplots()
v_bars = ax.bar(x,y,color='blue')
for bar,height in zip(v_bars,y):
    if height < 0:
        bar.set(color='green')
plt.show()

image-20210922104749751

x = np.random.randn(100).cumsum()
y = np.arange(100)

fig,ax = plt.subplots()
ax.fill_between(x,y)
plt.show()

image-20210922104826938

x1 = np.array([1,2,3])
x2 = np.array([3,2,2])

bar_labels = ['bar1','bar2','bar3']
plt.figure(figsize=(8,6))
y_pos = [x for x in np.arange(len(x1))]

plt.barh(y_pos,x1)
plt.barh(y_pos,-x2)
plt.show()

image-20210922105152105

g_data = [1,2,3]
b_data = [3,2,1]
r_data = [2,3,3]
labels = ['group1','group2','group3']

pos = list(range(len(g_data)))
width = 0.2
fig,ax = plt.subplots()
plt.bar(pos,g_data,width,alpha=0.5,color='g',label=labels[0])
plt.bar([p+width for p in pos],b_data,width,alpha=0.5,color='b',label=labels[1])
plt.bar([p+width*2 for p in pos],r_data,width,alpha=0.5,color='r',label=labels[2])
plt.show()

image-20210922105242228

绘图细节

import matplotlib.pyplot as plt
import numpy as np
import math

x = np.random.normal(loc = 0.0, scale=1.0, size=300)
width = 0.5
bins = np.arange(math.floor(x.min())-width,math.ceil(x.max())+width,width)
ax = plt.subplot(111)

# 边框不可见
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# 刻度不可见
plt.tick_params(bottom='off',top='off',left='off',right='off')
# 显示网格
plt.grid()
plt.hist(x,alpha = 0.5,bins = bins)
plt.show()

image-20210922140626739

x = range(10)
y = range(10)

labels = ['dududududu' for i in range(10)]
fig,ax = plt.subplots()
plt.plot(x,y)
# 标签显示不全; rotation
ax.set_xticklabels(labels,rotation=90)

image-20210922140929065

x = np.arange(10)
for i in range(1,4):
    plt.plot(x,i*x**2,label = "Game %d"%i)
# 设置图例样式
plt.legend(loc='upper center',bbox_to_anchor = (0.5,1.15), ncol=3)

image-20210922141957059

x = np.arange(10)
for i in range(1,4):
    plt.plot(x,i*x**2,label = "Game %d"%i,marker='*')
# 设置图例透明度
plt.legend(loc='upper right',framealpha=0.1)

image-20210922142151749

直方图&散点图

直方图

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0,20,1000)
bins = np.arange(-100,100,5)

plt.hist(data,bins=bins)
# 设置x轴的边距
plt.xlim([min(data)-5,max(data)+5])
plt.show()

image-20210922143212794

import random
data1 = [random.gauss(15,10) for i in range(500)]
data2 = [random.gauss(5,5) for i in range(500)]
bins = np.arange(-50,50,2.5)

plt.hist(data1, bins=bins,label='class 1',alpha=0.3)
plt.hist(data2, bins=bins,label='class 2',alpha=0.3)
plt.show()

image-20210922143252495

散点图

mu_vecl = np.array([0,0])
cov_matl = np.array([[2,0],[0,2]])

x1_samples = np.random.multivariate_normal(mu_vecl,cov_matl,100)
x2_samples = np.random.multivariate_normal(mu_vecl+0.2,cov_matl+0.2,100)
x3_samples = np.random.multivariate_normal(mu_vecl+0.4,cov_matl+0.4,100)

plt.scatter(x1_samples[:,0],x1_samples[:,1],marker='^',label='x1')
plt.scatter(x2_samples[:,0],x1_samples[:,1],marker='o',label='x2')
plt.scatter(x3_samples[:,0],x1_samples[:,1],marker='*',label='x3')
plt.legend()
plt.show()

image-20210922144443303

x =[0.13,0.22,0.39,0.59,0.68,0.74,0.93]
y =[0.75,0.34,0.44,0.52,0.80,0.25,0.55]

plt.scatter(x,y,marker='^',s=100)
# 添加坐标标注
for x,y in zip(x,y):
    plt.annotate('%s,%s'%(x,y),xy=(x,y),xytext=(0,-15),textcoords='offset points',ha='center')
plt.show()

image-20210922144541529

pie&子图布局

%matplotlib inline
import matplotlib.pyplot as plt

m = 51212
f = 40742

# 显示详细数据 '%1.1f%%'
plt.pie([m,f],autopct='%1.1f%%',explode=[0,0.05],labels=['man','woman'])

image-20210922144805409

ax1 = plt.subplot2grid((3,3),(0,0))
ax2 = plt.subplot2grid((3,3),(1,0))
ax3 = plt.subplot2grid((3,3),(0,2),rowspan=3)
ax4 = plt.subplot2grid((3,3),(2,0),colspan=2)
ax5 = plt.subplot2grid((3,3),(0,1),rowspan=2)

image-20210922144841390

posted @ 2021-11-11 09:59  C_Long  阅读(155)  评论(0)    收藏  举报