python导入数据画多列直方图_Python数据处理之Matplotlib学习

摘要这一篇文章会介绍一下python数据分析中matplotlib的使用。把一些常用的方法记录在此,方便自己以后的查阅与学习。

Matploylib介绍

在数据分析的时候,我们经常需要将数据可视化,这是就需要使用matplotlib模块了。

我们首先将matplotlib.pyplot导入后命名为plt, 在后面的内容中,出现的plt都默认是matplotlib.pyplot包

import matplotlib.pyplot as plt

%matplotlib inline

在使用jupyter的时候需要加上后面这句.

可视化的一些 Tips

当数据相差比较大的时候,绘制图像的时候有一部分数据挤在一起,这个时候可以使用 Log 对数据先进行对数处理,接着在进行绘图;

当坐标轴的数字比较大的时候,可以将其除一个数,使其变小,在 label 上进说明即可;

matplotlib基础

matplotlib是面向对象的绘图工具包,绘制的图形中每一个元素都是一个对象,比如线条,文字,刻度等信息,可以通过修改这些对象的属性,从而改变绘图样式。

matplotlib中主要的绘图对象列表如下:

Figure对象,可以想象为一张画布;

Axes对象,字面理解为坐标轴(因为每一个 Axes 都有一套 X Y轴坐标系,绘制图形时基于此坐标系绘制。) 也可以认为是子图,在一个Figure对象中可以包含多个Axes对象,也就是说一张画布可以包含多个子图;

Line2D对象,代表线条;

Text对象,代表了文字,比如一张子图需要标题,就可以使用一个Text对象;

下面我们先来看一个简单的例子:

N = 50

x = np.random.random(N) # 横坐标

y = np.random.random(N) # 纵坐标

colors = np.random.random(N) # 每个坐标的颜色

area = np.pi*(10*np.random.random(N))**2 # 每个坐标的颜色

plt.scatter(x,y,s=area,c=colors,alpha=0.5)

plt.show()

我们可以看一下画出来的图像,是一个散点图

snipaste_20180309_134441.png

在上面这个例子中,我们没有创建任何Figure对象,这是因为plt会默认创建Figure对象并保存在plt内部。

下面我们通过plt.figure()创建一个新的Figure对象,然后在此Figure对象上创建Axies对象。

fig = plt.figure()

ax1 = fig.add_subplot(2,2,1) #添加一个Axes对象到布局为两行两列的第一个位置

ax2 = fig.add_subplot(2,2,2)

ax3 = fig.add_subplot(2,2,3)

ax1.plot(np.random.randn(50).cumsum(), 'k--')

ax2.hist(np.random.randn(100), bins=20, color='k')

ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))

fig.show()

我们首先创建一个Figure对象,接着插入三个Axes对象,接着在Axes对象上绘制累积和线图,直方图以及散点图。

我们要注意的是上面的fig.add_subplot(2,2,1)表示添加一个Axes对象到布局为两行两列的第一个位置。

我们看一下上面代码绘制出图像的样子:

snipaste_20180309_135726.png

到这里我们就把matplotlib的基本功能看完了,下面我们看一下常用的属性设置。

子图的绘制

这里我们详细说明一下子图的绘制. matplotlib使用plt.subplots来绘制子图, 我们可以使用下面的命令绘制一个2行, 5列的子图.

fig, axs = plt.subplots(2, 5, figsize=(15, 6), facecolor='w', edgecolor='k')

fig.subplots_adjust(hspace = .5, wspace=.001)

axs = axs.ravel()

for i in range(10):

axs[i].contourf(np.random.rand(10,10),5,cmap=plt.cm.Oranges)

axs[i].set_title(str(250+i))

子图共享坐标轴

有下面两种方式可以共享子图的坐标轴, 我们可以设置为全局共享, 及所有的子图都能共享坐标轴:

fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)

我们也可以为某一个单独的子图设置共享:

fig=plt.figure()

ax1 = plt.subplot(211)

ax2 = plt.subplot(212, sharex = ax1)

下面看一个简单的例子, 下面的setp表示Set a property, 是用来设置坐标轴的属性的:

