MySQL backup and restore from Backups

Oct 11, 2016

We have to backup data regularly for the security reason. There are a bunch of methods to backup MySQL database, for some reason, the performance are not the same. Once the database crash or some fatal errors happen, backup is the only way to restore the data and reduce the loss to the minimum. Generally speaking, we have three backup solutions:

1, mysqldump + binary logs backup 2, LVM snapshot + binary logs backup 3, Xtrabackup

Lab environment:

System requirement: Ubuntu 16.06 server Database: Mysql 5.7

use mysqldump tool backup

### solution conception mysqldump is an logic backup tool, which means it will backup the data from database to a text file. In another word, it will store the table structure and data to a text file. The backup method is not difficult. First of all, mysqldump resolve the table’s structure. secondly, it will add a CREATE statement to the text file. The record in the table will be transfered to the insert statement for recovering. mysqldump advantages include the convenience and flexibility of viewing or even editing the output before restoring. Mysqldump is able to record the binary logs’ location and the content. This backup solution could be hot standby.

backup plan

mysqldump full backup(differential backup) and binary logs append backup

backup procedure

#### mysqldump full backup We need to add an read_only lock for the database before we start backup. So this backup is an warm standby.

#mysqldump -uroot -pmypass --lock-all-tables --master-data=2 --events --routines--all-databases > /backup/database_`date +%F`.sql

–lock-all-tables add the read_only lock for all tables. –master-data=2 mark the binary logs location at present –events Include Event Scheduler events for the dumped databases in the output. –routines Dump stored routines (procedures and functions) from dumped databases –all-databases backup all database.

here is the reference manual mysqldump — A Database Backup Program

# less database_2013-08-13.sql
-- #comment
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=14203; #present location is at binary log mysql-bin.000001, --master-data=2 procession
--
-- Current Database: `hellodb`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */;

binary logs full backup

first: add the data

mysql> use hellodb;
mysql> INSERT INTO students(Name,Age,Gender,ClassID,TeacherID) values ('Steve',22,'M',3,3);

second: binary log append backup

# mysqlbinlog --start-position=14203 --stop-position=14527 mysql-bin.000001 > /backup/binlog_`date +%F_%H`.sql

–start-position=14203 the last time backup log Position –stop-position=14527 today’s log Position

emulate data damaged. recovery all data.

mysql> DROP DATABASE hellodb; # delete DB
############ you have to implement at the offline ############
mysql> SET sql_log_bin=0; # shutdown binary logs
mysql> flush logs;
# mysql -uroot -pmypass < /zhao/database_2013-08-13.sql # restore backup file
# mysql -uroot -pmypass < /zhao/binlog_2013-08-13_19.sql # restore append backup file
# mysql -uroot –pmypass # check the  result
mysql> SET sql_log_bin=1;  # set the new backup Position

You have to rebuild all the indexes after this backup. and the backup file is large, so choose this solution as appropriate.

LVM snapshot backup

### solution conception 1, LVM requires the data of mysql database have to store on the logical volumes. 2, MySQL server have to be added read_only lock(mysql>FLUSH TABLES WITH READLOCK), you cannot quit server 3, Use another session create the snapshot for the volume which data located.

backup strategy

LVM snapshot full backup and binary logs append backup

precondition

#### create logical volumes and mount logical volumes

initialize mysql and redirect the data folder to /mydata/data

# cd /usr/local/mysql/
# scripts/mysql_install_db --user=mysql --datadir=/mydata/data

Edit and check the my.cnf file, reboot service

# vim /etc/my.cnf
datadir = /mydata/data
sync_binlog=1 # add this statement, Once the transaction is commited, the computer will move the logs from the cache to the logs file. and flush the new logs file to the driver.
# service mysqld start

Process running

#### Ensure transaction logs and data file have to locate in the same volume.

# ls /mydata/data/
hellodb myclass mysql-bin.000003 stu18.magedu.com.err
ibdata1 mysql mysql-bin.000004 stu18.magedu.com.pid
ib_logfile0 mysql-bin.000001 mysql-bin.index student
ib_logfile1 mysql-bin.000002 performance_schema test

the last two files are logs

Add the global lock and flush logs

mysql> FLUSH TABLES WITH READ LOCK;
mysql> FLUSH LOGS;

Check and save the binary log and the position of binary log at present(very important).

mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 | 187 | | |
+------------------+----------+--------------+------------------+
# mysql -uroot -pmypass -e 'SHOW MASTER STATUS;' >/zhao/lvmback-2013-08-14/binlog.txt

