python-绘图-matplotlib

1. matplotlib是什么?

  • python底层的绘图工具

2. matplotlib的基本要点:

  • 如何设置图片的大小;
    plt.figure(figsize=(, ))
  • 如何保存到本地;
    plt.savefig(’’)
  • x轴和y轴的描述信息;
    plt.xlabel("", fontproperties=)
    plt.ylabel("", fontproperties=)
  • 中文显示乱码问题;
    myfont = font_manager.FontProperties(fname="", size=)
  • 调整x轴和y轴的刻度;
    plt.xticks
  • x轴的刻度信息过长, 如何调整?
    rotation=45
  • 标记最高点;
    plt.scatter(x[0],y[0])
  • 添加网格;
    plt.grid(alpha=0.5)

基本要点:设置图片大小、中文乱码、调整坐标、绘制图形、保存图片、座标轴描述信息

案例1: 假设一天中每隔两个小时气温变化的折线图绘制;
首先安装pip install matplotlib

from matplotlib import pyplot as plt
from matplotlib import font_manager
# 4). 中文显示乱码问题;
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 = [15, 12, 13, 20, 23, 30, 15, 12, 13, 20, 23, 30]

# min(y_temp), max(y_temp)

#  1). 如何设置图片的大小;
plt.figure(figsize=(10, 10))

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

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

# 5). 调整x轴和y轴的刻度;
# 6). x轴的刻度信息过长, 如何调整?

plt.xticks(x_times, labels=["%s时0分"%(i) for i in x_times], fontproperties=myfont, rotation=45)
# fontproperties 指定字体,rotation 倾斜程度
# x_times指定的是x轴的刻度 labels是每个刻度上的表示

y_temp_range = range(min(y_temp), max(y_temp)+1, 2)
# y_temp_range y轴的刻度
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)

# 2). 如何保存到本地;
plt.savefig('doc/temp.png')

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

输出:
在这里插入图片描述

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

折线图:plt.plot()
散点图:plt.scatter()
横向柱状图:plt.bar(width)
竖向柱状图:plt.barh(height)
直方图:plt.list()
在这里插入图片描述
在这里插入图片描述

1.折线图plot

需求:绘制10点到12点每分钟的气温, 如何绘制折线图观察每分钟气温的变化情况?
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/cjkuni-uming/uming.ttc", size=25)
titlefont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=50)

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

plt.figure(figsize=(30,20))
plt.plot(x_times,y_temp)

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

xlabels = ["10点%s分" %(i) for i in range(0,61,10)]
xlabels += ["11点%s分" %(i) for i in range(0,61,10)]
plt.xticks(x_times[::10],labels=xlabels,fontproperties = myfont,rotation = 45)
y_temp_range = range(min(y_temp),max(y_temp),2)
plt.yticks(y_temp_range,labels=["%s 。C"%(i) for i in y_temp_range], fontproperties=myfont)

plt.savefig('/home/kiosk/Documents/python/python0221/1.png')
# plt.show()

在这里插入图片描述查看电脑里有哪些字体库:
在这里插入图片描述

需求2:假设大家在30岁的时候,根据自己的实际情况统计出来从11岁到30岁每年交的女
(男)朋友的数量如a,请绘制出该数据的折线图,以便分析每年交女(男)朋友的数量走势;

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

x_age = range(11, 31)
y_count = [random.randint(0, 5) for i in range(20)]
myfont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=14)
titlefont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=20)

plt.figure(figsize=(10, 10))
plt.plot(x_age, y_count)
plt.title("11岁至30岁所交男(女)友个数", fontproperties=titlefont)
plt.xlabel("年龄", fontproperties=myfont)
plt.ylabel("女(男)友数量", fontproperties=myfont)


plt.xticks(x_age, labels=["%s岁" %(item) for item in x_age], fontproperties=myfont, rotation=45)
plt.scatter(x_age[0], y_count[0], c='r')

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

在这里插入图片描述

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

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

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)]
myfont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=14)
titlefont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=20)

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

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

# 添加图例
plt.legend(loc="upper right", prop=titlefont)

# 添加网格
plt.grid(alpha=0.3)

plt.title("11岁至30岁所交男(女)友个数", fontproperties=titlefont)
plt.xlabel("年龄", fontproperties=myfont)
plt.ylabel("女(男)友数量", fontproperties=myfont)


plt.xticks(x_age, labels=["%s岁" %(item) for item in x_age], fontproperties=myfont, rotation=45)
plt.scatter(x_age[0], y_count_1[0], c='r')

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

在这里插入图片描述

2.散点图scatter


from matplotlib import pyplot as plt
from matplotlib import font_manager

#  中文显示乱码问题;
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_march = range(1, 32)
x_oct = range(50, 81)

# 图表的y轴的数据, 是一个可迭代的数据类型
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))

# 传入x和y轴的数据, 绘制图形;
plt.scatter(x_march, y_temp_march, label="3月的温度变化", color='r', alpha=0.5)
plt.scatter(x_oct, y_temp_oct, label="10月的温度变化", color='g', alpha=0.5)

