Matplotlib初相识

认识matplotlib

Matplotlib是一个Python 2D绘图库,能够以多种硬拷贝格局和跨渠道的交互式环境生成出版物质量的图形,用来制作各种静态,动态,交互式的图表

一个最简略的绘图比如

matplotlib的图画都是画在对应的figure上,能够以为是一个绘图区域。而一个figure又能够包括一个或许多个axes,能够以为是子区域,这个子区域能够指定属于自己的坐标系。下面经过简略的实例进行展现:

import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
fig, ax = plt.subplots()  # 该函数创立一个包括1个axes的figure,并将两者进行回来
ax.plot([1,2,3,4],[1,4,2,3])

榜首图

那么也能够用更为简略的办法来进行创立:

line = plt.plot([1,2,3,4],[1,4,2,3])

这是由于假如未指定axes,那么会主动创立一个,因而能够简化。

figure的组成

一般,一个完成的matplotlib图画会包括四个层级(容器):

  • Figure:尖端层,用来容纳一切绘图元素
  • Axes:matplotlib宇宙的中心,容纳了很多元素用来结构一幅幅的子图,一个figure能够由1个或许多个子图构成
  • Axis:axes的基层,用来处理一切与坐标轴、网格相关的元素
  • Tick:axis的基层,用来处理一切和刻度相关的元素

图2

两种绘图接口

matplotlib供给了两种最常用的绘图接口:

  • 创立figure和axes,然后在此之上调用绘图办法
  • 依赖pyplot主动创立figure和axes来绘图

就像是上小节所展现的那样两种创立图的办法。

通用绘图模板

Datawhale供给了一个一般的绘图模板,能够依据实际需求对该模板进行修正了补充:

# 先预备好数据
x = np.linspace(0, 2, 100)
y = x**2
# 设置绘图款式(非必须)
mpl.rc('lines', linewidth=4, linestyle='-.')
# 界说布局
fig, ax = plt.subplots()  
# 制作图画
ax.plot(x, y, label='linear')  
# 增加标签,文字和图例
ax.set_xlabel('x label') 
ax.set_ylabel('y label') 
ax.set_title("Simple Plot")  
ax.legend() ;

图3


考虑题

  • 请考虑两种绘图办法的优缺点和各自适合的运用场景

    • 我觉得先创立figure和axes再进行绘图的办法更适用于你对图的规划比较明晰,或许你想要画多个子图,这样在同一个figure上作画会简洁方便;而pyplot模型更实用于你当时只需求画一个图,那么把一切元素都加到当时这个图上就能够了
  • 在第五节绘图模板中咱们是以OO办法作为比如展现的,请考虑并写一个pyplot绘图办法的简略模板

    • plt.plot(x,y,label='linear')
      plt.xlabel("x label")
      plt.ylabel("y label")
      plt.title("simple plot")
      plt.legend()
      

艺术画笔见乾坤

先预备待会儿要用到的库

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目标在画布(canvas)上制作(Render)图形。因而跟人作画相似,需求三个过程:

  • 预备一个画图
  • 预备画笔、颜料
  • 作画

因而能够以为matplotlib有三层的API:

  • matplotlib.backend_bases.FigureCanvas 代表了绘图区,一切的图画都是在绘图区完成的
  • matplotlib.backend_bases.Renderer 代表了渲染器,能够近似理解为画笔,操控如安在 FigureCanvas 上画图。
  • matplotlib.artist.Artist 代表了具体的图表组件,即调用了Renderer的接口在Canvas上作图。

因而咱们大部分是运用Artist类来进行绘图。

Artist的分类

Artist有两种类型:primitivescontainers

  • primitive是基本要素,包括一些咱们要在绘图区作图用到的规范图形目标,例如曲线、文字、矩形等等。
  • container是容器,能够以为是用来放置基本要素的地方,包括图形figure,坐标系axes和坐标系axis

基本元素primitives

primitives首要有以下几种类型,咱们按照顺序介绍。

2DLines

其间常见的参数首要有:

  • xdata:横坐标的取值,默许便是range(1,len(data)+1)
  • ydata:纵坐标取值
  • linewidth:线条的宽度
  • linestyle:线型
  • color:线条的色彩
  • marker:点的标示款式
  • markersize:标示的巨细
如何设置参数特点

关于上面提到的各个参数有三种修正办法:

  • 在plot函数里边进行设置

    x = range(0,5)
    y = [2,5,7,9,11]
    plt.plot(x,y,linewidth = 10)  
    
  • 获取线目标,对线目标进行设置

    x = range(0,5)
    y = [2,5,7,8,10]
    line, = plt.plot(x, y, '-') # 这儿等号坐标的line,是一个列表解包的操作,目的是获取plt.plot回来列表中的Line2D目标,回来是一个列表类型
    line.set_antialiased(False); # 关闭抗锯齿功用,调用线目标的函数
    
  • 获取线特点,运用setp函数设置

    x = range(0,5)
    y = [2,5,7,8,10]
    lines = plt.plot(x, y)
    plt.setp(lines, color='r', linewidth=10);
    
