学习打卡2-艺术画笔见乾坤

一、概述

1.matplotlib的三层api
matplotlib的原理或者说基础逻辑是,用Artist对象在画布(canvas)上绘制(Render)图形。 就和人作画的步骤类似:

1.准备一块画布或画纸 
2.准备好颜料、画笔等制图工具 
3.作画

所以matplotlib有三个层次的API:

  • matplotlib.backend_bases.FigureCanvas 代表了绘图区,所有的图像都是在绘图区完成的
  • matplotlib.backend_bases.Renderer 代表了渲染器,可以近似理解为画笔,控制如何在 FigureCanvas 上画图。
  • matplotlib.artist.Artist 代表了具体的图表组件,即调用了Renderer的接口在Canvas上作图。 前两者处理程序和计算机的底层交互的事项,第三项Artist就是具体的调用接口来做出我们想要的图,比如图形、文本、线条的设定。所以通常来说,我们95%的时间,都是用来和matplotlib.artist.Artist类打交道的。

2.Artist的分类
Artist有两种类型:primitivescontainers
primitive是基本要素,它包含一些我们要在绘图区作图用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等。
container是容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis。他们之间的关系如下图所示:
在这里插入图片描述

3.matplotlib标准用法
matplotlib的标准使用流程为:

- 创建一个Figure实例

- 使用Figure实例创建一个或者多个Axes或Subplot实例

- 使用Axes实例的辅助方法来创建primitive 

值得一提的是,Axes是一种容器,它可能是matplotlib
API中最重要的类,并且我们大多数时间都花在和它打交道上。更具体的信息会在之后容器小节说明。
一个流程示例及说明如下:

import matplotlib.pyplot as plt
import numpy as np

# step 1 
# 我们用 matplotlib.pyplot.figure() 创建了一个Figure实例
fig = plt.figure()

# step 2
# 然后用Figure实例创建了一个两行一列(即可以有两个subplot)的绘图区,并同时在第一个位置创建了一个subplot
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot

# step 3
# 然后用Axes实例的方法画了一条曲线
t = np.arange(0.0, 1.0, 0.01)
“”“
numpy.arrange([start,]stop,[step,],dtype=None) -> numpy.ndarray
np.arrange()
函数返回一个有终点和起点的固定步长的排列,如[1,2,3,4,5],起点是1,终点是6,步长为1.
参数个数情况:np.arrange()函数分为一个参数,两个参数,三个参数三种情况
1)一个参数时,参数值为终点,起点取默认值0,步长取默认值12)两个参数时,第一个参数为起点,第二个参数为终点,步长取默认值13)三个参数时,第一个参数为起点,第二个参数为终点,第三个参数为步长。其中步长支持小数
#一个参数 默认起点0,步长为1 输出:【0 1 2】
a = np.arange(3)
#两个参数 默认步长为1 输出 【3 4 5 6 7 8】
a = np.arange(3,9)
#三个参数 起点为0,终点为3,步长为0.1 输出【0. 0.1,0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2. 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9】
a = np.arange(0,3,0.1)
“””
s = np.sin(2*np.pi*t) //sin(2πt)
“”“
补:
NumPy 提供了标准的三角函数:sin()、cos()、tan()import numpy as np
 
a = np.array([0,30,45,60,90])
print ('不同角度的正弦值:')
# 通过乘 pi/180 转化为弧度  
print (np.sin(a*np.pi/180))
print ('\n')
print ('数组中角度的余弦值:')
print (np.cos(a*np.pi/180))
print ('\n')
print ('数组中角度的正切值:')
print (np.tan(a*np.pi/180))
不同角度的正弦值:
[0.         0.5        0.70710678 0.8660254  1.        ]


数组中角度的余弦值:
[1.00000000e+00 8.66025404e-01 7.07106781e-01 5.00000000e-01
 6.12323400e-17]


数组中角度的正切值:
[0.00000000e+00 5.77350269e-01 1.00000000e+00 1.73205081e+00
 1.63312394e+16]
“””
line, = ax.plot(t, s, color='blue', lw=2)
#lw:设置画笔的粗细

在这里插入图片描述
NumPy 数学函数
NumPy 包含大量的各种数学运算的函数,包括三角函数,算术运算的函数,复数处理函数等。

#sinx的函数图
t = np.arange(0,2.0,0.01)
s= np.sin(2 * np.pi*t)
fig,ax = plt.subplots()
ax.set_ylabel('sin')
ax.set_xlabel('df')
ax.plot(t,s)
plt.grid(True)
plt.show()

在这里插入图片描述

二、基本元素 - primitives