import matplotlib.pyplot as plt

import numpy as np

t = np.arange(0.01, 5.0, 0.01)

s1 = np.sin(2 * np.pi * t)

s2 = np.exp(-t)

s3 = np.sin(4 * np.pi * t)

ax1 = plt.subplot(311)

plt.plot(t, s1)

plt.setp(ax1.get_xticklabels(), fontsize=6)

# share x only

ax2 = plt.subplot(312, sharex=ax1)

plt.plot(t, s2)

# make these tick labels invisible

plt.setp(ax2.get_xticklabels(), visible=False)

# share x and y

ax3 = plt.subplot(313, sharex=ax1, sharey=ax1)

plt.plot(t, s3)

plt.xlim(0.01, 5.0)

plt.show()

20201020_155246_s3mmhd6.jpg

常用属性设置

matplotlib绘制的图形可以设置各种属性,比如设置坐标系的刻度,标题,标签等属性。 matplotplib绘制图形时,基于X, Y轴坐标系绘图。我们可以设置X, Y坐标的各种属性,比如刻度,范围,标签等属性。

matplotlib显示中文

我们在开头加上下面的代码即可正常显示中文.

from pylab import * # 设置显示中文

mpl.rcParams['font.sans-serif'] = ['SimHei']

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

关于这里字体名称的设置,我们可以通过下面的方式来进行查看:

import matplotlib

a=sorted([f.name for f in matplotlib.font_manager.fontManager.ttflist])

for i in a:

print(i)

这里会打印出所有的注册的字体的名称,大致如下所示:

20201110_164653_0rr65wk.jpg

可以使用「FZShuTi」表示方正舒体。

数字与颜色的转换-map number to color

import matplotlib.cm as cm

print(cm.hot(0.3))

也可以使用下面的样式进行绘制:

cmap = plt.get_cmap('rainbow', 12)

设置标题,坐标刻度

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

# 设置标题

ax.set_title('Test Title')

major_ticks = np.arange(0, 101, 20)

minor_ticks = np.arange(0, 101, 5)

# 设置刻度

ax.set_xticks(major_ticks)

ax.set_xticks(minor_ticks, minor=True)   # 这个是短线

ax.set_yticks(major_ticks)

ax.set_yticks(minor_ticks, minor=True)

# 设置 X, Y 轴 标签

ax.set_xlabel("X axis")

ax.set_ylabel("Y axis")

# 设置网格

ax.grid(which='minor', alpha=0.2)

ax.grid(which='major', alpha=0.5)

# 添加文字

ax.text(42.5, 50, "Hello World")

fig.show()

可以看到下面的效果

snipaste_20180309_140508.png

设置标题位置

直接使用 set_title 会默认将标题生成在图像的上部。但是有的时候我们需要自动调整 title 的位置。我们可以通过设置 set_title 中的参数 y 来改变 title 的位置。下面看一个简单的例子,显示默认生成的标题的位置:

fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))

ax.set_title("Title Position")

生成的结果如下所示:

20201113_154632_bbhdh39.jpg

上面是默认生成的标题的位置,我们可以通过控制 y 来修改标题的位置。如下所示:

fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))

ax.set_title("Title Position", y=1.5)

这个时候看生成的效果,可以看到他的标题的位置就在图像的上方一些:

20201113_154844_v999lzg.jpg

加入文字

对于文字, 我们可以再外面加上边框等. 上面是在文字周围加上边框, 底色是红色.

text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))

例如下面是对MNIST降维的结果

ax.text(np.mean(v_x[ix][:,0]), np.mean(v_x[ix][:,1]), key, fontsize=18, bbox=dict(facecolor='white', alpha=0.5))

20200716_174542_t5j2zj5.jpg

关于这张图片的详细生成过程, 可以参考链接, t-SNE与AE对MNIST可视化

设置坐标轴刻度与坐标轴名称

注意, 在图中有两个部分, 我把他叫做坐标轴刻度与刻度名称, 坐标轴本身的名称. 我们通过下面一个小例子来看一下是如何来进行设置他们的.