如何制作lines

那咱们常见的功用是制作直线line,以及制作errorbar差错折线图,下面临这两种别离进行介绍。


制作line

能够选用两种办法来制作直线:

1、plot办法

x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]
fig,ax= plt.subplots()
ax.plot(x,y1)
ax.plot(x,y2)
print(ax.lines); 

图4

打印为:

<Axes.ArtistList of 2 lines>

能够看到创立了2个lines目标。

2、Line2D目标制作

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

图5


制作errorbar差错折线图

是运用pyplot中的errorbar类来完成,其参数为:

  • x:横坐标
  • y:纵坐标
  • yerr:指定在y轴水平的差错
  • xerr:指定在x轴水平的差错
  • fmt:指定折线图中某个点的色彩、形状、线条风格等
  • ecolor:指定errorbar的色彩
  • elinewidth:指定errorbar的线条宽度

那么具体的制作办法便是将plot更改为errorbar即可:

fig = 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,fmt='o-',ecolor='r',elinewidth=2);

图6


patches

这个类是二维图形类,它最常见的能够用来制作矩形、多边形、楔形。

矩形

Rectangle矩形类比较简略,首要是经过xy来操控锚点,然后操控矩形的高宽即可。

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

hist-直方图

其函数为plt.hist(),那么参数为:

  • x:数据集,直方图将会对这个数据集进行计算
  • bins:计算的区间散布,咱们能够指定区间进行计算,例如按照([0,10],[11,20])区间进行计算
  • range:tuplt,显现的区间
  • density:是否显现频数计算成果
  • histtype:可选{‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’}之一,默以为bar,step运用的是梯状,stepfilled则会对梯状内部进行填充,效果与bar相似
  • align:可选{‘left’, ‘mid’, ‘right’}之一,默以为’mid’,操控柱状图的水平散布,left或许right,会有部分空白区域,引荐运用默许
  • log:y轴是否选用指数刻度
  • stacked:是否为堆积状图
x=np.random.randint(0,100,100) #生成[0-100)之间的100个数据,即 数据集 
bins=np.arange(0,101,10) #设置连续的鸿沟值,即直方图的散布区间[0,10),[10,20)... 
fig = plt.figure(figsize = (6,12))
plt.subplot(311)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "left")#alpha设置通明度,0为彻底通明 
plt.xlabel('scores') 
plt.ylabel('count') 
plt.xlim(0,100); #设置x轴散布规模 plt.show()
plt.subplot(312)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "mid")
plt.subplot(313)
plt.hist(x,bins,color='fuchsia',alpha=0.5, density = True, histtype="step", 
        align = "right")

这儿对比了一下参数align的差异:

图7

bar-柱状图

相同,也是选用plt.bar()函数,其参数为:

  • left:x轴的方位序列,一般选用range函数产生一个序列,但是有时分能够是字符串
  • height:y轴的数值序列,也便是柱形图的高度,一般便是咱们需求展现的数据
  • alpha:通明度,值越小越通明
  • width:柱形的宽度
  • color或许facecolor:柱形填充的色彩
  • edgecolor:柱形边际色彩
  • label:标签
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=2);
# lw是柱形描边的线宽度

图8

多边形

Polygon类是多边形类,其参数首要是制作的多边形的极点坐标。

那么这个类中最常用的是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);

图8

楔型(饼状图)

一个楔型是以坐标xy为中心,半径r,从视点1扫到视点2。最常用是制作饼状图plt.pie()

其参数为:

  • x:楔型的形状,一维数组,能够看成是扫过视点的巨细
  • explode:假如不是None,那么便是一个len(x)的数组,用来指定每块的偏移
  • labels:指定每个块的标签,列表或许none
  • colors:指定每个块的色彩,列表或许none
  • startangle:饼状图开端制作的视点
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
sizes = [15, 30, 45, 10] 
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');  # 设置axes为等高宽比,这样才能够确保画出来为圆形

饼状图

collections

这个类是用来制作一组目标的调集,那么最常见的是用来制作散点图,即scatter办法,依据xy制作不同巨细或许色彩符号的散点图。

其首要的参数如下:

  • x和y
  • s:散点的尺度巨细
  • c:色彩
  • marker:符号类型
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) ;

散点图

image

这是制作图画的类,最常用的imshow能够依据数组制作成图画(数值是各个像素值)。

运用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()  # 主动调整子图使其填充整个图画

imshow函数

目标容器-Object container

前面咱们介绍的primitives根底元素,是包括在容器里边的,当然容器还会包括它本身的特点。

Figure容器

figure是最顶层的一个容器,它包括了图中的一切元素,而一个图表的布景能够以为便是在figure中增加的一个矩形。