primitives 的几种类型:曲线-Line2D,矩形-Rectangle,多边形-Polygon,图像-image

1.曲线-Line2D

lass matplotlib.lines.Line2D(xdata, ydata, linewidth=None, linestyle=None, color=None, marker=None, markersize=None, markeredgewidth=None, markeredgecolor=None, markerfacecolor=None, markerfacecoloralt=‘none’, fillstyle=None, antialiased=None, dash_capstyle=None, solid_capstyle=None, dash_joinstyle=None, solid_joinstyle=None, pickradius=5, drawstyle=None, markevery=None, **kwargs)
xdata:需要绘制的line中点的在x轴上的取值,若忽略,则默认为range(1,len(ydata)+1)

  • ydata:需要绘制的line中点的在y轴上的取值
  • linewidth:线条的宽度
  • linestyle:线型
  • color:线条的颜色
  • marker:点的标记
  • markersize:标记的size

a.Line2D属性的设置

1)直接在plot()函数中设置
2)通过获得线对象,对线对象进行设置
3)获得线属性,使用setp()函数设置

# 1) 直接在plot()函数中设置
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x,y, linewidth=10); # 设置线的粗细参数为10

在这里插入图片描述

# 2) 通过获得线对象,对线对象进行设置
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
line, = plt.plot(x, y, '-') # 这里等号坐标的line,是一个列表解包的操作,目的是获取plt.plot返回列表中的Line2D对象
line.set_antialiased(False); # 关闭抗锯齿功能

在这里插入图片描述

# 3) 获得线属性,使用setp()函数设置
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
lines = plt.plot(x, y)
plt.setp(lines, color='r', linewidth=10);

在这里插入图片描述
b.Line2D对象绘制直线

#Line2D对象绘制
import matplotlib.pyplot as plt
x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]
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.矩形-Rectangle

class matplotlib.patches.Rectangle(xy, width, height, angle=0.0, **kwargs)

最常见的矩形图是hist直方图和bar条形图

a.hist直方图

matplotlib.pyplot.hist(x,bins=None,range=None, density=None, bottom=None, histtype=‘bar’, align=‘mid’, log=False, color=None, label=None, stacked=False, normed=None)

  • 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,是否为堆积状图
# hist绘制直方图
import numpy as np
import matplotlib.pyplot as plt
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='fuchsia',alpha=0.5)#alpha设置透明度,0为完全透明 
plt.xlabel('scores') 
plt.ylabel('count') 
plt.xlim(0,100); #设置x轴分布范围 plt.show()

在这里插入图片描述
b.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绘制柱状图
import matplotlib.pyplot as plt
y = range(1,17)
plt.bar(np.arange(16), y, alpha=0.5, width=0.5, color='yellow', edgecolor='red', label='The First Bar', lw=3);

在这里插入图片描述
3.多边形-Polygon

class matplotlib.patches.Polygon(xy, closed=True, **kwargs)

matplotlib.patches.Polygon类中常用的是fill类,它是基于xy绘制一个填充的多边形,它的定义:

matplotlib.pyplot.fill(*args, data=None, **kwargs)

import numpy as np
import matplotlib.pyplot as plt
# 用fill来绘制图形
x = np.linspace(0, 5 * np.pi, 1000) 
y1 = np.sin(x)
y2 = np.sin(2 * x) 
plt.fill(x, y1, color = "g", alpha = 0.3);

在这里插入图片描述

plt.fill(x, y2, color = "g", alpha = 0.3);

在这里插入图片描述

import numpy as np 
from matplotlib.patches import Circle, Wedge, Polygon 
from matplotlib.collections import PatchCollection 
import matplotlib.pyplot as plt 
  
  
# Fixing random state for reproducibility 
np.random.seed(19680801) 
  
fig, ax = plt.subplots() 
  
resolution = 50  # the number of vertices 
N = 3
x = np.random.rand(N) 
y = np.random.rand(N) 
radii = 0.1 * np.random.rand(N) 
patches = [] 
  
for x1, y1, r in zip(x, y, radii):
    circle = Circle((x1, y1), r) 
    patches.append(circle) 
  
x = np.random.rand(N) 
y = np.random.rand(N) 
radii = 0.1 * np.random.rand(N) 
theta1 = 360.0 * np.random.rand(N) 
theta2 = 360.0 * np.random.rand(N) 
  
for x1, y1, r, t1, t2 in zip(x, y, radii, 
                             theta1, theta2):
    wedge = Wedge((x1, y1), r, t1, t2) 
    patches.append(wedge) 
  