Create the snapshot volume.

# lvcreate -L 100M -s -p r -n mydata-lvm /dev/vg1/mydata

switch to another session to release the lock

mysql> UNLOCK TABLES;

Backup the data

# cp -a * /backup/lvmback-2013-08-14/

Create the append backup

mysql> use hellodb; # assign the default database
Database changed
mysql> CREATE TABLE testtb (id int,name CHAR(10)); # create table
Query OK, 0 rows affected (0.35 sec)
mysql> INSERT INTO testtb VALUES (1,'tom'); # add data
Query OK, 1 row affected (0.09 sec)
# mysqlbinlog --start-position=187 mysql-bin.000004 > /zhao/lvmlogbin_2013-08-14/binlog.sql # append backup

emulate database crashed

# service mysqld stop
# cd /mydata/data/
# rm -rf *

restore data

# cp /zhao/lvmback-2013-08-14/* /mydata/data/ -a # full backup restore
# cd /mydata/data/ # check the file
# chown -R mysql.mysql * # change the permission
# service mysqld start # start service
# mysql -uroot –pmypass
mysql> SHOW DATABASES;
mysql> SET sql_log_bin=0 # close the log
mysql> source /backup/lvmlogbin_2013-08-14/binlog.sql; # restore log
mysql> SHOW TABLES; # check the tables
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes |
| coc |
| courses |
| scores |
| students |
| teachers |
| testtb |
| toc |
+-------------------+
mysql> SET sql_log_bin=1; # open the log

This method use the closed hot standby backup, so it is fast for backup and restore data.

Xtrabackup

## advantages Hot standby, reliable full backup or portion backup, support append backup, time point restore. No read_only lock requirement, save hard drive space. Restore backup is faster. All of the advantages only implement at InnoDB engine. MyISAM still doesn’t support append backup.

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_file%';
+--------------------------+----------+
| Variable_name | Value |
+--------------------------+----------+
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
| innodb_file_per_table | ON |
+--------------------------+----------+

innodb_file_per_table on means innodb sets to the individual table. If it sets off, you have to use mysqldump to do full backup and modify the my.cnf file and initialize all system and restore the data. So I highly recommend you set it to 1 (innodb_file_per_table):

# ls
classes.frm coc.MYD courses.MYI scores.MYI teachers.frm testtb.ibd
classes.MYD coc.MYI db.opt students.frm teachers.MYD toc.frm
classes.MYI courses.frm scores.frm students.MYD teachers.MYI toc.MYD
coc.frm courses.MYD scores.MYD students.MYI testtb.frm toc.MYI

Install Xtrabackup

download the lastest Xtrabackup from here here is the installation manual

and then you have to install the perl-DBD-mysql dependent package.

sudo apt-get install perl-DBD-mysql

Full backup

Once you use innobackupex to backup your database, it will call xtrabackup to backup all of the InnoDB table automatically. Copy all of the table structure definition related file(.frm), MyISAM,MERGE,CSV and ARCHIVE table related files. In the same time, it still is able to backup the system configure files and trigger related files.all of the files will be saved at an folder named by the time.

# innobackupex --user=DBUSER--password=DBUSERPASS /path/to/BACKUP-DIR/

the processing is following:

# mkdir /innobackup
# innobackupex --user=root --password=mypass /innobackup/ #完全备份
################ if the backup is correct the following information will be shown up###############
xtrabackup: Transaction log of lsn (1604655) to (1604655) was copied. # logs pos(lsn)
130814 07:04:55 innobackupex: All tables unlocked
innobackupex: Backup created in directory '/innobackup/2013-08-14_07-04-49'# the location of backup
innobackupex: MySQL binlog position: filename 'mysql-bin.000003', position 538898
130814 07:04:55 innobackupex: Connection to database server closed
130814 07:04:55 innobackupex: completed OK!

switch to backup folder to check out the data and files:

# cd /innobackup/2013-08-14_07-04-49/
[2013-08-14_07-04-49]# ls
backup-my.cnf myclass student xtrabackup_binlog_info
hellodb mysql test xtrabackup_checkpoints
ibdata1 performance_schema xtrabackup_binary xtrabackup_logfile

xtrabackup_checkpoints: This file contains a line showing the to_lsn, which is the database’s LSN at the end of the backup. Create the full backup with a command such as the following:

