Python_Matplotlib

Matplotlib

matplotlib是什么?

python底层的绘图工具,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。

matplotlib的基本要点

  • 设置图片的大小 ----> plt.figure(figsize=( ));
  • 绘制坐标图 ----> plt.plot( );
  • 保存到本地 ----> plt.savefig( );
  • x轴和y轴的描述信息 ---->plt.xlabel( ) / plt.ylabel( );
  • 标题的描述信息 ----> plt.title( );
  • 中文显示乱码问题 ----> font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=18);
  • 调整x轴和y轴的刻度 ----> plt.xticks( ) / plt.yticks( );
  • x轴的刻度信息过长时,如何调整 ----> plt.xticks(rotation=45);
  • 标记最高点 ----> plt.scatter( );
  • 在执行程序时显示图像 ----> plt.show( );

matplotlib的折线图,散点图,柱状图,直方图

常用统计图对比:
在这里插入图片描述

折线图

案例1:假设一天中每隔两个小时气温变化的折线图绘制

代码:

from matplotlib import pyplot as plt
from matplotlib import font_manager

# 5).中文显示乱码问题
myfont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=18)
titlefont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=24)

# 图表的x轴的数据, 是一个可迭代的数据类型
x_times = range(0, 24, 2)
# 图表的y轴的数据, 是一个可迭代的数据类型
y_temp = [8,10,13,25,16,19,11,20,25,16,19,8]
  
# 1).如何设置图片的大小
plt.figure(figsize=(10, 10))

# 2).传入x和y轴的数据,绘制图形
plt.plot(x_times, y_temp)

# 4). x轴和y轴以及标题的描述信息
plt.title("每天的气温变化(每隔两个小时)",fontproperties=titlefont )
plt.xlabel("时间", fontproperties=myfont)
plt.ylabel("温度", fontproperties=myfont)

# 6).调整x轴和y轴的刻度
# x轴的刻度信息过长,如何调整? ====> rotation=45 / 90
plt.xticks(x_times, labels=["%s时0分"%(i) for i in x_times], fontproperties=myfont, rotation=45)
y_temp_range = range(min(y_temp), max(y_temp)+1, 2)
plt.yticks(y_temp_range, labels=["%s 。C"%(i) for i in y_temp_range], fontproperties=myfont)

# 标记某个点
plt.scatter(x_times[2], y_temp[2], color='b')
plt.scatter(x_times[2], y_temp[2], color='', marker='o', edgecolors='r', s=300)

# 3).保存到本地
plt.savefig('doc/temp.png')

# 在执行程序时显示图像
plt.show()

绘制坐标图如下:
在这里插入图片描述
需求2:
绘制10点到12点每分钟的气温, 如何绘制折线图观察每分钟气温的变化情况?
每隔10分钟为一个刻度:10时10分 10时20分
temps = [random.randint(20, 35) for i in range(120)]

代码:

import random    
from matplotlib import pyplot as plt
from matplotlib import font_manager

myfont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=18)
titlefont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=26)

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

plt.figure(figsize=(30,10))
plt.plot(x_times,y_temps)

plt.title('10点~11点的气温变化',fontproperties=titlefont)
plt.xlabel('时间',fontproperties=myfont)
plt.ylabel('温度',fontproperties=myfont)

_x_labels = ['10时%s分' %(i) for i in range(0,60,10)]
_x_labels += ['11时%s分' %(i) for i in range(0,60,10)]
plt.xticks(x_times[::10],labels=_x_labels,fontproperties=myfont,rotation=45)
y_temps_range = range(min(y_temps),max(y_temps)+2,2)
plt.yticks(y_temps_range,labels=['%s 。C' %(i) for i in y_temps_range],fontproperties=myfont)

plt.savefig('doc/temps.png')

绘制坐标图如下:
在这里插入图片描述
需求3:
假设大家30岁时统计出你和你同桌各自从11岁到30岁每年交女(男)朋友的数量如列表a和b,请在一个图中展示数据折线图,以便比较两人20年之间每年交女(男)朋友的数量走势

代码:

import random
from matplotlib import pyplot as plt
from matplotlib import font_manager

myfont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=18)
titlefont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=26)

x_age = range(11,31)
y_count_1 = [random.randint(0,5) for i in range(20)]
y_count_2 = [random.randint(0,5) for j in range(20)]


plt.figure(figsize=(20,10))

# 在同一个图里面绘制多条折线:
# color:线条颜色
# linestyle:线条的风格
# linewidth:线条的粗细
# alpha:透明度
plt.plot(x_age,y_count_1,label='自己')
plt.plot(x_age,y_count_2,label='同桌',c='r',linestyle='--',linewidth=3,alpha=0.3)