from pylab import * # 设置显示中文

mpl.rcParams['font.sans-serif'] = ['SimHei']

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

x = np.linspace(0, 1, 100)

fig = plt.figure(figsize=(12,8))

ax = fig.add_subplot(1,1,1)

ax.set_title(u'设置曲线颜色与图例', fontsize=17)

# 绘制图形

ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')

# 设置坐标轴的标签

ax.yaxis.set_tick_params(labelsize=15) # 设置y轴的字体的大小

ax.set_xticks(np.linspace(0, 1, 11)) # 设置xticks出现的位置

xticks = [i if i in [0, 0.5, 0.8, 1.0] else '' for i in np.linspace(0, 1, 11)] # 只显示特定数字

ax.set_xticklabels(xticks, rotation=-45, fontsize=17) # 设置xticks的值

# 设置坐标轴名称

ax.set_ylabel("这是Y轴", fontsize='xx-large')

ax.set_xlabel('这是X轴',  fontsize='xx-large')

# 自动生成图例

ax.legend(fontsize=17)

# 设置图像x,y轴的范围,都是从0-1

ax.axis([0, 1, 0, 1])

fig.show()

这上面的内容包括:

设置坐标轴刻度的间隔

设置坐标轴刻度的名称, 调整大小和倾斜角度

设置x轴, y轴的名称

20200322_023151_wz2dthq.jpg

设置坐标轴为log scale

有的时候, 我们需要设置坐标轴为log scale, 我们可以使用plt.yscale进行设置, 可以参考下面的代码.

dt = 0.01

x = np.arange(-50.0, 50.0, dt)

y = np.arange(0, 100.0, dt)

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

ax.plot(x, y)

# 设置y scale

plt.yscale('log')

plt.ylabel('logy') # 设置y轴的label

最后绘制出来的结果如下图所示, 看y轴的刻度, 可以看到此时是log scale了:

20200512_205516_15m23ed.jpg

设置曲线颜色,图例

# 设置显示中文

from pylab import *

mpl.rcParams['font.sans-serif'] = ['SimHei']

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

x = np.linspace(0, 1,100)

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

ax.set_title(u'设置曲线颜色与图例')

# 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex

ax.plot(x, x ** (1/8), 'b--', label=r'$y = x^{1/8}$')

ax.plot(x, x ** 8, 'r--', label=r'$y = x^{8}$')

ax.plot(x, x ** (1/2), 'r.', label=r'$y = x^{1/2}$')

ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')

ax.plot(x, x, 'g-', label=r'$y = x$')

# 自动生成图例

ax.legend()

# 设置图像x,y轴的范围,都是从0-1

ax.axis([0, 1, 0, 1])

fig.show()

上面的代码运行完毕后我们可以看到如下的图像

snipaste_20180309_141925.png

关于一些常用的样式,我们记录一下:

线的样式linestyle=有

'-' 默认实线

'--' 虚线

'-.' 间断线

':' 点状线

图例与pandas结合使用

有的时候, 我们的使用pandas的数据来进行绘图的时候, 图例是dataframe中某一列的数据, 这个时候我们就可以使用下面的方式插入图例.

plt.legend(legend.values,loc=4)

关于图例位置自定义

要是我们想要自定义图例的位置, 比如说希望图例出现在曲线的上面, 或者周围, 我们可以使用ax.text来进行实现. 我们看一下下面的这个例子.

from pylab import * # 设置显示中文

mpl.rcParams['font.sans-serif'] = ['SimHei']

plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

x = np.linspace(0, 1,100)

fig = plt.figure(figsize=(12,8))

ax = fig.add_subplot(1,1,1)

ax.set_title(u'设置曲线颜色与图例')

# 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex

ax.plot(x, x ** 8, 'r--', label=r'$y = x^{8}$')

ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')

# 手动设置图例

ax.text(x[-10], 0.9*(x ** 8) [-10], r'$y = x^{8}$', fontsize=17)

ax.text(x[-26], 1.2*(x ** 2) [-26], r'$y = x^{2}$', fontsize=17)

# 自动生成图例