xtrabackup --backup --target-dir=/data/backups/base --datadir=/var/lib/mysql/ # just an example from the official website

xtrabackup_binlog_info: the position and information of the binary logs

xtrabackup_binary: the executable binary file of backup

backup-my.cnf: mysql configuration backup file

xtrabackup_logfile: xtrabackup log file

standby a full backup

standby means rollback the unsubmitted transactions and synchronize the submitted transactions. we can use innobackupex –apply-log to do that:

# innobackupex -apply-log /innobackup/2013-08-14_07-04-49/

xtrabackup: starting shutdown with innodb_fast_shutdown = 1
130814 7:39:33 InnoDB: Starting shutdown...
130814 7:39:37 InnoDB: Shutdown completed; log sequence number 1606156
130814 07:39:37 innobackupex: completed OK!

emulate database crashed and restore the backup

1, emulate database crashed

[ ~]# service mysqld stop
[ ~]# cd /mydata/data/
[ data]# rm -rf *

2, restore the backup important: you cannot initialize database and service before recovery all data

[ ~]# innobackupex --copy-back /innobackup/2013-08-14_07-04-49/

innobackupex: Starting to copy InnoDB log files
innobackupex: in '/innobackup/2013-08-14_07-04-49'
innobackupex: back to original InnoDB log directory '/mydata/data'
innobackupex: Copying '/innobackup/2013-08-14_07-04-49/ib_logfile0' to '/mydata/data'
innobackupex: Copying '/innobackup/2013-08-14_07-04-49/ib_logfile1' to '/mydata/data'
innobackupex: Finished copying back files.
130814 07:58:22 innobackupex: completed OK!

3, You need to make sure all the data files belone to the correct group, and the user permissions are correct. Otherwise you have to modify the data files’ permission

# chown -R mysql:mysql /mydata/data/

4, start the service to check the recovery.

[data]# service mysqld start

Use innobackupex to append backup

Every InnoDB file includes an LSN information, every time the file is changed, LSN automatically increases. Let’s change the data first:

[ data]# innobackupex --user=root --password=mypass --incremental /innobackup --incremental-basedir=/innobackup/2013-08-14_08-14-12/

/innobackup is the full backup folder, after this command, innobackupex will create a new folder to store all the appended backup data named by the time.

change the data second time and backup:

[ ~]# innobackupex --user=root --password=mypass --incremental /innobackup --incremental-basedir=/innobackup/2013-08-14_08-29-05/

–incremental-basedir: the last time backup folder

change the data third time and without append backup:

mysql> delete from coc where id=14;

Use innobackupex to do full bakcup + append backup + binary logs restore backup

1, You’d better split the data folder and logs folder. Or if the system crashed you have to lose data and logs at the same time.

mkdir /mybinlog
chown mysql:mysql /mybinlog
vim /etc/my.cnf
log-bin=/mybinlog/mysql-bin

copy the binary logs:

[data]# cp mysql-bin.000001/innobackup/]

2, emulate the system crash

[ ~]# service mysqld stop
[ ~]# cd /mydata/data/
[ data]# rm -rf *

3, standby backup the committed transactions need to add to the full backup the uncommitted transactions need to rollback

[ ~]# innobackupex --apply-log --redo-only/innobackup/2013-08-14_08-14-12/

add the append backup to the full backup at the first time:

[~]# innobackupex --apply-log--redo-only /innobackup/2013-08-14_08-14-12/--incremental-dir=/innobackup/2013-08-14_08-29-05/

add the append backup to the full backup at the first time:

[~]# innobackupex --apply-log--redo-only /innobackup/2013-08-14_08-14-12/ --incremental-dir=/innobackup/2013-08-14_09-08-39/

–redo-only just synchronizes the committed transactions and doesn’t rollback the uncommitted transactions.

4, restore data

[ ~]# innobackupex --copy-back/innobackup/2013-08-14_08-14-12/

5, change the group

[ ~]# cd /mydata/data/
[ data]# chown -R mysql:mysql *

6, check the result

[ ~]# mysql -uroot -pmypas
mysql> select * from coc;
+----+---------+----------+
| ID | ClassID | CourseID |
+----+---------+----------+
| 1| 1 | 2 |
| 2| 1 | 5 |
| 3| 2 | 2 |
| 4| 2 | 6 |
| 5| 3 | 1 |
| 6| 3 | 7 |
| 7| 4 | 5 |
| 8| 4 | 2 |
| 9| 5 | 1 |
| 10 | 5 | 9 |
| 11 | 6 | 3 |
| 12 | 6 | 4 |
| 13 | 7 | 4 |
| 14 | 7 | 3 |
+----+---------+----------+
14 rows in set (0.00 sec)

