python下Matplotlib绘图案例与常见设置简介

首先一幅Matplotlib的图像组成部分介绍。

基本构成

在matplotlib中,整个图像为一个Figure对象。在Figure对象中可以包含一个或者多个Axes对象。每个Axes(ax)对象都是一个拥有自己坐标系统的绘图区域。所属关系如下:

详解图像各个组件

下面以一个直线图来详解图像内部各个组件内容:

其中:title为图像标题,Axis为坐标轴, Label为坐标轴标注,Tick为刻度线,Tick Label为刻度注释。各个对象关系可以梳理成以下内容:

部分设置详解

图像中所有对象均来自于Artist的基类。 上面基本介绍清楚了图像中各个部分的基本关系,下面着重讲一下几个部分的详细的设置。 一个”Figure”意味着用户交互的整个窗口。在这个figure中容纳着”subplots”。 当我们调用plot时,matplotlib会调用gca()获取当前的axes绘图区域,而且gca反过来调用gcf()来获得当前的figure。如果figure为空,它会自动调用figure()生成一个figure, 严格的讲,是生成subplots(111)。

子图Subplots

注意:其中各个参数也可以用逗号,分隔开。第一个参数代表子图的行数;第二个参数代表该行图像的列数; 第三个参数代表每行的第几个图像。

plt.subplot(221) # 第一行的左图 plt.subplot(222) # 第一行的右图 plt.subplot(212) # 第二整行 plt.show()

参考案例直通车

另外:fig, ax = plt.subplots(2,2),其中参数分别代表子图的行数和列数,一共有 2x2 个图像。函数返回一个figure图像和一个子图ax的array列表。 补充:gridspec命令可以对子图区域划分提供更灵活的配置。

子图像统一标题设置

效果如下(subplot row i): 思路其实创建整个的子图像,然后将图像的刻度、标注等部分作不显示设置,仅仅显示图像的 title。

案例代码

import matplotlib.pyplot as plt

fig, big_axes = plt.subplots(figsize=(15.0, 15.0) , nrows=3, ncols=1, sharey=True) 

for row, big_ax in enumerate(big_axes, start=1):
    big_ax.set_title("Subplot row %s \n" % row, fontsize=16)

    # Turn off axis lines and ticks of the big subplot 
    # obs alpha is 0 in RGBA string!
    big_ax.tick_params(labelcolor=(0,0,0,0), top='off', bottom='off', left='off', right='off')
    # removes the white frame
    big_ax._frameon = False

for i in range(1,10):
    ax = fig.add_subplot(3,3,i)
    ax.set_title('Plot title ' + str(i))


fig.set_facecolor('w')
plt.tight_layout()
plt.show()    
刻度Tick Locators

Tick Locators 控制着 ticks 的位置。比如下面:

ax = plt.gca()
ax.xaxis.set_major_locator(eval(locator))

一些不同类型的locators:

案例代码:

import numpy as np
import matplotlib.pyplot as plt


def tickline():
plt.xlim(0, 10), plt.ylim(-1, 1), plt.yticks([])
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('none')
ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
ax.plot(np.arange(11), np.zeros(11))
return ax

locators = [
'plt.NullLocator()',
'plt.MultipleLocator(1.0)',
'plt.FixedLocator([0, 2, 8, 9, 10])',
'plt.IndexLocator(3, 1)',
'plt.LinearLocator(5)',
'plt.LogLocator(2, [1.0])',
'plt.AutoLocator()',
]

n_locators = len(locators)

size = 512, 40 * n_locators
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)


for i, locator in enumerate(locators):
plt.subplot(n_locators, 1, i + 1)
ax = tickline()
ax.xaxis.set_major_locator(eval(locator))
plt.text(5, 0.3, locator[3:], ha='center')

plt.subplots_adjust(bottom=.01, top=.99, left=.01, right=.99)
plt.show()

所有这些locators均来自于基类matplotlib.ticker.Locator。你可以通过继承该基类创建属于自己的locator样式。同时matplotlib也提供了特殊的日期locator, 位于matplotlib.date 基类matplotlib.ticker.Locator参考文献直通车

刻度和标注特殊设置

描述如下:在X轴标出一些重要的刻度点,当然实现方式有两种:直接在X轴上标注和通过注释annotate的形式标注在合适的位置。 其中第一种的实现并不是很合适,此处为了学习的目的一并说明下。

先说第一种:

正常X轴标注不会是这样的,为了说明此问题特意标注成这样,如此看来 0.3 和 0.4的标注重叠了,当然了解决重叠的问题可以通过改变figure 的size实现,显然此处并不想这样做。

怎么解决呢,那就在 0.3 和 0.4之间再设置一个刻度,有了空间后不显示即可。

代码如下:

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(3, 3))  
ax = fig.add_subplot(1, 1, 1, frameon=False)
ax.set_xlim(-0.015, 1.515)
ax.set_ylim(-0.01, 1.01)
ax.set_xticks([0, 0.3, 0.4, 1.0, 1.5])
#增加0.35处的刻度并不标注文本,然后重新标注0.3和0.4处文本
ax.set_xticklabels([0.0, "", "", 1.0, 1.5])
ax.set_xticks([0.35], minor=True)
ax.set_xticklabels(["0.3 0.4"], minor=True)

#上述设置只是增加空间,并不想看到刻度的标注,因此次刻度线不予显示。
for line in ax.xaxis.get_minorticklines():
line.set_visible(False)