# Some limiting conditions on Wedge 
patches += [ 
    Wedge((.3, .7), .1, 0, 360),             # Full circle 
    Wedge((.7, .8), .2, 0, 360, width = 0.05),  # Full ring 
    Wedge((.8, .3), .2, 0, 45),              # Full sector 
    Wedge((.8, .3), .2, 45, 90, width = 0.10),  # Ring sector 
] 
  
for i in range(N):
    polygon = Polygon(np.random.rand(N, 2), True) 
    patches.append(polygon) 
  
colors = 100 * np.random.rand(len(patches)) 
p = PatchCollection(patches, alpha = 0.4) 
p.set_array(np.array(colors)) 
ax.add_collection(p) 
fig.colorbar(p, ax = ax) 
  
plt.show()

在这里插入图片描述

4.图像-image

class matplotlib.image.AxesImage(ax, cmap=None, norm=None, interpolation=None, origin=None, extent=None, filternorm=True, filterrad=4.0, resample=False, **kwargs)

images是matplotlib中绘制image图像的类,其中最常用的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)

import matplotlib.pyplot as plt 
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)  #本函数返回一个或一组服从"0~1"均匀分布的随机值,取值范围[0,1)

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();

在这里插入图片描述

三、对象容器 - Object container

容器会包含一些primitives,并且容器还有它自身的属性。
比如Axes Artist,它是一种容器,它包含了很多primitives,比如Line2D,Text;同时,它也有自身的属性,比如xscal,用来控制X轴是linear还是log的。

1. Figure容器

fig = plt.figure()
ax1 = fig.add_subplot(211) # 作一幅2*1的图,选择第1个子图
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3]) # 位置参数,四个数分别代表了(left,bottom,width,height)
print(ax1) 
print(fig.axes) # fig.axes 中包含了subplot和axes两个实例, 刚刚添加的

在这里插入图片描述
2. Axes容器

fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch  # axes的patch是一个Rectangle实例
rect.set_facecolor('green')

在这里插入图片描述
3. Axis容器

# 不用print,直接显示结果
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()# 获取轴视角(位置)的间隔

在这里插入图片描述
4. Tick容器

import matplotlib
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='green',
                         labelleft=False, labelright=True);

在这里插入图片描述

四、思考题

1.primitives 和 container的区别和联系是什么,分别用于控制可视化图表中的哪些要素。

1)primitive是基本要素,它包含一些我们要在绘图区作图用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等。
2)container是容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis。

2.使用提供的drug数据集,对第一列yyyy和第二列state分组求和,画出下面折线图。PA加粗标黄,其他为灰色。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.read_csv('Drugs.csv')
data.head(10)

在这里插入图片描述test = data.groupby(['State','YYYY'])['DrugReports'].sum() test1 = pd.DataFrame(test) test1
在这里插入图片描述

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.read_csv('Drugs.csv')
for index,group in data.groupby('State'):
    data_group = group.groupby(['YYYY'])['DrugReports'].sum()
    df = pd.DataFrame(data_group)
    df['year'] = df.index
    if index == 'KY':
        plt.plot(df['year'],df['DrugReports'],label = index,color='gray')
    elif index == 'OH':
        plt.plot(df['year'],df['DrugReports'],label = index,color='gray')
    elif index == 'PA':
        plt.plot(df['year'],df['DrugReports'],label = index,color='yellow',linewidth = 10)
    elif index == 'VA':
        plt.plot(df['year'],df['DrugReports'],label = index,color='gray')
    else:
        plt.plot(df['year'],df['DrugReports'],label = index,color='gray')
plt.legend()
plt.show()   
plt.xlim(2010,2017)
plt.xlabel('Year')
plt.ylabel('Drug_reports')
plt.title('Evolution of PA vs other states')

在这里插入图片描述
3.分别用一组长方形柱和填充面积的方式模仿画出下图,函数 y = -1 * (x - 2) * (x - 8) +10 在区间[2,9]的积分面积

import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(2,9,100)
y1 = -1*(x1-2)*(x1-8)+10
x2 = np.linspace(0,10,1000)
y2 = -1*(x2-2)*(x2-8)+10
plt.plot(x2,y2,color='red')
plt.bar(x1,y1,width=0.05,color='grey')
plt.xlim(0)
plt.ylim(0)

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(2,9,1000)
y1 = -1*(x1-2)*(x1-8)+10
x2 = np.linspace(0,10,1000)
y2 = -1*(x2-2)*(x2-8)+10
plt.plot(x2,y2,color='red')
plt.fill_between(x1,y1,color='grey')
plt.xlim(0)
plt.ylim(0)

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值