we can see the third time modified information doesn’t implement.

7, restore data by binary logs check the last time backup logs

[ data]# cd /innobackup/2013-08-14_09-08-39/
[ 2013-08-14_09-08-39]# cat xtrabackup_binlog_info
mysql-bin.000001 780

export the data without backup logs

[ innobackup]# mysqlbinlog mysql-bin.000001
# at 780
#130814 9:20:19 server id 1 end_log_pos 851 Query thread_id=7 exec_time=0 error_code=0
SET TIMESTAMP=1376443219/*!*/;
BEGIN
/*!*/;
# at 851
#130814 9:20:19 server id 1 end_log_pos 944 Query thread_id=7 exec_time=0 error_code=0
SET TIMESTAMP=1376443219/*!*/;
delete from coc where id=14
/*!*/;
# at 944
#130814 9:20:19 server id 1 end_log_pos 1016 Query thread_id=7 exec_time=0 error_code=0
SET TIMESTAMP=1376443219/*!*/;
COMMIT
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[ innobackup]# mysqlbinlog --start-position=780 mysql-bin.000001 > ./all.sql # export data

restore data

[ ~]# mysql -uroot –pmypass
mysql> SET SQL_LOG_BIN=0; # shutdown binary logs file
mysql> source /innobackup/all.sql # import data
mysql> SET SQL_LOG_BIN=1; # start binary logs file
mysql> select * from coc;
+----+---------+----------+
| ID | ClassID | CourseID |
+----+---------+----------+
| 1 | 1 | 2 |
| 2 | 1 | 5 |
| 3 | 2 | 2 |
| 4 | 2 | 6 |
| 5 | 3 | 1 |
| 6 | 3 | 7 |
| 7 | 4 | 5 |
| 8 | 4 | 2 |
| 9 | 5 | 1 |
| 10 | 5 | 9 |
| 11 | 6 | 3 |
| 12 | 6 | 4 |
| 13 | 7 | 4 |
+----+---------+----------+
13 rows in set (0.00 sec)

we use hot backup on this backup plan. So I think it is the best way to backup mysql database.

Outcome:All of three backup solutions require binary logs, which means logs are so important for backup and system.

Matplotlib简明教程

Oct 11, 2016

今天我们开始matplotlib的学习,现在是凌晨00:00,我争取在4:00 之前写完

介绍

Matplotlib是一个非常强大的数据可视化工具,我们之前学习了NumPy和pandas 和 Scipy, Scipy和pandas有一些数据图形化的功能,但是功能很有限而且不美观,很难达到企业级别的要求。而Matplotlib完全满足了这种要求,他拥有以下几个优点:

容易使用 支持用户定义labels 对图表元素的高控性 高质量的输出图像 支持用户编辑

这篇教程只是介绍一些matplotlib的一些常用功能,如果想了解更多高级功能请访问官网: http://matplotlib.org/

安装

pip install matplotlib

下面我们需要import重要的 module

import matplotlib.pyplot as plt

基本操作

首先我们来画一个基本的plot。一个plot需要有x轴和y轴,我们用NumPy建立两个

import numpy as np
x = np.arange(0,5.5,0.5)
y = x ** 2
x
array([ 0. ,  0.5,  1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5,  5. ])
y
array([  0.  ,   0.25,   1.  ,   2.25,   4.  ,   6.25,   9.  ,  12.25,
        16.  ,  20.25,  25.  ])

建立x,y轴数据完成,我们可以用他们完成一个简单的plot

plt.plot(x, y, 'r') # 'r' 用红色线条
plt.xlabel('X Axis Title Here')
plt.ylabel('Y Axis Title Here')
plt.title('String Title Here')
plt.show() # 最后一定要用plt.show() 才能显示

png

添加多图表在一个plot中

# plt.subplot(nrows, ncols, plot_number)
plt.subplot(1,2,1)  # 建立一行二列的图表组,第三个参数代表第一个图表
plt.plot(x, y, 'r--') # 红色虚线,每个节点用 -
plt.subplot(1,2,2)  # 第三个参数代表第二个图表
plt.plot(y, x, 'g*-'); # 绿色实线,每个节点用 *

png

Matplotlib 面向对象方法

Matplotlib 有很多面向对象API,所以我们可以增加figure对象