ax.legend()

# 设置图像x,y轴的范围,都是从0-1

ax.axis([0, 1, 0, 1])

fig.show()

最终的实现的效果如下图所示, 可以看到在两条曲线周围都有了图例:

20200322_021047_fb5aikw.jpg

绘制图像的样式

绘制xkcd样式图片

我们可以绘制漫画风格的图片,只需要在初始设定plt.xkcd()即可;

plt.xkcd()

fig = plt.figure()

ax = fig.add_subplot(1, 1, 1)

np.random.seed(7)

x = np.linspace(1, 10, 50)

y = 2*x + 0.5*x**2 + 0.3*x**4 - 0.025*x**5 + 5*np.random.rand(50)

ax.scatter(x, y)

最终的绘制效果如下图所示:

20190413_125039_ywdd6py.jpg

我们需要注意的是, 在设置xkcd样式的时候, 可以这样写, 这样可以保证只有当前的图像应用这个风格.

with plt.xkcd():

# This figure will be in XKCD-style

fig1 = plt.figure()

# ...

# This figure will be in regular style

fig2 = plt.figure()

关于 xkcd 样式中文的设置,需要在定义风格之后进行,下面是一个例子:

plt.xkcd()

plt.rcParams['font.family'] = ['FZShuTi']

下面看一个简单的例子,包含中文的 xkcd 样式的图像:

plt.xkcd()

plt.rcParams['font.family'] = ['FZShuTi'] # 这个需要在设置样式之后再设置

fig = plt.figure()

ax = fig.add_subplot(1, 1, 1)

ax.set_title(u'是否考虑自己未来的规划', fontsize=25)

x = np.arange(3)*1.2

y = [137, 140, 176] # 有

z = [33, 45, 38] # 没有

sum = [i+j for i,j in zip(y,z)] # 计算每个年纪所占的比例

y =  [i/j for i,j in zip(y,sum)]

z = [i/j for i,j in zip(z,sum)]

w=0.3

# 绘制多个bar在同一个图中, 这里需要控制width

plt.bar(x-w/2, y, width=w, align='center', label='有')

plt.bar(x+w/2, z, width=w, align='center', label='没有')

ax.set_xticks(x) # 设置xticks出现的位置

ax.set_xticklabels(['高一', '高二', '高三'], rotation='30', fontsize='xx-large')

ax.plot(x, y, c='green') # 画出曲线

ax.legend(bbox_to_anchor=(1, 0.95)) # 绘制图例

plt.show()

最终的输出格式如下所示:

20201113_160156_suj8rzh.jpg

图像的样式概览

除了上面的风格之外, 我们还有不同类型的风格可以进行设置. 例如下面是设置为默认的风格, 完整的风格间下面的参考链接.

# 设置画图的style

matplotlib.style.use('default')

绘制其他样式

对于绘制其他样式的图片,只需要修改plt.style.use即可,可以看下面的简单的例子

# 生成随机数据

np.random.seed(7)

x = np.linspace(1, 12, 10)

y = 2*x + 0.7*x**2 - 20*np.sin(x) - 20*np.cos(x) + 5*np.random.rand(10)

plt.style.use("ggplot") # 使用美观的样式

plt.scatter(x, y)

20190413_125322_rgqt9hy.jpg

设置图像颜色风格

除了上面设置图像的风格之外,我们还可以设置图像的颜色的风格。我们可以使用下面的命令来设置颜色的样式。

plt.set_cmap('RdBu')

我们来看一下最终的效果,使用柱状图来举一个例子。

x = np.arange(3)*1.2

y = [4, 9, 2]

z = [1, 2, 3]

k = [11, 12, 13]

ax = plt.subplot(111)

plt.set_cmap('RdBu')

w=0.3

# 绘制多个bar在同一个图中, 这里需要控制width

plt.bar(x-w, y, width=w, align='center')

plt.bar(x, z, width=w, align='center')

plt.bar(x+w, k, width=w, align='center')

ax.set_xticks(x) # 设置xticks出现的位置

ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')

ax.autoscale(tight=True)

plt.show()