# 添加图例
plt.legend(loc='upper right',prop=myfont)
# 添加网格
plt.grid(alpha=0.3)

plt.title('每年交男(女)朋友数量的变化',fontproperties=titlefont)
plt.xlabel('年龄',fontproperties=myfont)
plt.ylabel('男(女)友数量',fontproperties=myfont)

plt.xticks(x_age,labels=['%s岁' %(i) for i in x_age],fontproperties=myfont,rotation=45)
plt.yticks(y_count_1,labels=['%s个' %(i) for i in y_count_1],fontproperties=myfont)

plt.savefig('doc/counts.png')

绘制坐标图如下:
在这里插入图片描述

散点图

需求:
绘制北京3,10月份每天白天的最高气温随时间(天)变化的散点图,并找出规律
数据来源:天气网 http://lishi.tianqi.com/beijing/index.html
a=[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]b b=[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轴坐标

代码:

from matplotlib import pyplot as plt
from matplotlib import font_manager

myfont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=18)
titlefont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=26)

x_march = range(1,32)
x_oct = range(40,71)

y_temp_march = [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_temp_oct = [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]

plt.figure(figsize=(30,10))

plt.scatter(x_march,y_temp_march,label='3月份的温度变化',c='r',alpha=0.3)
plt.scatter(x_oct,y_temp_oct,label='10月份的温度变化',c='g',alpha=0.3)

plt.title('北京3,10月份每天白天的最高气温随时间(天)变化散点图',fontproperties=titlefont)
plt.xlabel('时间',fontproperties=myfont)
plt.ylabel('温度',fontproperties=myfont)

_x_info = list(x_march) + list(x_oct)
_x_labels_march = ['3月%s日' %(i) for i in x_march]
_x_labels_oct = ['10月%s日' %(i-39) for i in x_oct]		# range(40, 71)
plt.xticks(_x_info[::3],labels=(_x_labels_march + _x_labels_oct)[::3],fontproperties=myfont,rotation=45)

_y_info = y_temp_march + y_temp_oct
_y_info_range = range(min(_y_info),max(_y_info)+3,3)
plt.yticks(_y_info_range,labels=['%s 。C' %(i) for i in _y_info_range],fontproperties=myfont)

plt.legend(loc='upper left',prop=myfont)
plt.grid(alpha=0.3)

plt.savefig('doc/scatter.png')

绘制坐标图如下:
在这里插入图片描述

柱状图(条形图)

单个条形图
案例:电影票房数据对比

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

a = [“战狼2”,“速度与激情8”,“功夫瑜伽”,“西游伏妖篇”,“变形金刚5:最后的骑士”,“摔跤吧!爸爸”, “加勒比海盗5:死无对证”,“金刚:骷髅岛”,“极限特工:终极回归”, “蜘蛛侠:英雄归来”,“悟空传”,“银河护卫队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] 单位:亿
代码:

from matplotlib import pyplot as plt
from matplotlib import font_manager

myfont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=18)
titlefont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=26)

y_money = [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]
# 方便测试,直接生成20个电影名
x_movies = ['流浪地球%s' %(i) for i in range(len(y_money))]

plt.figure(figsize=(30,10))

plt.title('某年内地电影票房前20电影与电影票房数据',fontproperties=titlefont)

# 竖向条形图
plt.bar(range(len(y_money)),y_money,color='r',alpha=0.3,width=0.7)
plt.xlabel('电影名',fontproperties=myfont)
plt.ylabel('电影票房(单位:亿)',fontproperties=myfont)
plt.xticks(range(len(y_money)),labels= x_movies,fontproperties=myfont,rotation=45)

# 横向条形图
# plt.barh(range(len(y_money)),y_money,color='r',alpha=0.3,height=0.7)
# plt.ylabel('电影名',fontproperties=myfont)
# plt.xlabel('电影票房(单位:亿)',fontproperties=myfont)
# plt.yticks(range(len(y_money)),labels= x_movies,fontproperties=myfont,rotation=45)

plt.savefig('doc/bar.png')

绘制坐标图如下:
竖向条形图
在这里插入图片描述
横向条形图:
在这里插入图片描述
多个条形图
案例:三天间电影票房数据对比
假设你知道了列表a中电影分别在2017-09-14(b_14), 2017-09-15(b_15), 2017-09-16(b_16)三天的票房,为了展示列表中电影本身的票房以及同其他电影的数据对比情况,应该如何更加直观的呈现该数据?

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

代码:

from matplotlib import pyplot as plt
from matplotlib import font_manager

myfont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=18)
titlefont = font_manager.FontProperties(fname='/usr/share/fonts/wqy-zenhei/wqy-zenhei.ttc',size=26)