当咱们向图表中增加add_subplot或许add_axes时,这些元素会被增加到figure.axes列表中:

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)
ax3 = fig.add_axes([0.2,0.1,0.3,0.4])  # 增加第三个子图
print(ax1) 
print(fig.axes) # fig.axes 中包括了subplot和axes两个实例, 刚刚增加的

子图

能够看到假如增加的子图方位重叠的可能存在的状况。而输出成果为:

AxesSubplot(0.125,0.53;0.775x0.35)
[<AxesSubplot:>, <Axes:>, <Axes:>]

figure.axes的列表中当时有三个元素,代表三个子图。

而咱们能够经过figure.delaxes()来删去其间的图表,或许能够经过迭代访问列表中的元素获取子图表,再在其上做修正:

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)
ax3 = fig.add_axes([0.2,0.1,0.3,0.4])
print(ax1) 
print(fig.axes) # fig.axes 中包括了subplot和axes两个实例, 刚刚增加的
for ax in fig.axes:
    ax.grid(True)

子图加上网格

Axes容器

Axes是matplotlib的中心。很多的用于绘图的Artist存放在它内部,而且它有许多辅佐办法来创立和增加Artist给它自己,而且它也有许多赋值办法来访问和修正这些Artist

和figure相似,axes包括一个patch特点,这个能够以为便是它的绘图区域:

fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch  # 获取实例
rect.set_facecolor("blue")

axespatch

Axes有许多办法用于绘图,如.plot()、.text()、.hist()、.imshow()等办法用于创立大多数常见的primitive(如Line2D,Rectangle,Text,Image等等)。

能够在恣意区域创立Axes,经过Figure.add_axes([left,bottom,width,height])来创立一个恣意区域的Axes,其间left,bottom,width,height都是[0—1]之间的浮点数,他们代表了相关于Figure的坐标。

而咱们往axes里边增加图表是经过add_line和add_patch来进行增加。

另外Axes还包括两个最重要的Artist container:

  • ax.xaxis:XAxis目标的实例,用于处理x轴tick以及label的制作
  • ax.yaxis:YAxis目标的实例,用于处理y轴tick以及label的制作

Axis容器

该容器用来处理跟坐标轴相关的特点,它包括坐标轴上的刻度线、刻度label、坐标网格、坐标轴标题等,而且能够独立对上下左右四个坐标轴进行处理。

能够经过下面的办法获取坐标轴的各个特点实例:

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实例的列表) 
axis.get_ticklines()    # 获取刻度线列表(一个Line2D实例的列表)
axis.get_data_interval()# 获取轴刻度间隔
axis.get_view_interval()# 获取轴视角(方位)的间隔

也能够对获取的特点进行修正,例如:

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('blue') # 色彩
    label.set_rotation(45) # 旋转视点
    label.set_fontsize(14) # 字体巨细
for line in ax1.yaxis.get_ticklines():
    # 调用y轴刻度线条实例, 是一个Line2D实例
    line.set_markeredgecolor('green')    # 色彩
    line.set_markersize(25)    # marker巨细
    line.set_markeredgewidth(2)# marker粗细

修正axis

Tick容器

它是axis下方的一个容器目标,包括了tick、grid、line实例以及对应的label。咱们能够访问它的特点来获取这些实例:

  • Tick.tick1line:Line2D实例
  • Tick.tick2line:Line2D实例
  • Tick.gridline:Line2D实例
  • Tick.label1:Text实例
  • Tick.label2:Text实例

y轴分为左右两个,因而tick1对应左侧的轴;tick2对应右侧的轴。

x轴分为上下两个,因而tick1对应下侧的轴;tick2对应上侧的轴。

例如咱们做如下修正:

fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
ax.yaxis.set_tick_params(which='major', labelcolor='blue',
                         labelleft=False, labelright=True);

设置右轴

将主轴设在右边且修正其色彩。


考虑题

  • primitives 和 container的差异和联络是什么,别离用于操控可视化图表中的哪些要

    • 【答】:我以为container是一个容器,而primitives 是基本元素,能够理解为container是包容primitives的,例如figure,axes,axis等作为一个容器,它们能够包括很多primitives 的根底元素在其上面进行展现
  • 运用供给的drug数据集,对榜首列yyyy和第二列state分组求和,画出下面折线图。PA加粗标黄,其他为灰色。
import pandas as pd
df = pd.read_csv("Drugs.csv")
df.head(5)
new_df = df.groupby(["YYYY","State"]).sum()
new_df

1

data = new_df.reset_index().pivot(index='YYYY', columns='State', values='DrugReports')
data

2

data = data.reset_index()
data

3

因而就能够开端绘图了:

fig,ax = plt.subplots(figsize = (12,12))
ax.grid(True, color='white')
rect = ax.patch
rect.set_facecolor('#efefef')
ax.plot(data["YYYY"], data["KY"],color='#afafaf')
ax.plot(data["YYYY"], data["OH"],color='#afafaf')
ax.plot(data["YYYY"], data["PA"],color='yellow',linewidth='8')
ax.plot(data["YYYY"], data["VA"],color='#afafaf')
ax.plot(data["YYYY"], data["WV"],color='#afafaf')
ax.set_title('Evolution of PA vs other states', color='yellow', loc='left')
ax.set_xlabel('Year')
ax.set_ylabel('DrugReports')

作业图1

  • 别离用一组长方形柱和填充面积的办法仿照画出下图,函数 y = -1 * (x – 2) * (x – 8) +10 在区间[2,9]的积分面积
import numpy as np
x = np.linspace(0,10)
y = -1 * (x - 2) * (x - 8) + 10
fig,ax = plt.subplots(2,1,figsize = (8,12))
x_bar = np.linspace(2,9)
y_bar = -1 * (x_bar - 2) * (x_bar - 8) + 10
y_bar_button = y_bar * 0
ax[0].plot(x,y,color="red")
ax[1].plot(x,y,color="red")
ax[0].bar(x_bar, y_bar,width=0.1, color='lightgray')
ax[1].bar(x_bar, y_bar, width = 0.1, color='lightgray')
ax[0].set_ylim((0,20))
ax[1].set_ylim((0,20))
ax[1].fill_between(x_bar, y_bar, y_bar_button, color="lightgray")

作业图2

布局格局定方圆

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']   #用来正常显现中文标签
plt.rcParams['axes.unicode_minus'] = False   #用来正常显现负号

子图

运用plt.subplots()制作均匀状态下的子图

该函数的回来别离是画布和子图构成的列表,传入的参数为行、列、第几个子图,figsize用来指定画布的巨细,sharex和sharey用来表明是否共享横轴和纵轴刻度,tight_layout用来调整子图的相对巨细使字符不重叠:

fig, axs = plt.subplots(2,5, figsize = (10,4), sharex = True, sharey = True)
fig.suptitle("样例1",size = 20)
for i in range(2):
    for j in range(5):
        axs[i][j].scatter(np.random.randn(10), np.random.randn(10))
        axs[i][j].set_title('第%d行,第%d列'%(i+1,j+1))
        axs[i][j].set_xlim(-5,5)
        axs[i][j].set_ylim(-5,5)
        if i==1: axs[i][j].set_xlabel('横坐标')
        if j==0: axs[i][j].set_ylabel('纵坐标')
fig.tight_layout()

子图样例1

前面是运用subplots(留意加了s)显式的创立多个目标,然后逐个进行画图;咱们还能够经过plt和subplot(留意没加s),每次在指定方位创立子图,创立后当时的制作都会指向该子图:

plt.figure()
# 子图1
plt.subplot(2,2,1) 
plt.plot([1,2], 'r')
# 子图2
plt.subplot(2,2,2)
plt.plot([1,2], 'b')
#子图3
plt.subplot(224)  # 当三位数都小于10时,能够省掉中间的逗号,这行指令等价于plt.subplot(2,2,4) 
plt.plot([1,2], 'g');

子图样例2

除了惯例的直角坐标系,还能够用projection办法创立极坐标系下的图表:

N = 300
r = 2 * np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
area = 50 * r**2
colors = theta
plt.subplot(projection='polar')
plt.scatter(theta, r, c=colors, s=area, cmap='hsv', alpha=0.75);

极坐标图


练一练

请考虑如何用极坐标系画出相似的玫瑰图

fig = plt.figure(figsize = (8,12))
ax = plt.subplot(projection = "polar")
x = np.arange(100,1000, 20)  # 间隔为20
y = np.linspace(0,np.pi*2, len(x))
ax.set_theta_direction(-1)  # 设置极坐标的方向为顺时针,1为逆时针
ax.set_theta_zero_location('N')  # 设置开端画的方位,有8个方位
ax.bar(y, x, width = 0.15,color=np.random.random((len(r), 3)))
plt.tight_layout()  

首要便是set_theta_direction和set_theta_zero_location两个函数调整图画。

极坐标2

运用GridSpec制作非均匀子图

所谓非均匀包括两层意义,榜首是指图的份额巨细不同但没有跨行或跨列,第二是指图为跨列或跨行状态

运用 add_gridspec 能够指定相对宽度份额 width_ratios 和相对高度份额参数 height_ratios

fig = plt.figure(figsize=(10, 4))
spec = fig.add_gridspec(nrows=2, ncols=5, width_ratios=[1,2,3,4,5], height_ratios=[1,3])
fig.suptitle('样例2', size=20)
for i in range(2):
    for j in range(5):
        ax = fig.add_subplot(spec[i, j])  # 留意此处的调用办法
        ax.scatter(np.random.randn(10), np.random.randn(10))
        ax.set_title('第%d行,第%d列'%(i+1,j+1))
        if i==1: ax.set_xlabel('横坐标')
        if j==0: ax.set_ylabel('纵坐标')