这是一个绘制多个柱状图的方式,最终的效果如下所示。

20190704_203736_2wwyesb.jpg

设置图像颜色

除了上面使用指定的颜色,我们还可以指定我们需要的颜色,还是使用上面的柱状图作为例子我们简单来看一下。

其实基本是一样的,只是在绘图的时候指定了颜色,color=.

这三种颜色搭配我感觉还是不错的,在这里放一下(最终的效果见下面)。

#e0109c

#1b71f1

#9eed3b

x = np.arange(3)*1.2

y = [4, 9, 2]

z = [1, 2, 3]

k = [11, 12, 13]

ax = plt.subplot(111)

w=0.3

# 绘制多个bar在同一个图中, 这里需要控制width

plt.bar(x-w, y, width=w, color='#e0109c', align='center')

plt.bar(x, z, width=w, color='#1b71f1', align='center')

plt.bar(x+w, k, width=w, color='#9eed3b', align='center')

ax.set_xticks(x) # 设置xticks出现的位置

ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')

ax.autoscale(tight=True)

plt.show()

上面的颜色,绘制出来的效果如下所示。

20190704_204346_1cgnhdp.jpg

常用图像

我们在数据分析的时候,经常会用到各种各样的图像,我们就在这里总结一下。

线形图

这个就有点类似把一些散点连起来,我们使用Axes.plot进行绘制

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

x = np.arange(10)

y = x**2

ax.plot(x,y)

fig.show()

snipaste_20180309_142541.png

柱状图

纵向的柱状图

fig = plt.figure(figsize=(7,5))

ax = fig.add_subplot(1,1,1)

bar_data = [5, 20, 15, 25, 10]

bar_labels = ['Tom', 'Dick', 'Harry', 'Slim', 'Jim']

plt.bar(range(len(bar_data)), bar_data, tick_label=bar_labels)

plt.show()

20190428_211823_qxb49gz.jpg

堆叠柱状图

我们可以将两个柱状图以堆叠的形式画在一起。下面看一个简单的例子。

data = pd.DataFrame({'A': [1,3,2,4], 'B': [4,2,3,1], 'index': ['test1', 'test2', 'test3', 'test4']})

创建的数据样例如下所示:

20201031_153323_nugoh6z.jpg

我们希望画两个柱状图,第一个柱状图的高度就是上面表格中的A,第二个柱状图从A的位置开始画起,他的高度是B,这样就是两个柱状图堆叠在一起的效果。

plt.rcParams['figure.figsize'] = (10, 6)

plt.bar(x='index', height='A', data=data, width=1.0, label='下')

plt.bar(x='index', height='B', bottom='A', data=data, width=1, label='上')

ax = plt.gca()

ax.legend(prop=myfont, bbox_to_anchor=(1.0, 0.9))

最终的效果如下所示:

20201031_153645_jeflcph.jpg

横向柱状图

将上面的plt.bar替换为plt.barh可以画出横向的柱状图. 一般用在labels比较长,或是比较多的时候,比如说我们可以绘制出下面的图像.

20190428_212005_sunizkv.jpg

参考链接 : matplotlib绘图——柱状图

绘制多条柱状图

有的时候,我们需要绘制多条柱状图在一起,从而来进行比较,可以使用下面的方式进行绘制.(其实这一部分的内容是和上面介绍设置图像颜色, 图像风格是重复的, 在这里再简单说明一下)

x = np.arange(3)*1.2

y = [4, 9, 2]

z = [1, 2, 3]

k = [11, 12, 13]

ax = plt.subplot(111)

w=0.3

# 绘制多个bar在同一个图中, 这里需要控制width

plt.bar(x-w, y, width=w, color='#e0109c', align='center')

plt.bar(x, z, width=w, color='#1b71f1', align='center')

plt.bar(x+w, k, width=w, color='#9eed3b', align='center')

ax.set_xticks(x) # 设置xticks出现的位置

ax.set_xticklabels(['1','2','3'], rotation='vertical', fontsize = 'xx-large')

ax.autoscale(tight=True)

plt.show()

