Python Matplotlib数据可视化
Matplotlib是Python绘图库,可绘2D/3D图表,功能强大,广泛应用于数据可视化。
(1)两种画图风格
matlab 风格,面向对象风格
区别:
- 看见 plt.plot 说明是 matlab 风格,看见 ax.plot 说明是面向对象风格
- matlab 风格下的 subplot 的数和位置从 1 数着走,面向对象风格的数和位置与编程代码习惯一致,从 0 数着走的
1.matlab 风格
画单个图
import numpy as np
import matplotlib.pyplot as plt # %matplotlib inline # 在 jupyter 环境下时需这条语句# 数据准备
x = np.linspace(0, 10, 1000) # 将 0-10 等分为 1000 个点# 创建图形对象
plt.figure()
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))# 显示图形
plt.show()
画带多个子图的图
例子1
x = np.linspace(0, 10, 100)plt.figure()
plt.subplot(2, 2, 1) # 两行两列第1个图,横着从左往右数
plt.plot(x, np.sin(x))plt.subplot(2, 2, 2)
plt.plot(x, np.cos(x))plt.subplot(2, 2, 3)
plt.plot(x, np.tan(x))plt.show()
例子2
for i in range(1, 7):plt.subplot(2, 3, i)plt.text(0.5, 0.5, str((2, 3, i)),fontsize = 16, ha = 'center')# test用于在子图中添加文本# 第三个参数为要写的文本 # fontsize 为字体大小 # ha 表示(x,y)在文本的位置 'center', 'right', 'left'plt.subplots_adjust(wspace = 1, hspace = 1)
# wspace和hspace参数子图和子图之间的间距,wspace设置左右,hspace设置上下
# 0-1 之间。0 表示无间距,1 表示间距等于子图的宽度 or 高度。plt.show()
2.面向对象风格
画单个图
x = np.linspace(0, 10, 1000)fig = plt.figure()
ax = plt.axes()ax.plot(x, np.sin(x), linestyle = ':')
ax.plot(x, np.cos(x), linestyle = '-.')plt.show()
画带多个子图的图
例子1
x = np.linspace(0, 10, 100)# 创建 2 行 1 列个子图位置 # ax 是元素为图像对象的数组 # 默认为 1 行 1 列
fig, ax = plt.subplots(2) ax[0].plot(x, np.sin(x)) # 在每个对象上调用 plot()方法
ax[1].plot(x, np.cos(x))plt.show()
例子2
x = np.linspace(0, 10, 100)
fig2, ax2 = plt.subplots(3, 2) # 3 行 2 列
ax2[0,0].plot(x, np.sin(x))
ax2[2,1].plot(x, np.cos(x))
plt.show()
例子3:sharex 和 sharey 参数,是否共享X轴或者Y轴。共享 y 轴时,同一行的图像只在最左边显示一个 y 轴,否则每个子图都带有一个 y 轴。
xn = np.linspace(0, 2*np.pi, 400)
yn = np.sin(xn**2)f, (ax1, ax2) = plt.subplots(1, 2, sharey = True)ax1.plot(xn, yn)
ax1.set_title('Sharing Y axis')
ax2.scatter(xn, yn)plt.show()
例子4:添加文本
fig, ax = plt.subplots(2, 3, sharex = 'col', sharey = 'row' )
for i in range(2):for j in range(3):ax[i, j].text(0.5, 0.5, "ax"+str([i, j]),fontsize = 18, ha = 'center')
plt.show()
例子5:占据多个位置的子图
x = np.linspace(0, 10, 1000)
y = np.sin(x ** 2)
z = np.cos(x ** 2)grid = plt.GridSpec(2, 3, wspace = 0.4, hspace = 0.3)plt.subplot(grid[0, 0])plt.subplot(grid[0, 1:])
plt.plot(x, y)plt.subplot(grid[1, :2])
plt.plot(x, z)plt.subplot(grid[1, 2])plt.show()
(2)图片保存与读取
1.保存图片
fig.savefig(imagePath)
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import osx = np.linspace(0, 10, 100)
myfig = plt.figure()
plt.plot(x, np.sin(x), '-')
plt.plot(x, np.cos(x), '--')
plt.show()myfig.savefig('my_figure.png')
# 参数填要保存的路径,绝对路径或者相对路径 # 这里图片的后缀名是 png
print(os.getcwd()) # 查看当前工作路径
查看所有类型的图片扩展名
myfig = plt.figure()
alltype = myfig.canvas.get_supported_filetypes() # 查看所有的扩展名
for key in alltype:print(key + " : " + alltype[key])
ps : Postscript
eps : Encapsulated Postscript
pdf : Portable Document Format
pgf : PGF code for LaTeX
png : Portable Network Graphics
raw : Raw RGBA bitmap
rgba : Raw RGBA bitmap
svg : Scalable Vector Graphics
svgz : Scalable Vector Graphics
jpg : Joint Photographic Experts Group
jpeg : Joint Photographic Experts Group
tif : Tagged Image File Format
tiff : Tagged Image File Format
<Figure size 432x288 with 0 Axes>
2.图片读取
import matplotlib.pyplot as plt
import matplotlib.image as mpimg# 加载图片
picture = mpimg.imread('my_figure.png')
print(type(picture)) # <class 'numpy.ndarray'>
print(picture.shape) # (480, 640, 4)# 显示图片
plt.imshow(picture)
plt.axis('off') # 不显示坐标轴
plt.show()
图片读取后就是一个三维数组,修改图片就是在操作这个三维数组。
(3)matlab 风格下绘图设置
1.绘图背景
例子:使用'classic'这种风格背景
import matplotlib.pyplot as plt
import numpy as npplt.style.use('classic') # 设置为经典格式
# 另外常用 seaborn、seaborn-whitegridx = np.linspace(0, 10, 100)
fig = plt.figure()
plt.plot(x, np.sin(x), '-')
plt.plot(x, np.cos(x), '--')
plt.show()
查看所有的背景风格
for xss in plt.style.available: # 查看所有的绘图格式plt.style.use(xss)print(xss)
bmh
classic
dark_background
fast
fivethirtyeight
ggplot
grayscale
seaborn-bright
seaborn-colorblind
seaborn-dark-palette
seaborn-dark
seaborn-darkgrid
seaborn-deep
seaborn-muted
seaborn-notebook
seaborn-paper
seaborn-pastel
seaborn-poster
seaborn-talk
seaborn-ticks
seaborn-white
seaborn-whitegrid
seaborn
Solarize_Light2
tableau-colorblind10
_classic_test
2.线条颜色
plt.style.use("seaborn")x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x - 0), color = 'blue') # 标准颜色名称
plt.plot(x, np.sin(x - 1), color = 'c') # 缩写颜色代码(r、g、b、y、c 青色、m 紫色、k 黑色)
plt.plot(x, np.sin(x - 2), color = '0.75') # 范围在 0~1 的灰度值,0 表示纯黑,1 表纯白,一般 0.5 到 1 之间比较灰
plt.plot(x, np.sin(x - 3), color = '#FFDD44') # 十六进制(RRGGBB,00~FF)
plt.plot(x, np.sin(x - 4), color = (1.0,0.2,0.3)) # RGB 元组,范围在 0~1
plt.show()
3.线条风格
例子1:设置线条风格
plt.style.use("seaborn")x = np.linspace(0, 10, 1000)
plt.plot(x, x + 0, linestyle = 'solid') # 实线
plt.plot(x, x + 1, linestyle = 'dashed') # 虚线
plt.plot(x, x + 2, linestyle = 'dashdot') # 点划线
plt.plot(x, x + 3, linestyle = 'dotted') # 实点线# 下面是简写形式
plt.plot(x, x + 4, linestyle = '-') # 实线
plt.plot(x, x + 5, linestyle = '--') # 虚线
plt.plot(x, x + 6, linestyle = '-.') # 点虚线
plt.plot(x, x + 7, linestyle = ':') # 点线
plt.show()
例子2:同时设置线条风格和颜色
x = np.linspace(0, 10, 1000)
plt.plot(x, x + 0, '-g') # 绿色实线
plt.plot(x, x + 1, '--c') # 青色虚线
plt.plot(x, x + 2, '-.k') # 黑色点虚线
plt.plot(x, x + 3, ':r') # 红色点线
plt.show()
4.点的形状
点的各种风格
============= ===============================
``'.'`` 小小圆点
``','`` 小正方块
``'o'`` 小圆点
``'v'`` 倒立金字塔
``'^'`` 金字塔
``'<'`` 左向金字塔
``'>'`` 右向金字塔
``'1'`` 下向弹弓
``'2'`` 上向弹弓
``'3'`` 左向弹弓
``'4'`` 右向弹弓
``'s'`` 正方形块
``'p'`` 五边形块
``'*'`` 五角星
``'h'`` 六边形块:上下是顶角
``'H'`` 六边形块:上下平行
``'+'`` + 形状
``'x'`` x 形状
``'D'`` 正方块:上下是顶角
``'d'`` 菱形块
``'|'`` 竖线
``'_'`` 横线(注意这里是下划线)
============= ===============================
同时设置线—点—色这三种风格
import matplotlib.pyplot as plt
import numpy as npx = np.linspace(0, 10, 30)
y = np.sin(x)plt.plot(x, y, '-or') # 线-点-色 # 实线-圆圈-红色
plt.show()
5.坐标轴上下限
第1种:使用 plt.xlim 和 ylim
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x))
plt.xlim(-1, 11)
plt.ylim(-1.5, 1.5)
plt.show()x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x))
plt.xlim(10, 0) # 逆序显示坐标轴
plt.ylim(1.2, -1.2)
plt.show()
第2种:使用 plt.axis([xmin, xmax, ymin, ymax])
注意不要搞混 axes 和 axis
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x))
plt.axis([-1, 11, -1.5, 1.5])
plt.show()
6.坐标轴刻度值、图形风格
plt.xticks函数
例子1:若不主动设置将默认使用数据的范围
mystr = ''
for x in range(ord('a'), ord('z')+1):mystr += chr(x)
print(mystr) # abcdefghijklmnopqrstuvwxyzx = np.linspace(0, 10, len(mystr)) # 将 0-10 等分为 26 个点
print(x)
# [ 0. 0.4 0.8 1.2 1.6 2. 2.4 2.8 3.2 3.6 4. 4.4 4.8 5.2
# 5.6 6. 6.4 6.8 7.2 7.6 8. 8.4 8.8 9.2 9.6 10. ]plt.plot(x, np.sin(x), '-g')
plt.plot(x, np.cos(x), ':b')
plt.axis('equal') # 使得 x 轴和 y 轴一样长和一样的刻度
plt.legend(['sin(x)', 'cos(x)'], loc = 'upper right')
plt.show()
例子2:自定义设置横坐标
plt.plot(x, np.sin(x), '-g')
plt.plot(x, np.cos(x), ':b')plt.axis('equal') # 使得 x 轴和 y 轴一样长和一样的刻度
plt.legend(['sin(x)', 'cos(x)'], loc = 'upper right')name_list = list(mystr)
plt.xticks(x, name_list) # 设置横坐标刻度值、名称
plt.show()
设置纵坐标肯定就是用plt.yticks了
例子3:plt.axis()的option参数
option : bool or str。bool:True 打开,False 关闭轴线和标签。str 如下:
- equal 就是横轴和纵轴的格子数相同
- tight 就是按照图形的内容自动收紧坐标轴,不留空白区域
7.图像标题 、坐标轴标题
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x))
plt.title("A Sine Curve")
plt.xlabel("x")
plt.ylabel("sin(x)")
plt.show()
8.图例
例子1:在 plt.plot 里面用label设置内容,在 plt.legend 里面设置位置
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x), '-g', label = 'sin(x)')
plt.plot(x, np.cos(x), ':b', label = 'cos(x)')plt.legend(loc = 'upper right')
# 若此处第一个参数再放置图例标签的列表,则会覆盖之前设置的 labelplt.show()
例子2:在 plt.legend()处设置内容和位置
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x), '-g')
plt.plot(x, np.cos(x), ':b')
plt.axis('equal')
plt.legend(['sin(x)', 'cos(x)'], loc = 'upper right')
plt.show()
例子3:legend 的 frameon 参数:bool。图例是否需要边框。默认 True。
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x), '-g')
plt.plot(x, np.cos(x), ':b')
plt.axis('equal')
plt.legend(['sin(x)', 'cos(x)'], loc = 'upper right', frameon = False)
plt.show()
例子4:legend 的 ncol 参数:整数。图例所包含的列数,默认为 1。
x = np.linspace(0, 10, 1000)
plt.plot(x, np.sin(x), '-g')
plt.plot(x, np.cos(x), ':b')
plt.axis('equal')
plt.legend(['sin(x)', 'cos(x)'], loc = 'upper right', frameon = False, ncol = 2)
plt.show()
例子5:只显示部分图例
方法 a
x = np.linspace(0, 10, 1000)
y = np.sin(x[:, np.newaxis] + np.pi * np.arange(0, 2, 0.5))
print('x.shape = ', x.shape) # (1000,)
print('y.shape = ', y.shape) # (1000, 4)lines = plt.plot(x, y) # lines 变量是一组 plt.Line2D 实例
plt.legend(lines[:2], ['first', 'second']) # 只显示两个图例
plt.show()
方法 b
x = np.linspace(0, 10, 1000)
y = np.sin(x[:, np.newaxis] + np.pi * np.arange(0, 2, 0.5))
plt.plot(x, y[:, 0], label = 'first')
plt.plot(x, y[:, 1], label = 'second')
plt.plot(x, y[:, 2:])
plt.legend()
plt.show()
9.水平垂直参考线、坐标轴标签加粗
import matplotlib.pyplot as plt
import numpy as np
import pandas as pdx = np.linspace(0, 10, 100)
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)# 将 x 轴第 4 个标签值加粗,红色
ax.get_xticklabels()[4].set(weight='heavy', color='red') # 在 x = np.pi 处设置垂直参考线
ax.axvline(np.pi, alpha=0.3, color='red') # 将 y 轴第 2 个标签值加粗,蓝色
ax.get_yticklabels()[2].set(weight='heavy', color='blue') # 在 y = 0.5 处处设置水平参考线
ax.axhline(y = 0.5, alpha=0.3, color='red') plt.show()
10.在图上添加文字与注释
ax.text(x, y, 文本, 字体大小, 颜色等)
fig, ax = plt.subplots(figsize=(12, 4))
# 这里是画一个图 # figsize 是设置这个图的宽度和高度
data.plot(ax = ax) # 面向对象画图风格之另一种形式# 提前设计风格
style = dict(size = 10, color = 'red')
style2 = dict(size = 10, color = 'red', ha = 'center')
# ha = 'center'表示(x, y)为文本框中心# (x, y)一般需要多次调试才能得到好看的图片
ax.text('2012-1-1', 3950, "New Year's Day", **style)
ax.text('2012-7-4', 4250, "Independence Day", **style2)
ax.text('2012-9-4', 4850, "Labor Day", **style2)
ax.text('2012-10-31', 4600, "Halloween", ha='right', **style)
ax.text('2012-11-25', 4450, "Thanksgiving", **style2)
ax.text('2012-12-25', 3850, "Christmas ", ha='right', **style)
(4)面向对象风格下的绘图设置
1.matlab 风格与面向对象风格对比
plt.plot() → ax.plot()
plt.legend() → ax.legend()
plt.axis() → ax.axis()
plt.xlabel() → ax.set_xlabel()
plt.ylabel() → ax.set_ylabel()
plt.xlim() → ax.set_xlim()
plt.ylim() → ax.set_ylim()
plt.title() → ax.set_title()
2.用 ax.set() 方法一次性设置所有的属性
x = np.linspace(0, 10, 1000)
ax = plt.axes()
ax.plot(x, np.sin(x), '-r')
ax.plot(x, np.cos(x), ':g')
ax.set(xlim = (-1, 11), ylim = (-1.5, 1.5), xlabel = 'x', ylabel = 'sin(x) and cos(x)', title = 'sin-cos sample')
ax.legend(['sin(x)', 'cos(x)'], loc = 'upper center')
plt.show()
(5)常用2D图形
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.style.use('seaborn-whitegrid')
1.plt.plot()
例子1:折线图
fig = plt.figure()
ax = plt.axes()
x = np.linspace(0, 10, 10)
ax.plot(x, np.sin(x))
plt.show()
例子2:有点也有连接线
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, '-ok')
# 直线(-)、圆圈(o)、黑色(k)
# 线条风格 + 点的风格 + 线条颜色
# 线条风格默认为'-'
plt.show()
例子3:有点无连接线,也就是散点图
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, 'ok') # 圆圈(o)、黑色(k)
# 当不设置线的风格时,就只有点了,也就是散点图
plt.show()
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, 'v', color = 'black') # 点的风格设置为'v',倒立金字塔形状
plt.show()
例子4:其他参数使用
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.plot(x, y, '-p', # p 是一种点的形状:六边形color = 'red', markersize = 10, # 设置点的大小linewidth = 2, # 设置线的宽度markerfacecolor = 'red', # 设置散点形状内部的颜色markeredgecolor = 'c', # 设置散点形状边缘的颜色markeredgewidth = 3) # 设置散点形状边缘的宽度
plt.ylim(-1.2, 1.2)
plt.show()
2.plt.scatter() 散点图
scatter 在创建散点图时具有更高的灵活性,可以单独控制每个散点与数据匹配,也可以让每个散点具有不同的属性
所有参数
- s 表示大小。标量或者序列对象
- c 表示颜色。标量或者序列对象
- marker 表示点的形状。
- cmap 表示颜色范围。可填 viridis、plasma、inferno、magma, Greens 等
- alpha 表示透明度。0-1 之间。0 表示完全透明。
普通散点图
x = np.linspace(0, 10, 30)
y = np.sin(x)
plt.scatter(x, y, marker = 'o')
plt.show()
四维信息的散点图
横坐标、纵坐标、点的大小、点的颜色代表四种信息
rng = np.random.RandomState(0)
x = rng.randn(100)
y = rng.randn(100)
colors = rng.rand(100) # 100 个 0-1 之间的数
sizes = 1000 * rng.rand(100)
plt.scatter(x, y, c = colors, s = sizes, alpha = 0.3, cmap = 'plasma' ) # cmap 设置点的颜色种类#plt.colorbar() # 在右侧显示颜色条
plt.colorbar(label = 'log$_{10}$(population)')
# 显示颜色条,同时设置颜色条的标题
#打印下标的方法:log$_{10}$ # 打印上标的方法 km$^2$plt.show()
自定义图例的四维散点图
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.style.use('seaborn-whitegrid')# 1)加载数据
cities = pd.read_csv(r'D:\PythonData\data\california_cities.csv') # dataframe
lat, lon = cities['latd'], cities['longd'] # 选取两列,也就是两个 series
population, area = cities['population_total'], cities['area_total_km2'] # 选取两列,也就是两个 series# 2)画四维信息散点图
plt.scatter(lon, lat, label = None, c = np.log10(population),cmap = 'viridis', s = area, linewidth = 0, alpha = 0.5)
plt.axis('equal')
plt.xlabel('longtidude')
plt.ylabel('latitude')
plt.colorbar(label = 'log$_{10}$(population)') # 设置颜色条的标题
# 打印下标的方法:log$_{10}$ # 打印上标的方法 km$^2$# 3)创建自定义图例(画一些带标签和示例点的“空散点”)
for area in [100, 300, 500]:plt.scatter([],[], c = 'k', alpha = 0.3, s = area, label = str(area)+'km$^2$')plt.legend(scatterpoints = 1, frameon = False, labelspacing = 1, title = 'City Area')
# scatterpoints 参数:设置图例中的示例点的个数
# labelspacing 参数:图例条目之间的垂直空间# 4)显示图像
plt.title('California Cities: Area and Population')
plt.show()
理解自定义图例
for area in [100, 300, 500]:# 画 3 个没有数据的散点图# 并对散点图设置标签plt.scatter([],[], c = 'k', alpha = 0.3, s = area, label = str(area)+'km$^2$') # 再对散点图设置示例点
plt.legend(scatterpoints = 2, frameon = False, labelspacing = 1, title = 'City Area')plt.show()
3.plt.errorbar() 误差图
①图形展示
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
plt.style.use('seaborn-whitegrid')x = np.linspace(0, 10, 50)
y = np.sin(x)
dy = 0.4
plt.errorbar(x, y, yerr = dy, fmt = 'o', ecolor = 'r', elinewidth = 2)
plt.show()
②全部参数
help(plt.errorbar)
- xerr, yerr:标量, 或者序列 shape(N,),或者序列 shape(2,N)(设置误差线下方和上方的长度)
- fmt:设置中间点的形状
- ecolor:设置误差线的颜色
- elinewidth:设置误差线的线宽,标量
- mfc,mec,ms,mew 分别是 markerfacecolor,markeredgecolor,markersize,markeredgewidth 的简写
- barsabove:布尔,表示误差线是否在点的上方。默认为 False,表示 marker 在误差线上方。True 表示误差线在上方
- lolims, uplims, xlolims, xuplims:布尔,默认为 False。前两个配合 yerr 参数使用,后两个配合 xerr 使用
- 以前两个为例:
- ①不使用该参数时,上下各画一条误差线,且不带箭头
- ②单独使用一个参数时,比如只使用 lolims = True,表示不画下方误差线,上方误差线要画并且还带一个箭头
- ③同时使用两个参数时,上下都要画误差线,并且都要带箭头
- errorevery:标量。默认为 1。表示以多少步长进行画误差线
x = np.linspace(0, 10, 50)
dy = 0.4
y = np.sin(x)
plt.errorbar(x, y,yerr = dy,fmt = 'p',ecolor = 'r',elinewidth = 2,mfc = 'c',mec = 'k',ms = 5,mew = 2,barsabove = True,lolims = True,errorevery = 2)plt.show()
4.plt.hist() 频次频率图
①图形解释
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn-whitegrid') # 每个柱状图的左右表示一个区间,高代表在这个区间里的数的个数
data = np.array([1, 2, 2, 3, 3, 4])
result = plt.hist(data)print(result[0])
# 每个区间频数的 array # [1. 0. 0. 2. 0. 0. 2. 0. 0. 1.]
print(result[1])
# 区间分界点的 array # [1. 1.3 1.6 1.9 2.2 2.5 2.8 3.1 3.4 3.7 4. ]
# 默认 10 个区间plt.show()
②全部参数
data = np.array([1, 2, 2, 3, 3, 4])result = plt.hist(x = data,bins = 3, # 设置区间个数 # 默认划分为 10 个区间range = (0, 10), # 设置区间上下限 #可不设置,默认值为 x.min()和 x.max()density = False, # 频率 或者 频数 # 默认 False表示频数weights = np.array([1]*len(data)), # 设置权重 #可不设置,默认权重全为 1cumulative = False, # 是否累积画图 # 默认 Falsebottom = 0, # 设置纵坐标基底 # 默认为 0histtype = 'stepfilled', # 设置图形类别align = 'mid', # 设置区间直方图中点在区间的上中下位置log = False, # 是否采用科学计数法orientation = 'vertical', # 垂直 or 水平图color = 'y', # 图形主体颜色edgecolor = 'red', # 图形边缘颜色alpha = 0.2 # 图形透明度
) print(result[0]) # 每个区间频数的 array
# [5. 1. 0.]print(result[1]) # 区间分界点的 array
# [ 0. 3.33333333 6.66666667 10. ]plt.show()
参数详细解释:
- bins参数:整数或序列对象。为整数时,设置区间个数,默认 10 个。每个区间左闭右开,最后一个区间左右都闭。为序列对象时,由它的所有值划分区间。
- range 参数:配合 bins 参数使用。bins 为整数时,设置区间的下限和上限,默认为 x.min()和 x.max()。如果 bins 是一个序列对象,那么该参数无作用。
- density 参数:默认为 False,表示图的纵坐标为频数,就是当前区间的值出现个数。为 True 时纵坐标为归一化的密度:所有直方图面积之和为 1,每个直方图的面积 = 频率,而频率 = 当前区间频数/总个数,面积 = 高度 * 宽度,所以有高度 = 频数/总个数/宽度。
- weights 参数:权重。和 x 一样长的序列对象。默认值为1。若没有设置density=True 时,而设置了该参数,则直方图的高度将等于频数乘以相应的权重。如果设置了 density = True,则该参数无用。
- cumulative 参数:默认为 False。取值为 False 或者 0 时,不进行累积画图。取值为 True 或者正数时,从左到右累积。取值为负数时,从右到左累积。
- bottom 参数:标量或序列对象。设置纵坐标的基底,默认为 0。 比如设置为 10,则实际频数为 1 的区间,在图中就是 10+1。
- histtype 参数:设置要绘制的直方图的类型。bar(默认)、barstacked、step、stepfilled(内部被填充,常用)
- align 参数:{'left', 'mid', 'right'}。设置每个直方图中点的位置,left 表示取当前区间的下限,right 取区间上限,默认为 mid。
- log 参数:布尔,纵坐标频数是否采用科学计数法,默认 False。
- orientation 参数: {'horizontal', 'vertical'}。画水平还是垂直的图。默认 vertical。
- color 和 edgecolor:传递标量或序列对象,设置颜色
- alpha 参数:用来设置透明度,0-1 之间,0 表示完全透明
例子1:按指定区间统计
data = np.array([1, 1.6, 2, 2, 2.4, 3, 3, 3, 3.1, 3.9, 4, 4, 4, 4])
bins = np.array([1, 2, 2.5, 3.5, 4])
plt.hist(data, bins = bins, alpha = 0.5, histtype = 'barstacked', color = 'steelblue', edgecolor = 'r')
plt.show()
例子2:平均划分区间统计
data = np.array([1, 1.6, 2, 2, 2.4, 3, 3, 3, 3.1, 3.9, 4, 4, 4, 4])
bins = 4
plt.hist(data, bins = bins, range = (1,5), alpha = 0.5,histtype = 'barstacked', color = 'steelblue', edgecolor = 'r')
plt.show()
例子3:设计权重使得纵坐标为频率
myarray = np.random.rand(10)
weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights = weights, alpha = 0.5,histtype = 'stepfilled', color = 'c', edgecolor = 'r')
plt.show()
例子4:画多个样本的数据
# 对不同的分布特征的样本进行对比时
# 将 histtype=‘stepfilled’与 alpha 参数搭配使用效果好x1 = np.random.normal(0, 0.8, 1000)
x2 = np.random.normal(-2, 1, 1000)
x3 = np.random.normal(3, 2, 1000)kwargs = dict(histtype = 'stepfilled', alpha = 0.3, density = True, bins = 40)plt.hist(x1, **kwargs)
plt.hist(x2, **kwargs)
plt.hist(x3, **kwargs)plt.show()
5.plt.bar()柱状图
常规柱状图
主要参数
plt.bar(x, height, width=0.8, bottom=None, color=None, **kwargs)
- x: 每一个柱形中点的 X 坐标
- height:每一个柱形的高度
- width: 柱形的宽度
- align 参数:{'center', 'edge'},默认 center,x 为柱形的中点。edge 表示 x 为柱形的左侧。要实现右侧,设置负的 width
- rwidth:柱子与柱子之间的距离,默认是 0
- bottom: 柱形的 Y 坐标的基底。默认是 0
其他通用参数
- color: 柱形的颜色
- edgecolor:柱状图边的颜色
- linewidth 条边的宽度。如果是 0,不画边。
- tick_label 坐标轴标签,默认数字标签
- xerr, yerr:形状(N,)或形状(2,N)的标量或类数组。加水平/垂直误差线。形状(2,N)是设置负正值。
- ecolor:误差线的颜色。默认黑色。
- log。默认 False。纵坐标是否科学计数法。
- orientation : {'vertical', 'horizontal'}。水平图或者垂直图
画图示例
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像的汉字显示为方块的问题name_list = ['Monday', 'Tuesday', 'Friday', 'Sunday']
num_list = [1.5, 0.6, 7.8, 6]plt.bar(range(len(num_list)), num_list, width = 0.8, color = 'rgby')
# 第一个柱状图的中心在数 0,第二个 1,第三个 2 # 同时取四种颜色plt.xlabel(u"日期")
plt.ylabel(u"访问量")
plt.title(u"渠道访问量统计表")
plt.ylim(0, 8.5)idx = np.arange(len(name_list))
width = 0
plt.xticks(idx + width, name_list) # 设置横坐标刻度值和名称
plt.show()
堆叠柱状图
巧用 bottom 参数画堆叠柱状图
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像的汉字显示为方块的问题name_list = ['Monday','Tuesday','Friday','Sunday']
num_list_boy = [1.5, 0.6, 7.8, 6]
num_list_girl = [1,2,3,1]plt.bar(range(len(name_list)), num_list_boy, label = 'boy', fc = 'y')
plt.bar(range(len(name_list)), num_list_girl, bottom = num_list_boy, label='girl', fc = 'r')plt.xlabel("日期")
plt.ylabel("访问量")
plt.title("渠道访问量统计表")
plt.ylim(0, 12)
plt.legend()idx = np.arange(len(name_list))
plt.xticks(idx, name_list)
plt.show()
瀑布图
巧用 bottom 参数画瀑布图
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False
# 解决保存图像的汉字显示为方块的问题name_list = ['Monday','Tuesday','Friday','Sunday']
data = [1.5, 0.6, 7.8, 6]bottom = np.array(data).cumsum() # [ 1.5 2.1 9.9 15.9]
print(bottom[0:-1]) # [1.5 2.1 9.9]
bottom = np.concatenate([np.array([0]), bottom[0:-1]])
# 纵向合并 # [0. 1.5 2.1 9.9]plt.bar(range(len(name_list)), data, bottom = bottom, label = 'boy',fc = 'r')plt.xlabel("日期")
plt.ylabel("访问量")
plt.title("渠道访问量统计表")
plt.ylim(0, 12)
plt.legend(loc = 2)idx = np.arange(len(name_list))
plt.xticks(idx, name_list)plt.show()
并列柱形图
name_list = ['Monday','Tuesday','Friday','Sunday']
num_list = [1.5, 0.6, 7.8, 6]
num_list1 = [1, 2, 3, 1]
x = list(range(len(num_list))) # [0, 1, 2, 3]total_width, n = 0.8, 2
width = total_width / n
# 得到单个柱状图的宽度 # 这里是 0.4 # 也就是说柱状图一半的宽度就是 0.2plt.bar(x, num_list, width = width, label = 'boy', fc = 'y') # 画第一个柱形图for i in range(len(x)):x[i] = x[i] + width # 设置第二个柱状图的中点位置,使得两个柱状图是挨着的
print(x) # [0.4, 1.4, 2.4, 3.4]
plt.bar(x, num_list1, width = width, label ='girl', fc = 'r') # 画第二个柱形图plt.legend()index = np.arange(len(name_list))
plt.xticks(index, name_list)plt.show()
6.plt.pie()饼图
# ①加载数据
edu = [0.2515, 0.3724, 0.3336, 0.0368, 0.0057]
labels = ['中专', '大专', '本科', '硕士', '其他']explode = [0, 0.1, 0.1, 0, 0] # 用于突出显示大专和本科学历人群
colors = ['#9999ff', '#ff9999', '#7777aa', '#2442aa', '#dd5555'] # 自定义颜色# ②中文乱码和坐标轴负号的处理
plt.rcParams['font.sans-serif'] = ['fangsong']
plt.rcParams['axes.unicode_minus'] = False # ③图形设置 1
# 将横、纵坐标轴标准化处理,保证饼图是一个正圆,否则为椭圆
plt.axes(aspect = 'equal')# 控制 x 轴和 y 轴的范围
plt.xlim(0, 3.8)
plt.ylim(0, 3.8)# ④绘制饼图
plt.pie(x = edu, # 绘图数据explode = explode, # 突出显示大专人群labels = labels, # 添加教育水平标签colors = colors, # 设置饼图的自定义填充色autopct = '%.1f%%', # 将数据百分比化,比如 0.1 变为 10%。这里保留一位小数。pctdistance = 0.5, # 设置百分比标签与圆心的距离,0-1 之间,0 表示圆心,1 表示圆边界,大于 1 表示圆外labeldistance = 0.8, # 设置教育水平标签与圆心的距离startangle = 180, # 设置饼图的初始角度counterclock = False, # 是否逆时针展示数据radius = 1.5, # 设置饼图的半径wedgeprops = {'linewidth': 2, 'edgecolor': 'red'}, # 设置饼图内外边界的属性值textprops = {'fontsize': 12, 'color': 'w'}, # 设置文本标签字体的大小和颜色center = (1.9, 1.9), # 设置饼图这个圆的圆心坐标frame = 0) # 是否显示饼图的图框,bool 值。非 0 和 True 表示设置,0 和 False 表示不设置。# ⑤图形设置 2
# 删除 x 轴和 y 轴的刻度
plt.xticks(())
plt.yticks(())# 添加图标题
#plt.title('芝麻信用失信用户教育水平分布')# ⑥显示图形
plt.show()
7.极坐标轴图形
xn = np.linspace(0, 2*np.pi, 400) # 表示角度范围 0,这里是 0-2pi
yn = np.sin(xn**2)fig, axes = plt.subplots(2, 2, subplot_kw=dict(polar=True))
# 第三个参数为关键axes[0, 0].plot(xn, yn)
axes[1, 1].scatter(xn, yn)plt.subplots_adjust(wspace = 0.4, hspace = 0.4)plt.show()
xn = np.linspace(0, 2*np.pi, 400) # 表示角度范围 0,这里是 0-2pi
yn = np.sin(xn**2)
fig, axes = plt.subplots(subplot_kw=dict(polar=True))
# 第三个参数为关键
axes.plot(xn, yn)
plt.show()
8.条形统计图
参考:Python数据可视化-seaborn库之countplot - cymx66688 - 博客园
(6)画中画
方法 1:两次 plt.axes()
①plt.axes()参数讲解
参数:[bottom, left, width, height]
前两个参数决定坐标轴的原点
后两个参数决定坐标轴的宽度和高度
默认是创建一个标准的坐标轴,填满整张图
②画中画原理:创建一大一小两个坐标轴
# ①画中画原理:创建一大一小两个坐标轴
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')ax1 = plt.axes() # 不设置表示使用默认坐标轴
ax2 = plt.axes([0.65, 0.65, 0.2, 0.2])plt.show()
③画个“画中画”
x = np.linspace(0, 10, 100)
ax1 = plt.axes()
ax2 = plt.axes([0.65, 0.65, 0.2, 0.2])ax1.plot(x, np.sin(x), color = 'c')
ax2.plot(x, np.cos(x), color = 'r')ax1.legend(['sin(x)'], loc = 'upper center')
ax2.legend(['cos(x)'], loc = 'upper center')plt.show()
方法 2:两次 fig.add_axes()
# 画两个图,设置不同的坐标轴原点x = np.linspace(0, 10) # 默认 50 个点
fig = plt.figure()ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.4], xticklabels = [], ylim = (-1.2, 1.2))
ax1.plot(x, np.sin(x))
ax1.legend(['sinx'], loc = 9)ax2 = fig.add_axes([0.6, 0.2, 0.2, 0.1], ylim = (-1.2, 1.2))
ax2.plot(x, np.cos(x))
ax2.legend(['cosx'], loc = 9)plt.show()
(7)三维图
1.导入 3d 模块
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn-whitegrid')
from mpl_toolkits import mplot3d # 导入 3d 模块fig = plt.figure()
ax = plt.axes(projection = '3d')
plt.show()
2.三维散点图与线
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn-whitegrid')
from mpl_toolkits import mplot3d ax = plt.axes(projection = '3d')zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline, 'gray') # 前后是 x 的坐标,左右是 y 的坐标zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata, c = zdata, cmap = 'plasma')plt.show()
3.线框图
def f(x, y):return np.sin(np.sqrt(x ** 2 + y ** 2))x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
print(Z.shape) # (30, 30)fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.plot_wireframe(X, Y, Z, color = 'c') # 线框图的每个 XYZ 必须是二维的
ax.set_title('wireframe')plt.show()
原理探究:线框图就是曲线围绕 z 轴旋转了 360 度
def f(x, y):return np.sin(np.sqrt(x ** 2 + y ** 2))x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
z = f(x,y)fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.plot3D(x,y,z)plt.show()
4.曲面图
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('seaborn-whitegrid')
from mpl_toolkits import mplot3ddef f(x, y):return np.sin(np.sqrt(x ** 2 + y ** 2))x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)ax = plt.axes(projection = '3d')
ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1,cmap = 'viridis', edgecolor = 'none', color = 'r')
# ax.plot_surface(X, Y, Z, cmap = 'viridis',
# edgecolor = 'none',
# rcount = 100, ccount = 100)
ax.set_title('surface')plt.show()
主要参数含义
help(ax.plot_surface)
plot_surface(X, Y, Z, *args, norm=None, vmin=None, vmax=None, lightsource=None, **kwargs)
- rcount, ccount。整数。默认 50。值越大曲面分得越细。
- rstride, cstride。整数。默认 10。和 rcount,ccount 只能有 1 个。越小越细
- cmap:颜色范围
- color:表面颜色。若 cmap 有值,则参数设置无效。
- facecolors:表面颜色(序列对象)
5.等高线图与热力图
函数
- matplotlib.pyplot contourf 和 matplotlib.pyplot.contour 都是绘制等高线的
- 不同点在于 contour() 是绘制轮廓线,contourf()会填充轮廓。除非另有说明,否则两个版本的函数是相同的。
参数
coutour([X, Y,] Z,[levels], **kwargs)
- X,Y : X,Y,Z 都是 2 维数组时,它们的形状必须相同。(例如,经由创建 numpy.meshgrid()) 。如果都是 1 维数组时,len(X)是 Z 的列数,而 len(Y) 是 Z 中的行数。
- Z:必须二维数组,绘制轮廓的高度值
- levels:int 或类似数组,可选。确定轮廓线/区域的数量和位置
- alpha:透明度,介于 0(透明)和 1(不透明)之间。
- cmap:str 或 colormap ,可选。设置颜色类别。
等高线图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# 计算 x,y 坐标对应的高度值
def f(x, y):return (1 - x / 2 + x ** 3 + y ** 5) * np.exp(-x ** 2 - y ** 2)# 生成 x,y 的数据
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)# 把 x,y 数据生成 mesh 网格状的数据,因为等高线的显示是在网格的基础上添加上高度值
X, Y = np.meshgrid(x, y)# 填充等高线
plt.contourf(X, Y, f(X, Y))# 显示图形
plt.show()
热力图:更改 cmap 参数的值即可实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt# 计算 x,y 坐标对应的高度值
def f(x, y):return (1 - x / 2 + x ** 3 + y ** 5) * np.exp(-x ** 2 - y ** 2)# 生成 x,y 的数据
n = 256
x = np.linspace(-3, 3, n)
y = np.linspace(-3, 3, n)# 把 x,y 数据生成 mesh 网格状的数据,因为等高线的显示是在网格的基础上添加上高度值
X, Y = np.meshgrid(x, y)# 填充等高线
plt.contourf(X, Y, f(X, Y), cmap = plt.cm.hot)# 显示图形
plt.show()
end