fig.tight_layout()

子图样例3

上述创立子图时用到了spec[i,j]的办法,阐明它是一个可索引的列表,那么相同也能够对其选用切片:

fig = plt.figure(figsize=(10, 4))
spec = fig.add_gridspec(nrows=2, ncols=6, width_ratios=[2,2.5,3,1,1.5,2], height_ratios=[1,2])
fig.suptitle('样例3', size=20)
# sub1
ax = fig.add_subplot(spec[0, :3])  # 高度取榜首个,宽度前三个都要了,便是1,7.5
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub2
ax = fig.add_subplot(spec[0, 3:5]) # 1,1+1.5
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub3
ax = fig.add_subplot(spec[:, 5])
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub4
ax = fig.add_subplot(spec[1, 0])
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub5
ax = fig.add_subplot(spec[1, 1:5])
ax.scatter(np.random.randn(10), np.random.randn(10))
fig.tight_layout()

子图样例4

子图上的办法

补充一些子图上的常用办法。


常用来画直线的办法为axhline, axvline, axline (水平、垂直、恣意方向)

fig, ax = plt.subplots(figsize=(4,3))
ax.axhline(0.5,0.1,0.8, color = 'red')  
# 榜首个参数为水平y等于多少,第二个为xmin,第三个为xmax,都是浮点数代表坐标轴占百分比
ax.axvline(0.5,0.2,0.8, color = "blue")
ax.axline([0.3,0.3],[0.7,0.7], color = "green");

子图画直线


运用grid能够增加灰色网格:

fig, ax = plt.subplots(figsize=(4,3))
ax.grid(True)

子图网格


运用set_xscale或许set_yscale能够设置坐标轴的刻度:

fig, axs = plt.subplots(1, 2, figsize=(10, 4))
for j in range(2):
    axs[j].plot(list('abcd'), [10**i for i in range(4)])
    if j==0:
        axs[j].set_yscale('log')
    else:
        pass
fig.tight_layout()

对数刻度


考虑题

  • 墨尔本1981年至1990年的每月温度状况
data = pd.read_csv("layout_ex1.csv")
data["Time"] = pd.to_datetime(data["Time"])
data["year_num"] = data["Time"].apply(lambda x: x.year)
fig, ax = plt.subplots(2, 5, figsize = (20,4))
fig.suptitle('墨尔本1981年至1990年月温度曲线',size=20,y=1.1)
for i in range(2):
    for j in range(5):
        tem = data[data["year_num"] == j+1981+i*5]["Temperature"]
        x = np.arange(0,12)
        ax[i][j].plot(x,tem,marker = "o",color='b')
        ax[i][j].set_title(str(j+1981 + i*5 ) + "年")
        if( j == 0):
            ax[i][j].set_ylabel("气温")
plt.tight_layout()

墨尔本温度

  • np.random.randn(2, 150) 生成一组二维数据,运用两种非均匀子图的切割办法,做出该数据对应的散点图和边际散布图
data = np.random.randn(2,150)
fig = plt.figure(figsize = (12,12))
spec = fig.add_gridspec(nrows = 2, ncols = 2,width_ratios = [3,1],height_ratios=[1,3])
ax = fig.add_subplot(spec[0,0])
ax.hist(data[0,:],color = "blue",width = 0.4)
ax.axis("off")
ax2 = fig.add_subplot(spec[1,1])
ax2.hist(data[1,:], orientation='horizontal',color = "blue",rwidth = 0.8)
# 第二个参数设置为在y上面
ax2.axis("off")
ax3 = fig.add_subplot(spec[1,0])
ax3.scatter(data[0,:],data[1,:],color = "blue")
ax3.grid(True)
ax3.set_ylabel("my_data_y")
ax3.set_xlabel("my_data_x")
plt.tight_layout()

作业题2

文字图例尽眉目

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
import datetime

Figure和Axes上的文本

文本API示例

下面这些指令是经过pyplot API和ooAPI别离创立文本的办法:

5


fig = plt.figure()
ax = fig.add_subplot()
# 设置x和y轴标签
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# 设置x和y轴显现规模均为0到10
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
        bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
# 在画布上增加文本,一般在子图上增加文本是更常见的操作,这种办法很少用
fig.text(0.4,0.8,'This is text for figure')
ax.plot([2], [1], 'o')
# 增加注解
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
            arrowprops=dict(facecolor='black', shrink=0.05));

文本样例1

text-子图上的文本

其调用办法为axes.text()。那么其参数为:

  • x,y:文本呈现的方位
  • s:文本的内容
  • fontdict:可选参数,用来调整文本的特点