绘制的结果如下:

20190704_204346_1cgnhdp.jpg

那么这个图什么时候可以用到呢,就是我们可以展示同一类的TP, FP, FN这些指标。如下图所示(下面是使用NSL-KDD做的实验的结果).

20190704_205325_2ywaped.jpg

参考链接 : Python matplotlib multiple bars

饼图的绘制

基础饼图的绘制

我们只需要给定饼图中每一块的大小,每一块的 label,每一块是否要突出,即可绘制出一个最基础的饼图。

# Pie chart, where the slices will be ordered and plotted counter-clockwise:

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'

sizes = [15, 30, 45, 10]

explode = (0, 0.1, 0, 0)  # only "explode" the 2nd slice (i.e. 'Hogs')

fig1, ax1 = plt.subplots()

ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',

shadow=True, startangle=90)

ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.

plt.show()

绘制的效果最终如下所示:

20201113_162104_2hmltb5.jpg

对饼图进行 Label

下面代码只需要修改 data,title,和 recipe 即可,后面的都可以不进行修改。

fig, ax = plt.subplots(figsize=(7, 5), subplot_kw=dict(aspect="equal"))

y1 = [135, 148, 166]

y3 = [73, 95, 93]

y4 = [85, 99, 82]

y5 = [114, 121, 122]

y6 = [105, 107, 100]

data = [np.sum(i) for i in [y1, y2, y3, y4, y5, y6]]

title = ["开设职业生涯规划课程",

"举办职业规划讲座",

"在学校开通职业规划评价系统",

"在学校设立专门的职业指导中心",

"创建丰富多彩的职业体验课程",

"加强教师和家长的指导"]

recipe = ['{} {:<3.2f} %'.format(i,j/np.sum(data)*100) for i,j in zip(title, data)] # 设置标题

# 下面的不需要修改

wedges, texts = ax.pie(data, wedgeprops=dict(width=0.4), startangle=-40)

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)

kw = dict(arrowprops=dict(arrowstyle="-"),

bbox=bbox_props, zorder=0, va="center")

for i, p in enumerate(wedges):

ang = (p.theta2 - p.theta1)/2. + p.theta1

y = np.sin(np.deg2rad(ang))

x = np.cos(np.deg2rad(ang))

horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]

connectionstyle = "angle,angleA=0,angleB={}".format(ang)

kw["arrowprops"].update({"connectionstyle": connectionstyle})

ax.annotate(recipe[i], xy=(x, y), xytext=(1.35*np.sign(x), 1.4*y),

horizontalalignment=horizontalalignment, **kw)

ax.set_title(u"您认为学校开展职业生涯规划教育的措施有哪些", fontsize=25, y=1.2)

plt.show()

最终生成的效果如下所示:

20201113_163136_bias6sx.jpg

直方图

直方图X轴一般是统计的样本,而Y轴一般是样本对应的统计度量。

为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。在 matplotlib 中可以使用Axes.hist方法绘制直方图。

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

data = np.random.normal(0,20,1000) # 在0-20之间产生1000个随机数

bins = np.arange(-100,100,5) # 产生区间刻度

ax.hist(data,bins=bins)

fig.show()

snipaste_20180309_144305.png

散点图

散点图,将所有的数据值在图形中绘制成点,这样有多少数据值在图形中就会有多少个点。通过这些数据点可以看出数据值的分布模式,比如是否有聚类模式,或者相关关系或者发现离群点。在 matplotlib 中可以通过Axes.scatter绘制散点图。

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

x = np.arange(1,100,1)

y = x**2+100*x*np.random.random(len(x))

ax.scatter(x,y)

fig.show()

snipaste_20180309_144804.png

散点图的美化

一些比较规整的,类似于表格的数据,也是可以使用散点图进行绘制。我们首先生成样例数据,这里是生成每一年,每一个年龄段的人口的数据。也就是1年,如果年龄段是0-80,也就是一年会有80组数据。

data = []

years = [str(i) for i in list(range(1990, 2020, 1))] # 所有的年份

ages = [str(i) for i in list(range(0, 81, 5))] # 所有的年龄段

