第二回:艺术画笔见乾坤
import numpy as np
import pandas as pd
import re
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Circle, Wedge
from matplotlib.collections import PatchCollection
概述
matplotlib 的三层api
matplotlib
的原理:使用Artist对象在画布cnvas
上绘制Render
图形-
类似于人画画:
- 1.准备一块画布
- 2.准备好颜料、画笔等制图工具
- 3.作画
-
因此matplotlib有三个层次的API:
matplotlib.backend_bases.FigureCanvas
代表“画纸”matplotlib.backend_bases.Renderer
代表了渲染器,可以近似理解为画笔matplotlib.artist.Artist
代表了具体的图表组件,即调用了Renderer的接口在Canvas上作图前两者处理程序和计算机的底层交互的事项,第三项Artist就是具体的调用接口来做出我们想要的图,比如图形、文本、线条的设定。所以通常来说,我们95%的时间,都是用来和matplotlib.artist.Artist类打交道的。
-
Artist的分类
Artist有两种类型:primitive
和containers
-
primitive
是基本要素,包含作图是用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等 -
containers
是容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis。
基本元素 - primitives
本章重点介绍下 primitives 的几种类型:曲线-Line2D,矩形-Rectangle,多边形-Polygon,图像-image
2DLines
曲线的绘制主要通过类 matplotlib.lines.Line2D
来完成的。
matplotlib中线-line
的含义:它表示的可以是连接所有顶点的实线样式,也可以是每个顶点的标记。此外,这条线也会受到绘画风格的影响,比如,我们可以创建虚线种类的线。
其中常用的的参数有:
- xdata:需要绘制的line中点的在x轴上的取值,若忽略,则默认为range(1,len(ydata)+1)
- ydata:需要绘制的line中点的在y轴上的取值
- linewidth:线条的宽度
- linestyle:线型
- color:线条的颜色
- marker:点的标记,详细可参考markers API
- markersize:标记的size
a. 设置Line2D的属性:
1) 直接在plot()函数中设置
2) 通过获得线对象,对线对象进行设置
3) 获得线属性,使用setp()函数设置
'''直接在plot()函数中设置'''
x = range(0, 5)
y = [2, 4, 5, 1, 7]
plt.plot(x, y, linewidth=8) #设置线的粗细参数为10
[<matplotlib.lines.Line2D at 0x1f86c21f100>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jQwNuAMq-1653051997871)(output_6_1.png)]
'''通过获得线对象,对线对象进行设置'''
x = range(0, 5)
y = [2, 4, 5, 1, 7]
line, = plt.plot(x, y, '-')# 这里等号坐标的line,是一个列表解包的操作,目的是获
line.set_antialiased(False); # 关闭抗锯齿功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qiVGiISD-1653051997873)(output_7_0.png)]
'''3.获得线属性,使用sept()函数设置'''
x = range(0, 5)
y = [2, 4, 5, 1, 7]
lines = plt.plot(x, y)
plt.setp(lines, color='r', linewidth=14)
[None, None]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyENTCWF-1653051997873)(output_8_1.png)]
b. 如何绘制lines
1) 绘制直线line
2) errorbar绘制误差折线图
介绍两种绘制直线line常用的方法:
1)plot方法绘制
2)Line2D对象绘制
'''1.plot方法绘制'''
x = range(0, 5)
y1 = [2, 5, 7, 12, 23]
y2 = [3, 6, 9, 17, 34]
fig, ax = plt.subplots()
ax.plot(x, y1)
ax.plot(x, y2)
print(ax.lines) # 通过直接使用辅助方法画线,打印ax.lines后可以看到在matplotlib
<Axes.ArtistList of 2 lines>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2wYxHnER-1653051997874)(output_10_1.png)]
'''2.Line2D对象绘制'''
x = range(0,5)
y1 = [2, 5, 7, 12, 23]
y2 = [3, 6, 9, 17, 34]
fig, ax = plt.subplots()
lines = [Line2D(x, y1), Line2D(x, y2, color='orange')] # 显式创建Line2D对象
for line in lines:
ax.add_line(line) # 使用add_line方法将创建的Line2D添加到子图中
ax.set_xlim(0, 4)
ax.set_ylim(2, 11)
(2.0, 11.0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wXjt1MC3-1653051997874)(output_11_1.png)]
C. errorbar绘制误差折线图
pyplot里有个专门绘制误差线的的功能,通过errobar
len实现,构造函数如下
matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)
主要参数有:
x:需要绘制的line中点的在x轴上的取值 y:需要绘制的line中点的在y轴上的取值 yerr:指定y轴水平的误差 xerr:指定x轴水平的误差 fmt:指定折线图中某个点的颜色,形状,线条风格,例如‘co--’ ecolor:指定error bar的颜色 elinewidth:指定error bar的线条宽度
绘制errorbar
flg = plt.figure()
x = np.arange(10)
y = 2.5 * np.sin(x / 20 * np.pi)
yerr = np.linspace(0.05, 0.2, 10)
plt.errorbar(x, y+3, yerr=yerr, ecolor='red', label='both limits (default)')
<ErrorbarContainer object of 3 artists>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IG4sGc6E-1653051997875)(output_13_1.png)]
patches
- matplotlib.patches.Patch类是二维图形类,并且是众多二维图形的父类
- 本节重点讲述三种最常见的子类,矩形,多边形和楔型。
a. Rectangle-矩形
Rectangle
矩形类在官网中的构造函数class matplotlib.patches.Rectangle(xy, width, height, angle=0.0, **kwargs)
其中xy控制锚点,width和height分别控制宽和高
在实际中最常见的矩形图`hist直方图`和`bar条形图`
- hist-直方图
常用参数:
- x: 数据集,最终的直方图将对数据集进行统计
- bins: 统计的区间分布
- range: tuple, 显示的区间,range在没有给出bins时生效
- density: bool,默认为false,显示的是频数统计结果,为True则显示频率统计结果,这里需要注意,频率统计结果=区间数目/(总数*区间宽度),和normed效果一致,官方推荐使用density
- histtype: 可选{‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’}之一,默认为bar,推荐使用默认配置,step使用的是梯状,* stepfilled则会对梯状内部进行填充,效果与bar类似
- align: 可选{‘left’, ‘mid’, ‘right’}之一,默认为’mid’,控制柱状图的水平分布,left或者right,会有部分空白区域,推荐使用默认
- log: bool,默认False,即y坐标轴是否选择指数刻度
- stacked: bool,默认为False,是否为堆积状图
x = np.random.randint(0, 100, 100) # 生成(0-100)之间的100个数据,即数据集
bins = np.arange(0,101, 10) # 设置连续的边界值,即直方图的分布区间[0, 10), [10,20)...
plt.hist(x, bins, color='green', alpha=0.5) # alpha设置透明度, 0为完全透明
plt.xlabel('scores')
plt.ylabel('count')
plt.xlim(0, 100) # 设置x轴分布范围plt.show()
(0.0, 100.0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rG087T24-1653051997875)(output_18_1.png)]
Rectangle
矩形类绘制直方图
df = pd.DataFrame(columns=['data'])
df.loc[:,'data'] = x
df['fenzu'] = pd.cut(df['data'], bins=bins, right = False, include_lowest=True)
df_cnt = df['fenzu'].value_counts().reset_index()
df_cnt.loc[:, 'mini'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\[(.*)\,', x)[0]).astype(int)
df_cnt.loc[:, 'maxi'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\,(.*)\)', x)[0]).astype(int)
df_cnt.loc[:, 'width'] = df_cnt['maxi'] - df_cnt['mini']
df_cnt.sort_values('mini', ascending = True, inplace = True)
df_cnt.reset_index(inplace = True, drop = True)
# 用Rectangle把hist绘制出来
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in df_cnt.index:
rect = plt.Rectangle((df_cnt.loc[i, 'mini'], 0), df_cnt.loc[i, 'width'], df_cnt.loc[i, 'fenzu'])
ax1.add_patch(rect)
ax1.set_xlim(0, 100)
ax1.set_ylim(0, 16)
(0.0, 16.0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KgiSnZhb-1653051997875)(output_20_1.png)]
- bar-柱状图
matplotlib.pyplot.bar(left, height, alpha=1, width=0.8, color=, edgecolor=, label=, lw=3)
常用参数:-
left:x轴的位置序列,一般采用range函数产生一个序列,但是有时候可以是字符串
-
height:y轴的数值序列,也就是柱形图的高度,一般就是我们需要展示的数据;
-
alpha:透明度,值越小越透明
-
width:为柱形图的宽度,一般这是为0.8即可;
-
color或facecolor:柱形图填充的颜色;
-
edgecolor:图形边缘颜色
-
label:解释每个图像代表的含义,这个参数是为legend()函数做铺垫的,表示该次bar的标签
有两种绘图柱状图的方式
-
-
bar绘制柱状图
-
Rectangle
矩形类绘制柱状图
'''1. bar绘制柱状图'''
y = range(1, 17)
plt.bar(np.arange(16), y, alpha=0.5, color='green', edgecolor='red', label='The First Bar', lw=3)
<BarContainer object of 16 artists>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tkvdOPJ3-1653051997875)(output_22_1.png)]
'''Rectangle矩形类绘制柱状图'''
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in range(1, 17):
rect = plt.Rectangle((i + 0.25, 0), 0.5, i)
ax1.add_patch(rect)
ax1.set_xlim(0, 19)
ax1.set_ylim(0, 19)
(0.0, 19.0)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hn1nP6dI-1653051997876)(output_23_1.png)]
b. Polygon-多边形
matplotlib.patches.Polygon类是多边形类。构造函数
`class matplotlib.patches.Polygon(xy, closed=True, **kwargs)`
xy是一个N×2的numpy array,为多边形的顶点。
closed为True则指定多边形将起点和终点重合从而显式关闭多边形。
matplotlib.patches.Polygon类中常用的是fill类,它是基于xy绘制一个填充的多边形,它的定义:
matplotlib.pyplot.fill(*args, data=None, **kwargs)
参数说明:关于x、y和color的序列,其中color是可选的参数,每个多边形都是由其节点的x和y位置列表定义的,后面可以选择一个颜色说明符。您可以通过提供多个x、y、[颜色]组来绘制多个多边形。
# 用fill来绘制图形
x = np.linspace(0, 5 * np.pi, 1000)
y1 = np.cos(x)
y2 = np.sin(x)
plt.fill(x, y1, color = 'g', alpha = 0.3)
[<matplotlib.patches.Polygon at 0x1cf3c700040>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fnVY5uqD-1653051997876)(output_25_1.png)]
c. Wedge-契形
matplotlib.patches.Polygon类是多边形类。其基类是matplotlib.patches.Patch,它的构造函数:
`class matplotlib.patches.Wedge(center, r, theta1, theta2, width=None, **kwargs)`
一个Wedge-契形 是以坐标x,y为中心,半径为r,从θ1扫到θ2(单位是度)。如果宽度给定,则从内半径r -宽度到外半径r画出部分楔形。wedge中比较常见的是绘制饼状图。
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=0, 0, frame=False, rotatelabels=False, *, normalize=None, data=None)
最主要的参数是前4个:
* x:契型的形状,一维数组。
* explode:如果不是等于None,则是一个len(x)数组,它指定用于偏移每个楔形块的半径的分数。
* labels:用于指定每个契型块的标记,取值是列表或为None。
* colors:饼图循环使用的颜色序列。如果取值为None,将使用当前活动循环中的颜色。
* startangle:饼状图开始的绘制的角度
'''绘制饼状图'''
labels = 'snakes', 'Cats', 'Sheeps', 'tiger'
sizes = [20, 30, 20, 30]
explode = (0, 0.1, 0, 0)
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.
(-1.198558317750227,
1.1176566215608759,
-1.1617174732534195,
1.1029389582539775)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLQWFnVR-1653051997876)(output_27_1.png)]
wedge绘制饼图
fig = plt.figure(figsize=(5, 5))
ax1 = fig.add_subplot(111)
theta1 = 0
sizes = [34, 53, 12, 1]
patches = []
patches += [
Wedge((0.5, 0.5), .4, 0, 54),
Wedge((0.5, 0.5), .4, 54, 162),
Wedge((0.5, 0.5), .4, 162, 324),
Wedge((0.5, 0.5), .4, 324, 360),
]
colors = 100 * np.random.rand(len(patches))
p = PatchCollection(patches, alpha=0.8)
p.set_array(colors)
ax1.add_collection(p)
<matplotlib.collections.PatchCollection at 0x1cf3fdb6f70>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wOclJJqE-1653051997877)(output_29_1.png)]
collections
collections类是用来绘制一组对象的集合,collections有许多不同的子类,如RegularPolyCollection, CircleCollection, Pathcollection, 分别对应不同的集合子类型。其中比较常用的就是散点图,它是属于PathCollection子类,scatter方法提供了该类的封装,根据x与y绘制不同大小或颜色标记的散点图。 它的构造方法:
`Axes.scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=, edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)`
最主要的参数:
* x:数据点x轴的位置
* y:数据点y轴的位置
* s:尺寸大小
* c:可以是单个颜色格式的字符串,也可以是一系列颜色
* marker: 标记的类型
# 用scatter绘制散点图
x = [0,2, 4, 6, 8, 10]
y = [10]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x, y, s=s)
<matplotlib.collections.PathCollection at 0x1cf3eff5fa0>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVnWRCX0-1653051997877)(output_31_1.png)]
images
images是matplotlib中绘制image图像的类,其中最常用的imshow可以根据数组绘制成图像,它的构造函数:
class matplotlib.image.AxesImage(ax, cmap=None, norm=None, interpolation=None, origin=None, extent=None, filternorm=True, filterrad=4.0, resample=False, **kwargs)
imshow根据数组绘制图像
matplotlib.pyplot.imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=, filternorm=1, filterrad=4.0, imlim=, resample=None, url=None, *, data=None, **kwargs)
使用imshow画图时首先需要传入一个数组,数组对应的是空间内的像素位置和像素点的值,interpolation参数可以设置不同的差值方法,具体效果如下。
methods = [None, 'none', 'nearest','bilinear', 'bicubic', 'spline16', 'spline36', 'hanning',
'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel',
'mitchell', 'sinc', 'lanczos']
grid = np.random.rand(4, 4)
fig, axs = plt.subplots(nrows=3, ncols=6, figsize=(9, 6),
subplot_kw={'xticks': [], 'yticks': []})
for ax, interp_method in zip(axs.flat, methods):
ax.imshow(grid, interpolation = interp_method, cmap='viridis')
ax.set_title(str(interp_method))
plt.tight_layout()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xKMv9u69-1653051997877)(output_33_0.png)]
对象容器 - Object container
容器会包含一些primitives,并且容器还有它自身的属性。
比如Axes Artist,它是一种容器,它包含了很多primitives,比如Line2D,Text;同时,它也有自身的属性,比如xscal,用来控制X轴是linear还是log的。
Figure容器
matplotlib.figure.Figures是Artist最顶层的container-对象容器,它包含了图表中的所有元素。一张图表的背景就是在Figure.patch的一个矩形Rectangle。
当我们向图表添加Figure.add_subplot()或者Figure.add_axes()元素时,这些都会被添加到Figure.axes列表中。
fig = plt.figure()
ax1 = fig.add_subplot(211) #做一幅2*1 的图,选择第一个子图
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
print(ax1)
print(fig.axes)
AxesSubplot(0.125,0.536818;0.775x0.343182)
[<AxesSubplot:>, <Axes:>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ohzshNsW-1653051997877)(output_36_1.png)]
由于Figure维持了current axes,因此你不应该手动的从Figure.axes列表中添加删除元素,而是要通过Figure.add_subplot()、Figure.add_axes()来添加元素,通过Figure.delaxes()来删除元素。但是你可以迭代或者访问Figure.axes中的Axes,然后修改这个Axes的属性
比如下面的遍历axes里的内容,并添加网格线
fig = plt.figure()
ax1 = fig.add_subplot(211)
for ax in fig.axes:
ax.grid(True)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ariWlyNp-1653051997877)(output_38_0.png)]
Figure 也有它自己的 text、line。、patch、 image ,可以直接通过add perimitive
语句直接添加
但是注意Figure默认的坐标系是以像素为单位,你可能需要转换成figure坐标系:(0,0)表示左下点,(1,1)表示右上点。
Figure容器的常见属性:
Figure.patch属性:Figure的背景矩形
Figure.axes属性:一个Axes实例的列表(包括Subplot)
Figure.images属性:一个FigureImages patch列表
Figure.lines属性:一个Line2D实例的列表(很少使用)
Figure.legends属性:一个Figure Legend实例列表(不同于Axes.legends)
Figure.texts属性:一个Figure Text实例列表
Axes容器
atplotlib.axes.Axes
matplotlib的核心。大量的用于绘图的Artist存放在它内部,并且它有许多辅助方法来创建和添加Artist给它自己,而且它也有许多赋值方法来访问和修改这些Artist
和Figure容器类似,Axes包含了一个patch属性,对于笛卡尔坐标系而言,它是一个Rectangle;对于极坐标而言,它是一个Circle。这个patch属性决定了绘图区域的形状、背景和边框。
fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch # axes的patch是一个Rectangle实例
rect.set_facecolor('green')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GPtqFVPM-1653051997878)(output_41_0.png)]
Axes有许多方法用于绘图,如.plot()、.text()、.hist()、.imshow()等方法用于创建大多数常见的primitive(如Line2D,Rectangle,Text,Image等等)
Axes容器的常见属性有:
artists: Artist实例列表
patch: Axes所在的矩形实例
collections: Collection实例
images: Axes图像
legends: Legend 实例
lines: Line2D 实例
patches: Patch 实例
texts: Text 实例
xaxis: matplotlib.axis.XAxis 实例
yaxis: matplotlib.axis.YAxis 实例
Axis容器
matplotlib.axis.Axis
实例处理tick line、grid line、tick label以及axis label的绘制,它包括坐标轴上的刻度线、刻度label、坐标网格、坐标轴标题。通常你可以独立的配置y轴的左边刻度以及右边的刻度,也可以独立地配置x轴的上边刻度以及下边的刻度。
刻度包括主刻度和次刻度,它们都是Tick刻度对象。
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
fig, ax = plt.subplots()
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x, y, '-')
axis = ax.xaxis # axis为X轴对象
axis.get_ticklocs() # 获取刻度线位置
axis.get_ticklabels() # 获取刻度label列表(一个Text实例的列表)。 可以通过minor=True|False关键字参数控制输出minor还是major的tick label。
axis.get_ticklines() # 获取刻度线列表(一个Line2D实例的列表)。 可以通过minor=True|False关键字参数控制输出minor还是major的tick line。
axis.get_data_interval()# 获取轴刻度间隔
axis.get_view_interval()# 获取轴视角(位置)的间隔
array([-0.2, 4.2])
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z7x6wx0W-1653051997878)(output_44_1.png)]
'''调整一些轴和刻度的属性'''
fig = plt.figure() # 创建一个新图表
rect = fig.patch # 矩形实例并将其设为黄色
rect.set_facecolor('lightgoldenrodyellow')
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4]) # 创一个axes对象,从(0.1,0.3)的位置开始,宽和高都为0.4,
rect = ax1.patch # ax1的矩形设为灰色
rect.set_facecolor('lightslategray')
for label in ax1.xaxis.get_ticklabels():
# 调用x轴刻度标签实例,是一个text实例
label.set_color('g') # 颜色
label.set_rotation(45) # 旋转角度
label.set_fontsize(16) # 字体大小
for line in ax1.yaxis.get_ticklines():
# 调用y轴刻度线条实例, 是一个Line2D实例
line.set_color('red') # 颜色
line.set_markersize(25) # marker大小
line.set_markeredgewidth(2)# marker粗细
'调整一些轴和刻度的属性'
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmeZzaxV-1653051997878)(output_45_1.png)]
Tick容器
matplotlib.axis.Tick是从Figure到Axes到Axis到Tick中最末端的容器对象。
Tick包含了tick、grid line实例以及对应的label。
所有的这些都可以通过Tick的属性获取,常见的tick属性有
Tick.tick1line:Line2D实例
Tick.tick2line:Line2D实例
Tick.gridline:Line2D实例
Tick.label1:Text实例
Tick.label2:Text实例
'''
y轴分为左右两个,因此tick1对应左侧的轴;tick2对应右侧的轴。
x轴分为上下两个,因此tick1对应下侧的轴;tick2对应上侧的轴。
下面的例子展示了,如何将Y轴右边轴设为主轴,并将标签设置为美元符号且为绿色
'''
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
# 设置ticker的显示格式
formatter = matplotlib.ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)
# 设置ticker的参数,右侧为主轴,颜色为绿色
ax.yaxis.set_tick_params(which='major', labelcolor='r',
labelleft=False, labelright=True);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21lKiRLi-1653051997879)(output_47_0.png)]
思考题
- primitives 和 container的区别和联系是什么,分别用于控制可视化图表中的哪些要素
1) primitive 是基本要素,包含作图是用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等\2) containers 是容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis
容器会包含一些primitives,并且容器还有它自身的属性。 比如Axes Artist,它是一种容器,它包含了很多primitives,比如Line2D,Text;同时,它也有自身的属性,比如xscal,用来控制X轴是linear还是log的
- 使用提供的drug数据集,对第一列yyyy和第二列state分组求和,画出下面折线图。PA加粗标黄,其他为灰色。
图标题和横纵坐标轴标题,以及线的文本暂不做要求。
# 1.plot方法绘制
x = [2010,2011,2012,2013,2014,2015,2016,2017]
y1 = [3000,3010,3015,3020,3010,3000,3010,2900]
y2 = [8000,6000,7000,11000,9000,8050,10010,10020]
y3 = [10100,10100,11000,12000,12100,10000,10010,9200]
y4 = [20000,20010,20010,21000,26000,27000,27100,28000]
y5 = [20000,20030,23000,27000,31000,37000,42000,47000]
fig = plt.figure()
ax1 = fig.add_axes([0, 1, 3, 2])
ax1.plot(x, y1,color= "gray",label="WW")
ax1.plot(x, y2,color= "gray",label="KY")
ax1.plot(x, y3,color= "gray",label="VA")
ax1.plot(x, y4,color= "orange", linewidth=5,label="FA")
ax1.plot(x, y5,color= "gray",label="CH")
plt.xlabel('Years',fontsize=22)
plt.ylabel('DrugReports',fontsize=22)
plt.title('Evolution of PA vs other states',fontsize=22,color='orange',horizontalalignment='left')
for ax in fig.axes:
ax.grid(True)
plt.legend() #显示图例
plt.show()
[<matplotlib.lines.Line2D at 0x1cf43e0b370>]
[<matplotlib.lines.Line2D at 0x1cf43e0ba60>]
[<matplotlib.lines.Line2D at 0x1cf43e0bd30>]
[<matplotlib.lines.Line2D at 0x1cf43e0bfd0>]
[<matplotlib.lines.Line2D at 0x1cf43e12220>]
Text(0.5, 0, 'Years')
Text(0, 0.5, 'DrugReports')
Text(0.5, 1.0, 'Evolution of PA vs other states')
<matplotlib.legend.Legend at 0x1cf43d71d60>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZnFWke6-1653051997879)(output_50_9.png)]
- 分别用一组长方形柱和填充面积的方式模仿画出下图,函数 y = -1 * (x - 2) * (x - 8) +10 在区间[2,9]的积分面积
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mPatches
def func(x):
return -(x-2)*(x-8) + 40
x = np.linspace(0,10)
print(x )
y = func(x)
print(y)
fig, ax = plt.subplots()
plt.plot(x, y ,'r' , linewidth=2)
a=2
b=9
ax.set_xticks([0,2,4,6,8,10])
ax.set_yticks([b])
ax.set_xticklabels(['$0$','$2$', '$4$','$6$','$8$','$10$'])
plt.figtext(0.9 , 0.1 , '$x$')
plt.figtext(0.1, 0.9, '$y$')
ix = np.linspace(a,b)
iy = func(ix)
verts = [(a,0)]+ list(zip(ix, iy)) + [ (b,0)]
poly = mPatches.Polygon(verts , facecolor='0.5' , edgecolor='0.3')
ax.add_patch(poly)
plt.text((a+b)*0.5 * 0.7 , 35 , r'$\int_a^b (-(x-2) * (x-8) + 10) dx$')
plt.show()
[ 0. 0.20408163 0.40816327 0.6122449 0.81632653 1.02040816
1.2244898 1.42857143 1.63265306 1.83673469 2.04081633 2.24489796
2.44897959 2.65306122 2.85714286 3.06122449 3.26530612 3.46938776
3.67346939 3.87755102 4.08163265 4.28571429 4.48979592 4.69387755
4.89795918 5.10204082 5.30612245 5.51020408 5.71428571 5.91836735
6.12244898 6.32653061 6.53061224 6.73469388 6.93877551 7.14285714
7.34693878 7.55102041 7.75510204 7.95918367 8.16326531 8.36734694
8.57142857 8.7755102 8.97959184 9.18367347 9.3877551 9.59183673
9.79591837 10. ]
[24. 25.99916701 27.9150354 29.74760516 31.4968763 33.16284881
34.7455227 36.24489796 37.66097459 38.9937526 40.24323199 41.40941274
42.49229488 43.49187838 44.40816327 45.24114952 45.99083715 46.65722616
47.24031653 47.74010829 48.15660142 48.48979592 48.7396918 48.90628905
48.98958767 48.98958767 48.90628905 48.7396918 48.48979592 48.15660142
47.74010829 47.24031653 46.65722616 45.99083715 45.24114952 44.40816327
43.49187838 42.49229488 41.40941274 40.24323199 38.9937526 37.66097459
36.24489796 34.7455227 33.16284881 31.4968763 29.74760516 27.9150354
25.99916701 24. ]
[<matplotlib.lines.Line2D at 0x1cf43e5fbb0>]
[<matplotlib.axis.XTick at 0x1cf43e3ea90>,
<matplotlib.axis.XTick at 0x1cf43e3ea60>,
<matplotlib.axis.XTick at 0x1cf43dca550>,
<matplotlib.axis.XTick at 0x1cf441e1220>,
<matplotlib.axis.XTick at 0x1cf441e1970>,
<matplotlib.axis.XTick at 0x1cf441de100>]
[<matplotlib.axis.YTick at 0x1cf43e448b0>]
[Text(0, 0, '$0$'),
Text(2, 0, '$2$'),
Text(4, 0, '$4$'),
Text(6, 0, '$6$'),
Text(8, 0, '$8$'),
Text(10, 0, '$10$')]
Text(0.9, 0.1, '$x$')
Text(0.1, 0.9, '$y$')
<matplotlib.patches.Polygon at 0x1cf43e5fd00>
Text(3.8499999999999996, 35, '$\\int_a^b (-(x-2) * (x-8) + 10) dx$')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ckO0aUh9-1653051997879)(output_52_9.png)]