ax.grid(True)
plt.show()

最终图像形式如下:

当然最合理的方式是采用注释的形式,比如:

案例代码如下:

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np

# Plot a sinc function
delta=2.0
x=np.linspace(-10,10,100)
y=np.sinc(x-delta)

# Mark delta
plt.axvline(delta,ls="--",color="r")
plt.annotate(r"$\delta$",xy=(delta+0.2,-0.2),color="r",size=15)
plt.plot(x,y)
增加X轴与Y轴间的间隔,向右移动X轴标注

显示效果对比:

设置前:

设置后:

上图代码如下:

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
plot_data=[1.7,1.7,1.7,1.54,1.52]
xdata = range(len(plot_data))
labels = ["2009-June","2009-Dec","2010-June","2010-Dec","2011-June"]
ax.plot(xdata,plot_data,"b-")
ax.set_xticks(range(len(labels)))
ax.set_xticklabels(labels)
ax.set_yticks([1.4,1.6,1.8])

# grow the y axis down by 0.05
ax.set_ylim(1.35, 1.8)
# expand the x axis by 0.5 at two ends
ax.set_xlim(-0.5, len(labels)-0.5)

plt.show()
移动刻度标注

上图说明需求:

通过设置 set_horizontalalignment()来控制标注的左右位置:

for tick in ax2.xaxis.get_majorticklabels():
    tick.set_horizontalalignment("left")

当然标注文本的上下位置也是可以控制的,比如:

ax2.xaxis.get_majorticklabels()[2].set_y(-.1)

当然控制刻度标注的上下位置也可以用labelpad参数进行设置:

pl.xlabel("...", labelpad=20) 
或:
ax.xaxis.labelpad = 20   

具体设置请查阅官方文档,完整的代码如下:

# -*- coding: utf-8 -*-

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

# my fake data
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)])
data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3

# creates fig with 2 subplots
fig = plt.figure(figsize=(10.0, 6.0))
ax = plt.subplot2grid((2,1), (0, 0))
ax2 = plt.subplot2grid((2,1), (1, 0))
## plot dates
ax2.plot_date( dates, data )

# rotates labels 
plt.setp( ax2.xaxis.get_majorticklabels(), rotation=-45 ) 

# shift labels to the right
for tick in ax2.xaxis.get_majorticklabels():
    tick.set_horizontalalignment("right")

plt.tight_layout()
plt.show()
调整图像边缘及图像间的空白间隔plt.tight_layout()

图像外部边缘的调整可以使用plt.tight_layout()进行自动控制,此方法不能够很好的控制图像间的间隔。 如果想同时控制图像外侧边缘以及图像间的空白区域,使用命令:

plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8,hspace=0.2, wspace=0.3)
图像的大小设置

如果已经存在figure对象,可以通过以下代码设置尺寸大小:

f.set_figheight(15)
f.set_figwidth(15)

若果通过.sublots()命令来创建新的figure对象, 可以通过设置figsize参数达到目的。

f, axs = plt.subplots(2,2,figsize=(15,15))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Petrichor的专栏

leetcode: 36. Valid Sudoku

19130
来自专栏人人都是极客

4.训练模型之准备训练数据

终于要开始训练识别熊猫的模型了, 第一步是准备好训练数据,这里有三件事情要做: 收集一定数量的熊猫图片。 将图片中的熊猫用矩形框标注出来。 将原始图片和标注文件...

51680
来自专栏GIS讲堂

postgis常用函数介绍(一)

在进行地理信息系统开发的过程中,常用的空间数据库有esri的sde,postgres的postgis以及mySQL的mysql gis等等,在本文,给大家介绍的...

39130
来自专栏Deep Learning 笔记

MNIST__数字识别__SOFTMAX

本次MNIST的手写数字识别未采用input_data.py文件,想尝试一下用原始的数据集来运行这个DEMO。

14810
来自专栏机器之心

入门 | GPU是如何优化运行机器学习算法的?

415140
来自专栏null的专栏

挑战数据结构和算法面试题——最大间隔

题目来自伯乐在线,欢迎有不同答案的同学来一起讨论。 ? 分析: 本题首先需要理解清楚最大间隔的最小: 最初的间隔为:[1,1,4,1],此时最大间隔为4 删...

32030
来自专栏ATYUN订阅号

Tensorflow 1.3.0版本的变更概述

尽管距离Tensoflow 1.2.1版本发布才仅仅一个月,但是1.3.0版本中的软件已经发生了很多变化。开发人员可以在Tensorflow的Github页面上...

37970
来自专栏desperate633

LintCode 爬楼梯题目分析代码小结

假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?

7420
来自专栏知识分享

当年参加飞思卡尔自己写的双线识别算法

原理 先找到一个白点A,然后向右找到黑点,记录黑点的位置,以当前黑点的竖坐标位置向上判断,上面的点是什么点,如果为黑点向左找白点,如果为白点向右找黑点(找到边界...

31070
来自专栏小樱的经验随笔

qsc oj 22 哗啦啦村的刁难(3)(随机数,神题)

哗啦啦村的刁难(3) 发布时间: 2017年2月28日 20:00   最后更新: 2017年2月28日 20:01   时间限制: 1000ms   内存限制...

29990

扫码关注云+社区

领取腾讯云代金券