面向对象方法介绍

我们可以吧figure看做一个对象,同过matplotlib添加。然后给figure设置各种属性。

# 建立一个空 Figure
fig = plt.figure()

# 添加 axes 到 figure
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 左,下,宽,高 (range 0 to 1)

# 使用
axes.plot(x, y, 'b')
axes.set_xlabel('Set X Label') # set方法
axes.set_ylabel('Set y Label')
axes.set_title('Set Title')
<matplotlib.text.Text at 0x111c85198>

png

下面我们添加复合图表,代码有点复杂,但是如果写起来会发现很容易控制

# Creates blank canvas
fig = plt.figure()

axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 主轴
axes2 = fig.add_axes([0.2, 0.5, 0.4, 0.3]) # 插入轴

# 大的主图
axes1.plot(x, y, 'b')
axes1.set_xlabel('X_label_axes2')
axes1.set_ylabel('Y_label_axes2')
axes1.set_title('Axes 2 Title')

# 小的附图
axes2.plot(y, x, 'r')
axes2.set_xlabel('X_label_axes2')
axes2.set_ylabel('Y_label_axes2')
axes2.set_title('Axes 2 Title');

png

subplots()

plt.subplots() 将扮演一个自动管理行列的角色

# 用subplots 将会自动添加axes进figure
fig, axes = plt.subplots()