x_movies = ['猩球崛起3:终极之战','敦刻尔克','蜘蛛侠:英雄归来','战狼2']
y_16 = [15746, 312, 4497, 319]
y_15 = [12357, 156, 2045, 168]
y_14 = [2358, 399, 2358, 362]

plt.figure(figsize=(30,10))
bar_width = 0.3
x_range = range(len(x_movies))
plt.bar(x_range,y_14,color='g',width=bar_width,label='2017-09-14票房数据',alpha=0.5)
plt.bar([i + bar_width for i in x_range],y_15,color='r',width=bar_width,label='2017-09-15票房数据',alpha=0.5)
plt.bar([i + bar_width*2 for i in x_range],y_16,color='y',width=bar_width,label='2017-09-16票房数据',alpha=0.5)
plt.xticks(x_range,labels= x_movies,fontproperties=myfont,rotation=45)

plt.title('某年内地电影票房前20电影与电影票房数据',fontproperties=titlefont)
plt.xlabel('电影名',fontproperties=myfont)
plt.ylabel('电影票房(单位:亿)',fontproperties=myfont)

plt.savefig('doc/bars.png')

绘制坐标图如下:
在这里插入图片描述

直方图

要点: 把数据分为多少组进行统计

  • 如果数据在100个以内, 一般分为5-12组;
  • 组数 = 极差 / 组距
    组距:每个小组里面端点的距离

应用场景(关键字:分布状态):

  • 用户年龄的分布状态;
  • 一段时间内用户的点击数分布状态;
  • 用户活跃时间的分布状态。

可以绘制直方图的数据:

  • 连续的数据;
  • 没有统计过的数据; ------原始数据

案例1:
250部电影,电影时长的分布状态

方法一(直接设置组数):

import random
from matplotlib import  pyplot as plt

y = [random.randint(60,180) for i in range(250)]

# 直方图绘制数据分为20个分组
plt.hist(y, 20)
plt.savefig('doc/hist01.png')

绘制坐标图如下:

在这里插入图片描述 方法二(计算组数):

import random
from matplotlib import pyplot as plt

y = [random.randint(60,180) for i in range(250)]

d = 10  # 组距
# 组数 = 极差 / 组距
# //:整除
num_bins = (max(y)-min(y)) // d

plt.hist(y,num_bins)
plt.xticks(list(range(min(y),max(y)+d))[::d])

plt.grid(linestyle='-.',alpha=0.3)

plt.savefig('doc/hist02.png')

绘制坐标图如下:
在这里插入图片描述
案例2:
美国从家到上班地点所需时间的统计
The U.S. Census Bureau found that there were 124 million people who work outside of their homes.[9] Using their data on the time occupied by travel to work, the table below shows the absolute number of people who responded with travel times “at least 30 but less than 35 minutes” is higher than the numbers for the categories above and below it. This is likely due to people rounding their reported journey time.[citation needed] The problem of reporting values as somewhat arbitrarily rounded numbers is a common phenomenon when collecting data from people.[citation needed]

Data by absolute numbers

Interval Width Quantity Quantity/width
0 5 4180 836
5 5 13687 2737
10 5 18618 3723
15 5 19634 3926
20 5 17981 3596
25 5 7190 1438
30 5 16369 3273
35 5 3212 642
40 5 4122 824
45 15 9200 613
60 30 6461 215
90 60 3435 57

分析材料:

公司到家的的距离:interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90]
间距:width = [5, 5, 5, 5, 5, 5, 5, 5, 15, 30, 60]
对应的人数:quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 57]

直方图不能实现,应该用折线图实现,因为这份数据是统计过的数据,不是原始数据

代码:

from matplotlib import pyplot as plt

interval = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 60, 90]
quantity = [836, 2737, 3723, 3926, 3596, 1438, 3273, 642, 824, 613, 215, 57]

plt.figure(figsize=(20,10))

plt.plot(interval,quantity)

plt.xticks(interval)
plt.grid(linestyle='-.',alpha=0.3)

# gca = get current axis 获取当前的坐标轴
ax = plt.gca()
# 设置右边框和上边框
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
# 设置x轴为下边框
ax.xaxis.set_ticks_position('bottom')
# 设置y轴为左边框
ax.yaxis.set_ticks_position('left')
# 设置x轴和y轴的交点为(0,0)点
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))

plt.savefig('doc/案例.png')

绘制坐标图如下:
在这里插入图片描述

除此之外,还有更多其他的画图工具:如 pyecharts

猜你喜欢

转载自blog.csdn.net/King15229085063/article/details/87888905
今日推荐