# 3). x轴和y轴的描述信息;
plt.title("北京3,10月份每天白天的最高气温随时间(天)变化的散点图", fontproperties=titlefont)
plt.xlabel("时间", fontproperties=myfont)
plt.ylabel("温度", fontproperties=myfont)

# 5). 调整x轴和y轴的刻度;
# 6). x轴的刻度信息过长, 如何调整?
_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 - 49) for i in x_oct]  # range(50, 81)
plt.xticks(_x_info[::3], labels=(_x_labels_march + _x_labels_oct)[::3], fontproperties=myfont, rotation=45)

# 图例 loc指的是图例的位置:左上方
plt.legend(prop=myfont, loc="upper left")
plt.grid(alpha=0.5)

# 2). 如何保存到本地;
plt.savefig('doc/scatter.png')

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

在这里插入图片描述

3.条形图bar

1.一个变量

案例:
假设你获取到了某年内地电影票房前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/cjkuni-uming/uming.ttc", size=18)
titlefont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=24)


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]
x_movies = ["流浪地球%s" %(i) for i in range(len(y_money))]

#   如何设置图片的大小;
plt.figure(figsize=(30, 10))
# (1,2)  -====('a', 10)
# 生成竖向的条形图
# plt.bar(range(len(x_movies)), y_money, color='orange', width=0.5)
# # 生成横向的条形图
plt.barh(range(len(x_movies)), y_money, color='orange', height=0.7)

# 修改刻度信息的配置
# plt.xticks(range(len(y_money)), labels=x_movies, fontproperties=myfont, rotation=45)
plt.yticks(range(len(y_money)), labels=x_movies, fontproperties=myfont, rotation=45)

# 3). x轴和y轴的描述信息;
plt.title("某年内地电影票房前20的电影和电影票房数据", fontproperties=titlefont)
plt.xlabel("电影名", fontproperties=myfont)
plt.ylabel("电影票房(单位:亿)", fontproperties=myfont)
plt.savefig('doc/bar.png')

2.多个变量

案例:
假设你知道了列表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]
数据来源: http://www.cbooo.cn/movieday


from matplotlib import pyplot as plt
from matplotlib import font_manager

#  中文显示乱码问题;
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_movies_name = ["猩球崛起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_name))
# ['a', 'b', 'c', 'd'] ===== [0, 1,2,3]
# [1,2,3,4]
# [3,4,4,4]

# [(0, 1), (1, 2), (2, 3), (3, 4)]
# [(0+0.3, 1), (1+0.3, 3)]
plt.bar(x_range, y_14, color='green', width=bar_width, label="2017-09-14票房数据")
plt.bar([i + bar_width for i in x_range], y_15, color='red', width=bar_width, label="2017-09-15票房数据")
plt.bar([i + bar_width * 2 for i in x_range], y_16, color='orange', width=bar_width, label="2017-09-16票房数据")
# 修改刻度信息的配置
plt.xticks(range(len(x_movies_name)), labels=x_movies_name, fontproperties=myfont, rotation=45)

# 3). x轴和y轴的描述信息;
plt.title("某年内地电影票房前20的电影和电影票房数据", fontproperties=titlefont)
plt.xlabel("电影名", fontproperties=myfont)
plt.ylabel("电影票房(单位:亿)", fontproperties=myfont)
plt.savefig('doc/bar.png')

在这里插入图片描述

4.直方图hist

把数据分为多少组进行统计?
- 如果数据在100个以内, 一般分为5-12组;
- 组距:每个小组里面端点的距离;
组数 = 极差 / 组距

直方图更多的应用场景:
- 用户年龄的分布状态;
- 一段时间内用户的点击数分布状态;
- 用户活跃时间的分布状态.

需求:250部电影的时长, 电影时长的分布状态;

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

# 设置x轴的刻度范围,
plt.xticks(list(range(min(y), max(y) + d))[::d])

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

# 直方图绘制数据分为12个分组;
plt.hist(y, num_bins)
plt.savefig('doc/02_hist.png')

在这里插入图片描述

4.练习

数据来源: https://en.wikipedia.org/wiki/Histogram#Examples
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

from matplotlib import pyplot as plt

# 公司到家的的距离
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]
# 设置图形的大小
plt.figure(figsize=(10, 10))

# 绘制条形图
# plt.bar(range(12), quantity, width=1)
# 绘制折线图
plt.plot(interval, quantity)
# 设置x轴的刻度
# _x = [i-0.5 for i in range(12)]
# plt.xticks(_x, labels=interval)
plt.xticks(interval)
# 设置网格
plt.grid(linestyle='-.', alpha=0.5)

# 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/03_bar.png')

在这里插入图片描述还可以参考matplotlib官网
加水印:

# 水印 20为x轴位置,2000为y轴距离
plt.text(20, 2000, 'summer',
         fontsize=60, color='gray',
         va='center', alpha=0.4)

在这里插入图片描述若要添加图片水印:参考官网

猜你喜欢

转载自blog.csdn.net/weixin_43067754/article/details/87894089