Python-Matplotlib可视化(3)——自定义样式绘制精美统计图

232 阅读9分钟

matplotlib提供了填充图案用于填充平面。这些填充图案,对于仅包含黑白两色的图形中具有重要作用。

import numpy as np

import matplotlib.pyplot as plt

n = 10

a = np.random.random(n)

b = np.random.random(n)

x = np.arange(n)

plt.bar(x, a, color='w', hatch='x', edgecolor='black')

plt.bar(x, a+b, bottom=a, color='w', edgecolor='black', hatch='/')

plt.show()

控制填充样式

具有填充呈现性的函数(如pyplot.bar())接受可选参数hatch控制填充样式,此参数的可选值包括:"/", "\", "|", "-", "+", "x", "o", "O","."和"*",每个值对应于不同的填充图案;edgecolor参数可用于控制图案填充的颜色。

控制标记样式


《详解常见统计图的绘制》中,我们已经了解了如何如何绘制曲线,并明白了曲线是由点之间的连线构成的;此外,散点图表示数据集中的每个点。而matplotlib提供了多种形状,可以用其他类型的标记替换点的样式。

标记的指定方式包括以下几种:

  1. 预定义标记:预定义的形状,表示为[0, 8]范围内的整数或某些预定义的字符串。

  2. 顶点列表:值对列表,用作形状路径的坐标。

  3. 正多边形:表示N边正多边形的三元组(N, 0, angle),其中angle为旋转角度。

  4. 星形多边形:它表示为三元组(N, 1, angle),代表N边正星形,其中angle为旋转角度。

import numpy as np

import matplotlib.pyplot as plt

a = np.random.standard_normal((100, 2))

a += np.array((-1, -1))

b = np.random.standard_normal((100, 2))

b += np.array((1, 1))

plt.scatter(a[:,0], a[:,1], color = 'm', marker = 'x')

plt.scatter(b[:,0], b[:,1], color = 'c', marker = '^')

plt.show()

控制标记样式使用marker参数,可以为每个数据集合集合指定不同的标记。

我们已经在中学习了如何在散点图中为每个点定义不同的颜色,如果我们需要为每个点定义不同样式该怎么办呢?问题在于,与color参数不同,marker参数不接受标记样式列表作为输入。因此,我们不能实现plt.scatter()的单次调来显示具有不同标记的多个点集。解决方案是,将每种类型的数据点分隔置不同集合中,并为每个集合单独调用pyplot.scatter()调用:

import numpy as np

import matplotlib.pyplot as plt

label_list = (

b'Iris-setosa',

b'Iris-versicolor',

b'Iris-virginica',

)

colors = ['c','y','m']

def read_label(label):

return label_list.index(label)

data = np.loadtxt('iris.data', delimiter = ',', converters = { 4 : read_label })

marker_set = ('^', 'x', '.')

for i, marker in enumerate(marker_set):

data_subset = np.asarray([x for x in data if x[4] == i])

plt.scatter(data_subset[:,0], data_subset[:,1], color = colors[i], marker = marker)

plt.show()

控制标记样式对于pyplot.plot(),也可以使用相同的标记参数访问标记样式。当数据点密集时,每个点都使用标记进行显示将会导致图片混乱,因此matplotlib提供了markevery参数,允许每隔N个点显示一个标记:

import numpy as np

import matplotlib.pyplot as plt

x = np.linspace(-6, 6, 1024)

y_1 = np.sinc(x)

y_2 = np.sinc(x) + 1

plt.plot(x, y_1, marker = 'x', color = '.75')

plt.plot(x, y_2, marker = 'o', color = 'k', markevery = 64)

plt.show()

控制标记样式

控制标记大小


标记的大小可选参数s进行控制:

import numpy as np

import matplotlib.pyplot as plt

a = np.random.standard_normal((100, 2))

a += np.array((-1, -1))

b = np.random.standard_normal((100, 2))

b += np.array((1, 1))

plt.scatter(a[:,0], a[:,1], c = 'm', s = 100.)

plt.scatter(b[:,0], b[:,1], c = 'c', s = 25.)

plt.show()

控制标记大小Tips:标记的大小由plt.scatter()的参数s设置,但应注意它设置的是标记的表面积倍率而非半径。

plt.scatter()函数还可以接受列表作为s参数的输入,其表示每个点对应一个大小:

import numpy as np

import matplotlib.pyplot as plt

m = np.random.standard_normal((1000, 2))

r_list = np.sum(m ** 2, axis = 1)

plt.scatter(m[:, 0], m[:, 1], c = 'w', edgecolor='c', marker = 'o', s = 32. * r_list)

plt.show()

控制标记大小Tips:plt.plot()函数允许在markersize(或简写为ms)参数的帮助下更改标记的大小,但是此参数不接受列表作为输入。

创建自定义标记


虽然matplotlib提供了多种标记形状。但是在某些情况下我们可能仍然找不到适合具体需求的形状。例如,我们可能希望使用公司徽标等作为形状。

在matplotlib中,将形状描述为一条路径——一系列点的连接。因此,如果要定义我们自己的标记形状,必须提供一系列的点:

import numpy as np

import matplotlib.path as mpath

from matplotlib import pyplot as plt

shape_description = [

( 1., 2., mpath.Path.MOVETO),

( 1., 1., mpath.Path.LINETO),

( 2., 1., mpath.Path.LINETO),

( 2., -1., mpath.Path.LINETO),

( 1., -1., mpath.Path.LINETO),

( 1., -2., mpath.Path.LINETO),

(-1., -2., mpath.Path.LINETO),

(-1., -1., mpath.Path.LINETO),

(-2., -1., mpath.Path.LINETO),

(-2., 1., mpath.Path.LINETO),

(-1., 1., mpath.Path.LINETO),

(-1., 2., mpath.Path.LINETO),

( 0., 0., mpath.Path.CLOSEPOLY),

]

u, v, codes = zip(*shape_description)

my_marker = mpath.Path(np.asarray((u, v)).T, codes)

data = np.random.rand(8, 8)

plt.scatter(data[:,0], data[:, 1], c = 'm', marker = my_marker, s = 75)

plt.show()

创建自定义标识Tips:所有带有标记的图形的pyplot函数都有一个可选参数marker,其参数值可以是预定义的matplotlib标记,也可以是自定义的路径实例,路径对象在matplotlib.path模块中定义。

Path对象的构造函数将坐标列表和指令列表作为输入;每个坐标一条指令,使用一个列表将坐标和指令融合在一起,然后将坐标列表和指令传递给路径构造函数,如下所示:

u, v, codes = zip(*shape_description)

my_marker = mpath.Path(np.asarray((u, v)).T, codes)

形状是通过光标的移动来描述的:

  • MOVETO:此指令将光标移动到指定的坐标,并不画线。

  • LINETO:这将在光标当前点和目标点之间绘制直线,并将光标移动至目标点。

  • CLOSEPOLY:此指令仅用于关闭路径,每个形状都以这条指示结束。

理论上,任何形状都是可能的,我们只需要描述它的路径。单在实践中,如果想使用复杂的形状,最好可以提前进行转换工作。

总结——对标记进行更精细控制


通过上述介绍,我们可以对标记进行精细控制,如边缘颜色、内部颜色等。

import numpy as np

import matplotlib.pyplot as plt

x = np.linspace(-6, 6, 1024)

y = np.sinc(x)

plt.plot(x, y,

linewidth = 3.,

color = 'm',

markersize = 9,

markeredgewidth = 1.5,

markerfacecolor = 'y',

markeredgecolor = 'c',

marker = 'o',

markevery = 64)

plt.show()

精确控制图形属性Tips:markeredgecolor、markerfacecolor和markeredgewidth参数分别用于控制标记的边颜色、内部颜色和线宽。所有可以使用标记的函数(如plt.plot())都接受这些可选参数。

系列链接


Python-Matplotlib可视化(1)——一文详解常见统计图的绘制

Python-Matplotlib可视化(2)——自定义颜色绘制精美统计图

Python-Matplotlib可视化(4)——添加注释让统计图通俗易懂

Python-Matplotlib可视化(5)——添加自定义形状绘制复杂图形

Python-Matplotlib可视化(6)——自定义坐标轴让统计图清晰易懂

做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。

别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。

我先来介绍一下这些东西怎么用,文末抱走。


(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

(4)200多本电子书

这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。

基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

(5)Python知识点汇总

知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。

在这里插入图片描述

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

了解详情:docs.qq.com/doc/DSnl3ZG…