# 一样的
axes.plot(x, y, 'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title('title');

png

下面我们重复添加多图表的过程

# Empty canvas of 1 by 2 subplots
fig, axes = plt.subplots(nrows=1, ncols=2)  # 一个fig 可以包含多个axes

png

# Axes 是一个array 当plot 建立时候
axes
array([<matplotlib.axes._subplots.AxesSubplot object at 0x111f0f8d0>,<matplotlib.axes._subplots.AxesSubplot object at 0x1121f5588>], dtype=object)

我们可以用循环遍历这个数组

for ax in axes:
    ax.plot(x, y, 'b')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title')

# Display the figure object    
fig

png

可以看出这样才是真正使用到了编程。通过循环建立两个图表 我们总结一下,首先设置了x轴和y轴所代表的变量,然后用plt.subplots() 方法建立图表模型,最后用循环来增加图表,这在实际生活中非常有用,比如需要分别打印一年12个月每个月的销售数据。

我们还可以用 fig.tight_layout() 或者 plt.tight_layout() 方法调整子图表的分布

fig, axes = plt.subplots(nrows=1, ncols=2)

for ax in axes:
    ax.plot(x, y, 'g')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('title')

fig    
plt.tight_layout()

__ png

图表的大小,横纵比例与像素

需要改变这三个 我们要了解两个重要的参数 figsize: 一个关于长宽的tuple dpi: dots-per-inch (pixel per inch).

fig = plt.figure(figsize=(8,4), dpi=100)
<matplotlib.figure.Figure at 0x11228ea58>

这两个参数可以运用在任何layout管理对象中,比如subplots

fig, axes = plt.subplots(figsize=(12,3))

axes.plot(x, y, 'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title('title');

png

保存图片

Matplotlib支持保存PNG, JPG, EPS, SVG, PGF 和 PDF格式的图片。例子如下:

fig.savefig("filename.png")

fig.savefig("filename.png", dpi=200)

图例,标签和标题

代码如下所示:

ax.set_title("title");

ax.set_xlabel("x")
ax.set_ylabel("y");

#### 图例

可以用 legend() 在一个图表中打印两条曲线

fig = plt.figure()

ax = fig.add_axes([0,0,1,1])

ax.plot(x, x**2, label="x**2")
ax.plot(x, x**3, label="x**3")
ax.legend()
<matplotlib.legend.Legend at 0x113a3d8d0>

png

loc 参数可以定义图例位置

# Lots of options....

ax.legend(loc=1) # upper right corner
ax.legend(loc=2) # upper left corner
ax.legend(loc=3) # lower left corner
ax.legend(loc=4) # lower right corner

# .. many more options are available

# Most common to choose
ax.legend(loc=0) # 让 matplotlib 自动决定最好的位置
fig

png

设置颜色,线条长宽,线条类型

颜色可以用字母表示,线条的话如下面代码所示:

# MATLAB style line color and style
fig, ax = plt.subplots()
ax.plot(x, x**2, 'b.-') # b 代表蓝色,后面是带点的线条
ax.plot(x, x**3, 'g--') # g 代表绿色,后面是代表虚线
[<matplotlib.lines.Line2D at 0x111fae048>]

png

这里有详细的说明: http://matplotlib.org/api/lines_api.html

还可以用RGB代码设置颜色

fig, ax = plt.subplots()

ax.plot(x, x+1, color="blue", alpha=0.5) # half-transparant
ax.plot(x, x+2, color="#8B008B")        # RGB hex code
ax.plot(x, x+3, color="#FF8C00")        # RGB hex code
[<matplotlib.lines.Line2D at 0x112179390>]

png

线条和标记风格

线条宽度我们可以用 linewidth 或者 lw 关键字, 线条风格我们可以用 linestyle 或者 ls 关键字

fig, ax = plt.subplots(figsize=(12,6))

ax.plot(x, x+1, color="red", linewidth=0.25)
ax.plot(x, x+2, color="red", linewidth=0.50)
ax.plot(x, x+3, color="red", linewidth=1.00)
ax.plot(x, x+4, color="red", linewidth=2.00)

# possible linestype options ‘-‘, ‘–’, ‘-.’, ‘:’, ‘steps’
ax.plot(x, x+5, color="green", lw=3, linestyle='-')
ax.plot(x, x+6, color="green", lw=3, ls='-.')
ax.plot(x, x+7, color="green", lw=3, ls=':')

# custom dash
line, = ax.plot(x, x+8, color="black", lw=1.50)
line.set_dashes([5, 10, 15, 10]) # format: line length, space length, ...

# possible marker symbols: marker = '+', 'o', '*', 's', ',', '.', '1', '2', '3', '4', ...
ax.plot(x, x+ 9, color="blue", lw=3, ls='-', marker='+')
ax.plot(x, x+10, color="blue", lw=3, ls='--', marker='o')
ax.plot(x, x+11, color="blue", lw=3, ls='-', marker='s')
ax.plot(x, x+12, color="blue", lw=3, ls='--', marker='1')

# marker size and color
ax.plot(x, x+13, color="purple", lw=1, ls='-', marker='o', markersize=2)
ax.plot(x, x+14, color="purple", lw=1, ls='-', marker='o', markersize=4)
ax.plot(x, x+15, color="purple", lw=1, ls='-', marker='o', markersize=8, markerfacecolor="red")
ax.plot(x, x+16, color="purple", lw=1, ls='-', marker='s', markersize=8,
        markerfacecolor="yellow", markeredgewidth=3, markeredgecolor="green");

png

控制轴的外观

这里讨论如何控制轴的尺寸和外观

绘图范围

我们可以用set_ylim 和 set_xlim 来控制图表的范围,或者直接用axis(‘tight’)来自动将图表紧凑起来

fig, axes = plt.subplots(1, 3, figsize=(12, 4))

axes[0].plot(x, x**2, x, x**3)
axes[0].set_title("default axes ranges")

axes[1].plot(x, x**2, x, x**3)
axes[1].axis('tight')
axes[1].set_title("tight axes")

axes[2].plot(x, x**2, x, x**3)
axes[2].set_ylim([0, 60])
axes[2].set_xlim([2, 5])
axes[2].set_title("custom axes range");

png

特别绘图类型

下面介绍几种特别的绘图类型,有时候也需要用到

plt.scatter(x,y)
<matplotlib.collections.PathCollection at 0x1122be438>

png

from random import sample
data = sample(range(1, 1000), 100)  
plt.hist(data)   # 这个以后将会经常用到
(array([ 14.,  11.,   9.,  12.,   6.,   7.,  13.,  13.,   6.,   9.]),
 array([  28. ,  123.5,  219. ,  314.5,  410. ,  505.5,  601. ,  696.5,
         792. ,  887.5,  983. ]),
 <a list of 10 Patch objects>)

png

data = [np.random.normal(0, std, 100) for std in range(1, 4)]

# rectangular box plot
plt.boxplot(data,vert=True,patch_artist=True);   

png

最后介绍几个很好的matplotlib的学习资源,对大家很有帮助:

  • http://www.matplotlib.org - matplotlib 的官方网站
  • https://github.com/matplotlib/matplotlib - matplotlib 源码
  • http://matplotlib.org/gallery.html - 所有的图示案例,很重要!!!
  • http://www.loria.fr/~rougier/teaching/matplotlib - 一个很好的matpplotlib的教程
  • http://scipy-lectures.github.io/matplotlib/matplotlib.html - 另一个很好的参考