populations = [10000*i for i in list(range(0, 81, 5))] # 每个年龄段的人口

for year_index, year in enumerate(years):

for age_index, age in enumerate(ages):

data.append([year, age, (1+0.1*year_index)*populations[age_index]])

plot_data = pd.DataFrame(data, columns=['year', 'age', 'population'])

plot_data.head()

生成的数据如下所示:

20201031_162856_3gtckw5.jpg

我们使用散点图对上面的数据进行可视化:

plt.rcParams['figure.figsize'] = (18, 8)

plt.scatter(

x=plot_data['year'],

y=plot_data['age'],

c=plot_data['population'],

s=plot_data['population']*0.0005,

ec='tab:gray',

cmap=plt.cm.RdBu_r,

alpha=0.8)

ax = plt.gca()

# 坐标轴控制

ax.set_xticks([years[i] for i in range(0, len(years), int(len(years)/5))])

ax.set_yticks([ages[i] for i in range(0, len(ages), int(len(ages)/5))])

# 不显示左侧和底部纵坐标轴

ax.spines['left'].set_visible(False)

ax.spines['bottom'].set_visible(False)

# 显示 y 轴网格线

ax.grid(b=False, axis='y', lw=1)

plt.ylabel('Mean Age')

最终的效果如下所示:

20201031_163047_chdy4r3.jpg

高阶散点图-指定不同类别使用不同颜色

如果散点图中有不同的类别, 同时希望可以对不同类别使用不同的颜色, 并使用图例标注出来, 我们需要依序进行绘制.

以下是一个完整的例子, 详细说明可以查看链接: matplotlib绘图优化-散点图绘制图例

cmap = plt.get_cmap('rainbow', 12) # 数字与颜色的转换

scatter_x = np.array([1,2,3,4,5])

scatter_y = np.array([5,4,3,2,1])

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

cdict = {1: '111', 2: '222', 3: '333'}

fig, ax = plt.subplots()

for key in cdict.keys():

ix = np.where(group == key)

ax.scatter(scatter_x[ix], scatter_y[ix], color = cmap(key), label = key, s = 100) # 注意这里color的指定

ax.legend()

plt.show()

最终的结果如下所示:

20200630_190033_ctqwxpg.jpg

除了可以控制颜色的不同以外, 我们还可以控制形状的不同, 可以通过简单设置marker来达到效果, 下面有12种不同的marker:

markers = ["8","s","p","P","*","h","H","+","x","X","D","d"]

绘制多边形(区间的绘制)

我们可以使用plt.fill进行多边形的绘制,我们先看一个简单的例子:

# 绘制一个多边形的区域

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

test_y = np.array([4,1,2])

fig, axes = plt.subplots(nrows=1, ncols=1,figsize=(13,7))

axes.fill(test_x,test_y)

20190316_133727_k7nk48c.jpg

我们可以使用这个方法来绘制一个区间的效果;

# 绘制一个多边形的区域

test_x = np.linspace(0.1, 9.9, 200)

test_y = np.sin(test_x)

fig, axes = plt.subplots(nrows=1, ncols=1,figsize=(13,7))

axes.plot(test_x,test_y,c='r')

axes.fill(np.concatenate([test_x,test_x[::-1]]),np.concatenate([test_y + 1, test_y - 1]))

20190316_134321_j18oauh.jpg

箱线图

箱线图可以看出数据的分散程度,异常值等信息,箱线图根据一组数据的以下 5 个统计值进行绘制:

最小值;

第1四分位数;

中位数;

第3四分位数;

最大值;

在 matplotlib 中可以使用Axes.boxplot方法绘制箱线图

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

# 产生 50 个小于 100 的随机数

spread = np.random.rand(50) * 100

# 产生 25 个值为 50 的数据

center = np.ones(25) * 50

# 异常值

outlier_high = np.random.rand(10) * 100 + 100

outlier_low = np.random.rand(10) * -100

data = np.concatenate((spread, center, outlier_high, outlier_low), 0)

ax.boxplot(data)

fig.show()