要点解释下fontdict和**kwargs参数,这两种办法都能够用于调整呈现的文本款式,最终效果是相同的,不仅text办法,其他文本办法如set_xlabel,set_title等相同适用这两种办法修正款式。经过一个比如演示这两种办法是如何运用的。

fig = plt.figure(figsize = (10,3))
axes = fig.subplots(1,2)
axes[0].text(0.3,0.8, "modift by **kwargs", style="italic",
            bbox = {"facecolor":"red", "alpha":0.5, "pad": 10})
font = {"bbox": {"facecolor":"red", "alpha":0.5, "pad": 10},
       "style":"italic"}
axes[1].text(0.3,0.8, "modify by fontdict", fontdict = font)

文本样例2

那么这些款式常用的参数如下:

111

222

xlabel和ylabel

其调用办法为axes.set_xlabel和axes.set_ylabel

其参数为:

  • xlabel:标签内容
  • fontdict和之前相同
  • **kwargs也和之前相同
  • labelpad:标签和坐标轴之间的距离
  • loc:标签方位,可选为”left”,”center”,”right”

在**kwargs中有另外的参数能够调整标签的方位等信息,下面来观察他们的差异:

fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,2)
axes[0].set_xlabel('xlabel',labelpad=20,loc='left')
# loc参数仅能供给大略的方位调整,假如想要更准确的设置标签的方位,能够运用position参数+horizontalalignment参数来定位
# position由一个元组过程,榜首个元素0.2表明x轴标签在x轴的方位,第二个元素关于xlabel其实是无意义的,随意填一个数都能够
# horizontalalignment='left'表明左对齐,这样设置后x轴标签就能准确定位在x=0.2的方位处
axes[1].set_xlabel('xlabel', position=(0.2, _), horizontalalignment='left');

标签样例

title和suptitle-子图和画布的标题

title调用办法为axes.set_title(),其参数为:

  • label:标签内容
  • fontdict,loc,**kwargs和之前相同
  • pad:标题违背图表顶部的方位
  • y:title地点子图垂向的方位,默许在子图的顶部

suptitle的调用为figure.suptitle()。

下面检查pad和y的影响:

fig = plt.figure(figsize=(10,3))
fig.suptitle('This is figure title',y=1.2) # 经过参数y设置高度
axes = fig.subplots(1,2)
axes[0].set_title('This is title,pad = 15',pad=15)
axes[1].set_title('This is title,pad = 6',pad=6);
fig = plt.figure(figsize=(10,3))
fig.suptitle('This is figure title2',y=1) 
axes = fig.subplots(1,2)
axes[0].set_title('This is title,y = 1',y = 1)
axes[1].set_title('This is title,y = 1.2',y = 1.2);

pad样例

y样例

能够看到两者其实便是操控标题与图的距离而已。

annotate-子图的注解

调用办法为axes.annotate(),其参数为:

  • text:注解的内容
  • xy:注解箭头指向的方位
  • xytext:注解文字的坐标
  • xycoords:用来界说xy参数的坐标系
  • textcoords:用来界说xytext参数的坐标系
  • arrowprops:用来界说指向箭头的款式

其参数特别多样化,这儿只是举个比如:

fig = plt.figure()
ax = fig.add_subplot()
ax.annotate("annotate1",
            xy=(0.2, 0.2), xycoords='data',
            xytext=(0.8, 0.8), textcoords='data',
            arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.2")
            );

箭头实例

字体的特点设置

字体设置一般有大局字体设置和自界说部分字体设置两种办法。

为了方便在图中加入合适的字体,能够测验了解中文字体的英文称号,此链接中就有常用的中文字体的英文名

#该block讲述如安在matplotlib里边,修正字体默许特点,完成大局字体的更改。
plt.rcParams['font.sans-serif'] = ['SimSun']    # 指定默许字体为新宋体。
plt.rcParams['axes.unicode_minus'] = False      # 解决保存图画时 负号'-' 显现为方块和报错的问题。
#部分字体的修正办法1
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(x, label='小示例图标签')
# 直接用字体的名字
plt.xlabel('x 轴称号参数', fontproperties='Microsoft YaHei', fontsize=16)         # 设置x轴称号,选用微软雅黑字体
plt.ylabel('y 轴称号参数', fontproperties='Microsoft YaHei', fontsize=14)         # 设置Y轴称号
plt.title('坐标系的标题',  fontproperties='Microsoft YaHei', fontsize=20)         # 设置坐标系标题的字体
plt.legend(loc='lower right', prop={"family": 'Microsoft YaHei'}, fontsize=10) ;   # 小示例图的字体设置

字体1

tick上的文本

设置tick(刻度)和ticklabel(刻度标签)也是可视化中经常需求操作的过程,matplotlib既供给了主动生成刻度和刻度标签的办法(默许状态),同时也供给了许多灵活设置的办法。

简略办法

直接运用axis.set_ticks设置标签方位,运用axis.set_ticklabels设置标签格局:

x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 10.1, 2.));

tick1

