In [1]:
%matplotlib inline
from pandas import Series, DataFrame
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
#import seaborn as sns #即使不适用seaborn内的功能,也可以使绘图自动带有seaborn风格
In [2]:
# df = pd.read_excel('https://github.com/liupengyuan/python_tutorial/blob/master/chapter4/countrys_freq.xlsx?raw=true')
df = pd.read_excel('countrys_freq.xlsx')
df
Out[2]:
In [3]:
df.plot()
Out[3]:
In [4]:
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体 plt.rcParams['font.sans-serif'] = ['FangSong'] 前者为全局影响,后者影响当前
# mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题 plt.rcParams['axes.unicode_minus'] = False
In [5]:
df.plot()
Out[5]:
In [6]:
df.index.name = '时间'
df.columns.name = '国家'
df.plot()
Out[6]:
In [7]:
df.plot(title = '十年来美国日本德国出现频次对比',figsize=(8,6))
Out[7]:
In [8]:
plt.style.available
Out[8]:
利用plt.style.available,查看目前可用的风格类型
In [9]:
# plt.style.use("ggplot")
使用ggplot风格
In [10]:
df.plot(title = '十年来美国日本德国出现频次对比',figsize=(8,6))
Out[10]:
将pandas绘图与matplotlib绘图结合可以很方便的定制可视化实例。这里先介绍matplotlib基础
Matplotlib is an excellent 2D and 3D graphics library for generating scientific figures.
仅介绍matplotblib最基础的使用,matplotlib绘图的进一步详细使用,可参考官方网站文档,特别是http://matplotlib.org/users/pyplot_tutorial.html
In [11]:
from IPython.core.display import Image, display
display(Image(filename='figures/anatomy1.png', width=800))
1. 概念与布局
In [12]:
x = np.linspace(0, 5, 10)
y = x ** 2
数据
In [13]:
# 创建一个图形画布
fig = plt.figure(figsize = (6,4), dpi=100)
# 创建一个坐标轴(axes)并设置图形大小比例
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 坐标轴图形大小:左,下,右(宽),上(高) (0到1,表示比例位置)
In [14]:
fig = plt.figure()
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8])
axes.plot(x, y, 'r')
Out[14]:
In [15]:
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, 'r')
# 第二个坐标轴下作图
axes2.plot(y, x, 'g')
Out[15]:
In [16]:
fig = plt.figure(figsize=(8,6))
ax1 = fig.add_subplot(2,2,1)
ax1.plot(x,y,'r')
ax2 = fig.add_subplot(2,2,2)
ax2.plot(y,x,'b')
ax3 = fig.add_subplot(2,2,3)
ax3.plot(x,y,'k')
ax4 = fig.add_subplot(2,2,4)
ax4.plot(y,x,'g')
Out[16]:
In [17]:
fig, axes = plt.subplots(nrows=2, ncols=2) # axes 是ndarray类型 里面是2*2个axes对象
print('axes type is{}, shape is {}.'.format(type(axes), axes.shape))
for ax in axes.flatten()[:3]:
ax.plot(x, y, 'r')
axes[1][1].plot(x, y, 'g')
Out[17]:
In [18]:
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2) # axes 是ndarray类型 里面是2*2个axes对象
ax1.plot(x, y, 'r')
ax2.plot(x, y, 'g')
ax3.plot(x, y, 'b')
ax4.plot(x, y, 'y')
Out[18]:
也可以按照数组元素的顺序,依次取出
In [19]:
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flatten()[:3]:
ax.plot(x, y, 'r')
axes[1][1].plot(x, y, 'g')
fig.tight_layout()
用figure对象的tight_layout()方法可解决轴有重叠的问题,这个方法会自动地调节图形的位置
In [20]:
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(223)
ax3 = fig.add_subplot(1,2,2)
ax1.plot(x, x**2, 'r')
ax2.plot(x, x**2, 'g')
ax3.plot(x, x**2, 'b')
plt.tight_layout()
2. 图例、标签及标题(Legends, labels and titles)
In [21]:
fig, ax = plt.subplots()
ax.plot(x,x**2)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('title')
# ax.set(xlabel='xx', ylabel='yy', title='title'); #与上面三个等价
Out[21]:
利用set_xlabel(), ax.set_ylabel(), ax.set_title()这三个函数来设置x轴标签,y轴标签,图表抬头(标题)
In [22]:
fig, ax = plt.subplots()
ax.plot(x, x**2)
ax.plot(x, x**3)
ax.legend(('curve1', 'curve2'))
ax.set(xlabel='xx', ylabel='yy', title='title');
利用legend()函数,由一个列表或元组,将图例文字传入
In [23]:
fig, ax = plt.subplots()
ax.plot(x, x**2, label="curve1")
ax.plot(x, x**3, label="curve2")
ax.legend(loc=5)
ax.set(xlabel='xx', ylabel='yy', title='title');
3. 字体
In [24]:
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong']
如果要显示汉字,则与前一样需要设置全局参数中的字体
In [25]:
fig, ax = plt.subplots()
ax.plot(x, x**2, label="线1")
ax.plot(x, x**3, label="线2")
ax.legend(loc=5)
ax.set(xlabel='x轴', ylabel='y轴', title='标题');
显示中文与之前的设置一样(windows平台)
In [26]:
fig, ax = plt.subplots()
ax.plot(x, x**2, label=r"$y = \alpha^2$")
ax.plot(x, x**3, label=r"$y = \alpha^3$")
ax.legend()
ax.set_xlabel(r'$\alpha$', fontsize=18)
ax.set_ylabel(r'$y$', fontsize=18)
ax.set_title(r"$\alpha^2$");
In [27]:
# Update the matplotlib configuration parameters:
plt.rcParams.update({'font.size': 16, 'font.family': 'serif'})
更新字体设置
In [28]:
fig, ax = plt.subplots()
ax.plot(x, x**2, label=r"$y = \alpha^2$")
ax.plot(x, x**3, label=r"$y = \alpha^3$")
ax.legend(loc=2) # upper left corner
ax.set_xlabel(r'$\alpha$')
ax.set_ylabel(r'$y$')
ax.set_title('title', fontsize = 20);
全局设置下,仍然可以对各个标签等字体进行单独设置
4. 颜色,线型(linetypes),线宽(linewidths)
In [29]:
fig, ax = plt.subplots()
ax.plot(x, x**2, color = 'blue') # blue line
ax.plot(x, x**3, 'g') # green line
Out[29]:
In [30]:
fig, ax = plt.subplots()
ax.plot(x, x+1, color="red", alpha=0.5) # 红色,半透明
ax.plot(x, x+2, color="#1155dd") # RGB值,对应红绿蓝,dd最大,因此颜色偏蓝
line = ax.plot(x, x+3, color="#15cc55") # 偏绿
In [31]:
fig, ax = plt.subplots(figsize=(12,6))
# 线宽
ax.plot(x, x+1, color="blue", linewidth=0.25)
ax.plot(x, x+2, color="blue", linewidth=0.50)
ax.plot(x, x+3, color="blue", linewidth=1.00)
ax.plot(x, x+4, color="blue", linewidth=2.00)
# 线型 ‘-‘, ‘--’, ‘-.’, ‘:’, ‘steps’
ax.plot(x, x+5, color="red", lw=2, linestyle='-')
ax.plot(x, x+6, color="red", lw=2, ls='-.')
ax.plot(x, x+7, color="red", lw=2, ls=':')
ax.plot(x, x+8, "r", lw=2, ls='steps')
Out[31]:
参数:linewidth, linestyle,可以简写为:lw, ls。用于设置线宽及线型
In [32]:
fig, ax = plt.subplots(figsize=(12,6))
# 标记符号: marker = '+', 'o', '*', 's', ',', '.', '1', '2', '3', '4', ...
ax.plot(x, x+ 9, color="green", lw=2, ls='--', marker='+')
ax.plot(x, x+10, color="green", lw=2, ls='--', marker='o')
ax.plot(x, x+11, color="green", lw=2, ls='--', marker='s')
ax.plot(x, x+12, color="green", lw=2, ls='--', marker='*')
# 标记符号
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=2, markeredgecolor="blue");
In [33]:
fig, ax = plt.subplots(figsize=(12,6))
line = ax.plot(x, x+1, color="black", lw=1.50)
print(type(line), len(line))
line[0].set_dashes([5, 10, 100, 10]) # 格式: 线长度,空白长度,线长度,空白长度...
还可以利用set_dashes()函数,设置dashes线的具体形式
5. 控制坐标轴(axis)
In [34]:
plt.rcParams.update({'font.size': 16, 'font.family': 'FangSong'})
In [35]:
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
axes[0].plot(x, x**2, x, x**3)
axes[0].set_title("缺省坐标轴(axes)范围")
axes[1].plot(x, x**2, x, x**3)
axes[1].axis('tight')
axes[1].set_title("紧致坐标轴范围")
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("定制坐标轴范围");
In [36]:
fig, axes = plt.subplots(1, 2, figsize=(10,4))
axes[0].plot(x, x**2,'r', x, np.exp(x), 'g')
axes[0].set_title("正常比例")
axes[1].plot(x, x**2, 'r', x, np.exp(x), 'g')
axes[1].set_yscale("log")
axes[1].set_title("对数比例 (y)");
In [37]:
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(x, x**2, x, x**3, lw=2)
#设置x轴记号(tick)位置
ax.set_xticks([1, 2.5, 3, 4, 5])
#每个记号标签
ax.set_xticklabels([r'$\alpha$', r'$\beta$', r'$\gamma$', r'$\delta$', '终点'], fontsize=18)
#设置y轴记号(tick)位置
yticks = [0, 50, 100, 150]
ax.set_yticks(yticks)
ax.set_yticklabels(["${:.1f}$".format(y) for y in yticks], fontsize=18);
In [38]:
fig, ax = plt.subplots(1, 1)
ax.plot(x, x**2, x, np.exp(x))
# 标签与坐标数字之间的距离
ax.xaxis.labelpad = 30
ax.yaxis.labelpad = 30
ax.set_xlabel("x")
ax.set_ylabel("y")
# 坐标轴与坐标数字之间的距离设置,并不常用,缺省为3
# plt.rcParams['xtick.major.pad'] = 15
# plt.rcParams['ytick.major.pad'] = 15
Out[38]:
In [39]:
fig, ax = plt.subplots()
ax.plot(x, x**2, lw=2, color="blue")
ax.set_ylabel(r"area $(m^2)$", fontsize=18, color="blue")
for label in ax.get_yticklabels():
label.set_color("blue")
In [40]:
fig, axes = plt.subplots(1, 2, figsize=(10,3))
#设置网格
axes[0].plot(x, x**2, x, x**3, lw=2)
axes[0].grid() #grid(True)
#对网格进行定制
axes[1].plot(x, x**2, x, x**3, lw=2)
axes[1].grid(color='b', alpha=0.5, linestyle='--', linewidth=0.5)
In [41]:
fig, ax1 = plt.subplots()
ax1.plot(x, x**2, lw=2, color="blue")
ax1.set_ylabel(r"area $(m^2)$", fontsize=18, color="blue")
for label in ax1.get_yticklabels():
label.set_color("blue")
ax2 = ax1.twinx()
ax2.plot(x, x**3, lw=2, color="red")
ax2.set_ylabel(r"volume $(m^3)$", fontsize=18, color="red")
for label in ax2.get_yticklabels():
label.set_color("red")
In [42]:
fig, ax = plt.subplots()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('b')
ax.spines['left'].set_linewidth(2)
ax.plot(x,x**2,'g')
Out[42]:
In [43]:
mpl.rcParams['axes.unicode_minus'] = False
解决图像中负号'-'有时显示或保存为方块的问题
In [44]:
fig, ax = plt.subplots()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('top')
ax.spines['bottom'].set_position(('data',0)) # set position of x spine to x=0
ax.yaxis.set_ticks_position('right')
ax.spines['left'].set_position(('data',0)) # set position of y spine to y=0
xx = np.linspace(-0.75, 1., 100)
ax.plot(xx, xx**3);
6. 其他
In [45]:
fig, ax = plt.subplots()
ax.plot(xx, xx**2, xx, xx**3)
ax.text(x=0.15, y=0.2, s=r"$y=x^2$", fontsize=20, color="blue")
ax.text(0.65, 0.1, r"$y=x^3$", fontsize=20, color="green");
In [46]:
n = np.array([0,1,2,3,4,5])
t = np.linspace(0, 2 * np.pi, 100)
In [47]:
fig = plt.figure(figsize = (12,3))
ax0 = fig.add_subplot(1,4,1)
ax0.scatter(xx, xx + 0.25*np.random.randn(len(xx)))
ax0.set_title("scatter")
ax1 = fig.add_subplot(1,4,2)
ax1.step(n, n**2, lw=2)
ax1.set_title("step")
# axes[2].bar(n, n**2, align="center", width=0.5, alpha=0.5)
# axes[2].set_title("bar")
ax2 = fig.add_subplot(1,4,3)
ax2.fill_between(x, x**2, x**3, color="green", alpha=0.5)
ax2.set_title("fill_between")
ax3 = fig.add_subplot(1,4,4, polar = True)
ax3.plot(t, t, color='blue', lw=3)
ax3.set_title("polar", loc='left')
plt.tight_layout()
还可以绘制各种图形
In [48]:
fig.savefig("test.png")
fig.savefig('test.pdf')
In [49]:
fig.savefig("test.png", dpi = 300)
In [50]:
df
Out[50]:
In [51]:
x = np.arange(5)
fig = plt.figure(figsize = (10,8))
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(223)
ax3 = fig.add_subplot(224)
df.plot(ax = ax1)
df.iloc[:5].plot(ax = ax2, ls='--')
ax3.plot(x, x**2, 'g')
plt.tight_layout()