上面的代码中,我们特意创建了 data 数据,可以推断出该数据的中位数是 50,还有一些其他异常值,绘制的图形如下:

snipaste_20180309_145249.png

绘制动态图

除了能绘制上面的静态图像,我们还可以绘制动态图像,下面我们来举一个小例子来说明matplotlib如何绘制动态图像。

动态图主要是通过animation模块实现。具体就是matplotlib.animation.FuncAnimation(fig, func)。其中fig代表所绘制的图像。而func可以看作是更新函数,它刷新每一帧的值。

import numpy as np

import matplotlib.pyplot as plt

import matplotlib.animation as animation

fig = plt.figure()

ax = fig.add_subplot(1,1,1)

x = np.arange(0,2*np.pi,0.01)

line, = plt.plot(x,np.sin(x))

# 更新函数

def update(i):

line.set_ydata(np.sin(x+i/10))

return line

animation = animation.FuncAnimation(fig,update,interval=20)

plt.show()

上面的interval表示更新频率,以ms计。(说实话,制作动画还是喜欢使用Mathematica来进行制作)

看一下上面的绘制出的效果

snipaste_20180309_161355.gif

绘制三维图像

最后,我们来说一下三维图像的绘制。

绘制三维散点图

import numpy as np

# 导入2d,3d的绘图模块

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

# x, y, z 均为 0 到 1 之间的 100 个随机数

x = np.random.normal(0, 1, 100)

y = np.random.normal(0, 1, 100)

z = np.random.normal(0, 1, 100)

fig = plt.figure()

ax = Axes3D(fig)

ax.scatter(x,y,z)

plt.show()

snipaste_20180309_165915.png

绘制三维线形图

# 载入模块

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

import numpy as np

# 生成数据

x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)

y = np.sin(x)

z = np.cos(x)

# 创建 3D 图形对象

fig = plt.figure()

ax = Axes3D(fig)

# 绘制线型图

ax.plot(x, y, z)

# 显示图

plt.show()

snipaste_20180309_170029.png

绘制三维曲面图

# 载入模块

import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

# 创建 3D 图形对象

fig = plt.figure()

ax = Axes3D(fig)

# 生成数据

X = np.arange(-2, 2, 0.1)

Y = np.arange(-2, 2, 0.1)

X, Y = np.meshgrid(X, Y) #注意这一步

Z = np.sqrt(X ** 2 + Y ** 2)

# 绘制曲面图,并使用 cmap 着色

ax.plot_surface(X, Y, Z, cmap=plt.cm.winter)

plt.show()

这个上面的meshgrid是用来生成底部的网格的,我们可以看一下x,y是什么

snipaste_20180309_170629.png

运行上面的代码,于是我们可以得到下面的图像

snipaste_20180309_170201.png

子图的绘制

之前绘制二维图像的时候我们是通过.add_subplot()来绘制子图的,其实在三维的时候也是一样的,只是注意 3D 绘图时要添加 projection='3d' 参数,下面我们看一个具体的例子。

# -*- coding: utf-8 -*

# 载入模块

from mpl_toolkits.mplot3d import Axes3D

import matplotlib.pyplot as plt

import numpy as np

# 创建 1 张画布

fig = plt.figure()

#===============

# 向画布添加子图 1

ax1 = fig.add_subplot(1, 2, 1, projection='3d')

# 生成子图 1 数据

x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)

y = np.sin(x)

z = np.cos(x)

# 绘制第 1 张图

ax1.plot(x, y, z)

#===============

# 向画布添加子图 2

ax2 = fig.add_subplot(1, 2, 2, projection='3d')

# 生成子图 2 数据

X = np.arange(-2, 2, 0.1)

Y = np.arange(-2, 2, 0.1)

X, Y = np.meshgrid(X, Y)

Z = np.sqrt(X ** 2 + Y ** 2)

# 绘制第 2 张图

ax2.plot_surface(X, Y, Z, cmap=plt.cm.winter)

# 显示图

plt.show()

snipaste_20180309_170950.png

上面就是matplotlib的一些常用的用法了,记录在此也方便自己的查阅。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值