能够主动设置相对来说会好一点(上图)

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla);

tick2

咱们一般设置tick都是要与数值的规模匹配, 然后再设置ticklabel为咱们想要的类型,如下:


fig, axs = plt.subplots(2, 1, figsize=(6, 4), tight_layout=True)
x1 = np.linspace(0.0, 6.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
axs[0].plot(x1, y1)
axs[0].set_xticks([0,1,2,3,4,5,6])
axs[1].plot(x1, y1)
axs[1].set_xticks([0,1,2,3,4,5,6])#要将x轴的刻度放在数据规模中的哪些方位
axs[1].set_xticklabels(['zero','one', 'two', 'three', 'four', 'five','six'],#设置刻度对应的标签
                   rotation=30, fontsize='small')#rotation选项设定x刻度标签倾斜30度。
axs[1].xaxis.set_ticks_position('top')
#set_ticks_position()办法是用来设置刻度地点的方位,常用的参数有bottom、top、both、none
print(axs[1].xaxis.get_ticklines());

tick4

上方的比如便是方位在bottom,下方便是在top,both便是上下都有,none便是都没有。

Tick Lacators and Formatters

除了上述的简略办法以外,还能够经过Axis.set_major_locator和Axis.set_minor_locator办法用来设置标签的方位,Axis.set_major_formatter和Axis.set_minor_formatter办法用来设置标签的格局。这种办法的好处是不用显式地列举出刻度值列表。

set_major_formatter和set_minor_formatter这两个formatter格局指令能够接收字符串格局(matplotlib.ticker.StrMethodFormatter)或函数参数(matplotlib.ticker.FuncFormatter)来设置刻度值的格局 。

这部分的内容比较引荐用到的时分再去查。

Tick Formatters

承受字符串:

fig, axs = plt.subplots(2, 2, figsize=(12, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
    ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('-%1.1f')
axs[1, 0].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
axs[1, 1].xaxis.set_major_formatter(formatter);

tick3

承受函数:

def formatoddticks(x, pos):
    if x % 2:
        return f'{x:1.2f}'
    else:
        return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
ax.xaxis.set_major_formatter(formatoddticks);

tick5

Tick Locators

这个完成更杂乱的操作:

fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
    ax.plot(x1*10., y1)
locator = matplotlib.ticker.AutoLocator()
axs[0, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MaxNLocator(nbins=3)
axs[0, 1].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.MultipleLocator(5)
axs[1, 0].xaxis.set_major_locator(locator)
locator = matplotlib.ticker.FixedLocator([0,7,14,21,28])
axs[1, 1].xaxis.set_major_locator(locator);

tick6

# 特别的日期型locator和formatter
locator = mdates.DayLocator(bymonthday=[1,15,25])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70);

tick7

legend图例

在学习legend之前需求先学习几个术语:

  • legend entry(图例条目):每个图例都有一个或许多个条目组成,一个条目包括一个key和对应的label,例如图中三条曲线需求标示,那么便是3个条目
  • legend key(图例键):每个legend label左边的符号,指明是哪条曲线
  • legend label(图例标签):描述文本
  • legend handle(图例句柄):用于在图例中生成恰当图例条目的原始目标

以下图为例,右侧的方框中的共有两个legend entry;两个legend key,别离是一个蓝色和一个黄色的legend key;两个legend label,一个名为‘Line up’和一个名为‘Line Down’的legend label

示例图

图例的制作相同有OO办法和pyplot办法两种办法,写法都是相同的,运用legend()即可调用。

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend(handles = [line_up, line_down], labels = ['Line Up', 'Line Down']);

legend1

fig, ax = plt.subplots()
line_up, = ax.plot([1, 2, 3], label='Line 2')
line_down, = ax.plot([3, 2, 1], label='Line 1')
ax.legend()

legend2

而设置图例的方位,能够经过设置loc参数的值来设置,其有10个方位能够挑选,每个都有字符串的办法和对应的数字办法:

Location String Location Code
best 0
upper right 1
upper left 2
lower left 3
lower right 4
right 5
center left 6
center right 7
lower center 8
upper center 9
center 10
fig,axes = plt.subplots(2,5,figsize=(15,5))
for i in range(2):
    for j in range(5):
        axes[i][j].plot([0.5],[0.5])
        axes[i][j].legend(labels='a',loc=i*5+j)  # 观察loc参数传入不同值时图例的方位
fig.tight_layout()

legend3

还能够设置图例的边框和布景:

fig = plt.figure(figsize=(10,3))
axes = fig.subplots(1,3)
for i, ax in enumerate(axes):
    ax.plot([1,2,3],label=f'ax {i}')
axes[0].legend(frameon=False) #去掉图例边框
axes[1].legend(edgecolor='blue') #设置图例边框色彩
axes[2].legend(facecolor='gray'); #设置图例布景色彩,若无边框,参数无效

legend4

也能够为图例加上标题:

fig,ax =plt.subplots()
ax.plot([1,2,3],label='label')
ax.legend(title='legend title');

legend5


考虑题

测验运用两种办法仿照画出下面的图表(要点是柱状图上的标签),本文学习的text办法和matplotlib自带的柱状图标签办法bar_label

榜首种

label = ["Jim","Slim","Harry","Dick","Tom"]
y = [4,7,6,8,10]
error = np.random.rand(len(y)).round(2) #差错
fig,ax = plt.subplots()
ax.set_title("How fast do you want to go today?")
ax.set_xlim(0,15)
for i in range(0, len(y)):
    ax.text(y[i] + error[i]+1, label[i], '±' + str(error[i]), fontsize=10,horizontalalignment='center',color='blue')
ax.set_xlabel('performance')
ax.barh(label, y, color = 'blue',xerr = error)
# barh有一个参数为xerr便是来画差错线的
label = ["Jim","Slim","Harry","Dick","Tom"]
y = [4,7,6,8,10]
error = np.random.rand(len(y)).round(2) #差错
fig,ax = plt.subplots()
ax.set_title("How fast do you want to go today?")
ax.set_xlim(0,15)
ax.set_xlabel('performance')
b = ax.barh(label, y, color = 'blue',xerr = error)
plt.bar_label(b, ["±"+str(i) for i in error])

考虑题

款式色彩秀芳华

第五回具体介绍matplotlib中款式和色彩的运用

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

matplotlib的绘图款式(style)

设置款式最简略便是在制作每一个元素时在参数中设定对应的款式,不过也能够用办法来批量修正大局的款式。

matplotlib预先界说款式

只需求在python脚步最开端时输入想运用的style的称号就能够调用,那么咱们能够检查有哪些办法方便运用:

print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']

那么运用办法例如:

plt.style.use('ggplot')
plt.plot([1,2,3,4],[2,3,4,5]);

款式比如1

用户自界说stylesheet

在恣意途径下创立一个后缀名为mplstyle的款式清单,编辑文件增加以下款式内容:

axes.titlesize : 24
axes.labelsize : 20
lines.linewidth : 3
lines.markersize : 10
xtick.labelsize : 16
ytick.labelsize : 16

引证自界说stylesheet后观察图表改变:

plt.style.use('style1.mplstyle')
plt.plot([1,2,3,4],[2,3,4,5]);

款式比如2

值得特别留意的是,matplotlib支持混合款式的引证,只需在引证时输入一个款式列表,若是几个款式中涉及到同一个参数,右边的款式表会掩盖左边的值:

plt.style.use(['dark_background', 'style1.mplstyle'])
plt.plot([1,2,3,4],[2,3,4,5]);

款式比如3

设置rcparams

还能够经过修正默许rc设置的办法改动款式,一切rc设置都保存在一个叫做 matplotlib.rcParams的变量中。修正过后再绘图,能够看到绘图款式发生了改变。

plt.style.use('default') # 恢复到默许款式
mpl.rcParams['lines.linewidth'] = 2
mpl.rcParams['lines.linestyle'] = '--'
plt.plot([1,2,3,4],[2,3,4,5]);

款式比如4

另外matplotlib也还供给了一种更快捷的修正款式办法,能够一次性修正多个款式。

mpl.rc('lines', linewidth=4, linestyle='-.')

matplotlib的色彩设置color

在matplotlib中,设置色彩有以下几种办法

RGB或许RGBA

plt.plot([1,2,3],[4,5,6],color=(0.1, 0.2, 0.5))
plt.plot([4,5,6],[1,2,3],color=(0.1, 0.2, 0.5, 0.5));

色彩用[0,1]之间的浮点数表明,四个分量按顺序别离为(red, green, blue, alpha),其间alpha通明度可省掉。

色彩样例1

HEX RGB或许RGBA

# 用十六进制色彩码表明,相同最后两位表明通明度,可省掉
plt.plot([1,2,3],[4,5,6],color='#0f0f0f')
plt.plot([4,5,6],[1,2,3],color='#0f0f0f80');

色彩样例2

灰度色阶

# 当只有一个坐落[0,1]的值时,表明灰度色阶
plt.plot([1,2,3],[4,5,6],color='0.5');

色彩杨丽3

单字符基本色彩

八个基本色彩能够用单个字符来表明,别离是’b’, ‘g’, ‘r’, ‘c’, ‘m’, ‘y’, ‘k’, ‘w’,对应的是blue, green, red, cyan, magenta, yellow, black, and white的英文缩写,设置color=’m’即可。

色彩称号

matplotlib供给了色彩对照表,可供查询色彩对应的称号

素材对照

用colormap设置一组色彩

具体能够阅读这篇文章。

x = np.random.randn(50)
y = np.random.randn(50)
plt.scatter(x,y,c=x,cmap='RdYlBu');

色彩4