1. 画曲线图html
前面依然使用plt句柄,只是最后获取当前图像python
2. 画柱状图api
3. 转载的一个教程: 点击打开连接数组
漂亮插图demosvg
首先一幅Matplotlib
的图像组成部分介绍。函数
在matplotlib中,整个图像
为一个Figure
对象。在Figure对象中能够包含一个或者多个Axes
对象。每一个Axes(ax)对象都是一个拥有本身坐标系统的绘图区域。所属关系以下:oop
下面以一个直线图来详解图像内部各个组件内容:post
其中:title为图像标题,Axis为坐标轴, Label为坐标轴标注,Tick为刻度线,Tick Label为刻度注释。各个对象关系能够梳理成如下内容:
图像中全部对象均来自于Artist
的基类。
上面基本介绍清楚了图像中各个部分的基本关系,下面着重讲一下几个部分的详细的设置。
一个"Figure"意味着用户交互的整个窗口。在这个figure中容纳着"subplots"。
当咱们调用plot时,matplotlib会调用gca()
获取当前的axes绘图区域,并且gca
反过来调用gcf()
来得到当前的figure。若是figure为空,它会自动调用figure()
生成一个figure, 严格的讲,是生成subplots(111)
。
Figures
Subplots
plt.subplot(221) # 第一行的左图 plt.subplot(222) # 第一行的右图 plt.subplot(212) # 第二整行 plt.show()
注意:其中各个参数也能够用逗号,
分隔开。第一个参数表明子图的行数;第二个参数表明该行图像的列数; 第三个参数表明每行的第几个图像。
另外:fig, ax = plt.subplots(2,2)
,其中参数分别表明子图的行数和列数,一共有 2x2 个图像。函数返回一个figure图像和一个子图ax的array列表。
补充:gridspec命令能够对子图区域划分提供更灵活的配置。
这是因为matplotlib文件夹内没有中文字体包致使的,实际上函数包自己是支持中文的,常看法决方案是拷贝字体文件到matplotlib中,不过我感受太麻烦,找到了另外的方式,
1
2
3
4
|
from
pylab
import
mpl
mpl.rcParams[
'font.sans-serif'
]
=
[
'FangSong'
]
# 指定默认字体
mpl.rcParams[
'axes.unicode_minus'
]
=
False
# 解决保存图像是负号'-'显示为方块的问题
|
加上这三行代码指定一下字体就好了(实际上最后一行能够不加)
1.axes列表中包含各个子图句柄
1
2
3
4
5
6
7
|
# 3x3子图
fig, axes
=
plt.subplots(
3
,
3
)
# 子图间距设定
fig.subplots_adjust(hspace
=
0.3
, wspace
=
0.3
)
# 在分别绘制各个子图
for
i, ax
in
enumerate
(axes.flat):
pass
|
2.每一个子图句柄须要单独生成
1
2
3
4
5
6
7
8
|
# 画布
fig
=
plt.figure()
# 添加子图
ax
=
fig.add_subplot(
211
)
pass
# 添加子图
ax2
=
fig.add_subplot(
212
)
pass
|
3.使用plt包命名空间代指多个子图句柄
【注】这种方法的句柄含在plt中,与上面的ax的方法属性并不相同,下面会详解
1
2
3
4
5
6
7
8
9
|
# 添加子图
plt.subplot(
311
)
pass
# 添加子图
plt.subplot(
312
)
pass
# 添加子图
plt.subplot(
313
)
pass
|
【注】使用ax代指子图方法一、2的句柄,plt代指方法3中的命名空间。坐标生成:
1
2
3
4
5
6
|
# 一维坐标生成
x
=
np.linspace(
0
,
10
,
100
)
# 二维网格生成
u
=
np.linspace(
-
1
,
1
,
100
)
x,y
=
np.meshgrid(u,u)
|
坐标轴标签:
1
2
3
4
5
6
7
8
|
xlabel
=
"True: {0}, Pred: {1}"
.
format
(cls_true[i], cls_pred[i])
xlabel
=
"y"
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
plt.xlabel(
'x'
)
plt.ylabel(
'y'
)
|
坐标轴刻度:
1
2
3
4
5
|
ax.set_xticks([])
ax.set_yticks([])
plt.xticks(
range
(
len
(x)), [
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
])
plt.yticks(
range
(
1
,
8
,
2
))
|
坐标网格:
1
2
3
4
5
6
7
|
# 横纵坐标单位长度统一
plt.axis(
'equal'
)
# 网格
plt.grid(
True
)
# 网格
ax.grid(
True
)
|
图表标题:
1
|
plt.title(
'Second Derivative'
)
|
对数坐标:
1
2
3
4
5
|
'''对数坐标'''
plt.semilogx(x,y)
# 对x取对数
plt.semilogy(x,y)
# 对y取对数
plt.loglog(x,y)
# 同时取对数
|
绘图:
1
2
3
4
5
6
7
8
9
10
|
# 色彩填充
ax.fill(x,y1,facecolor
=
'g'
,alpha
=
0.3
)
ax.fill_between(x,y,y1,facecolor
=
'b'
)
# 等高线
ax.contourf(x,y,z)
# 显示数组,由于是数组因此才会有vmin和vmax的关键字
ax.imshow()
# 线性绘图
plt.plot(x,y1,c
=
'b'
,linestyle
=
'
',marker='
^')
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import
matplotlib.pyplot as plt
plt.figure(figsize
=
(
12
,
9
))
labels
=
[
'part1'
,
'part2'
,
'part3'
]
# 各个饼的比例
sizes
=
[
30
,
20
,
50
]
colors
=
[
'yellowgreen'
,
'gold'
,
'lightskyblue'
]
# 各个模块离圆心的距离,参数为距离
explode
=
(
0.05
,
0.0
,
0.0
)
# 图 label的text 比例的text
patches, l_texts, p_texts
=
plt.pie(sizes, explode
=
explode, labels
=
labels, colors
=
colors, labeldistance
=
0.8
,
autopct
=
'%3.1f%%'
, shadow
=
True
, startangle
=
90
, pctdistance
=
0.6
)
# 设置x,y轴刻度一致,这样饼图才能是圆的
plt.axis(
'equal'
)
plt.legend()
# 设置label的字体大小
for
t
in
l_texts:
t.set_size(
20
)
# 设置比例数字的字体大小
for
t
in
p_texts:
t.set_size(
20
)
plt.show()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
import
numpy as np
from
matplotlib
import
pyplot as plt
plt.figure(figsize
=
(
9
,
6
))
n
=
12
X
=
np.arange(n)
+
1
# numpy.random.uniform(low=0.0, high=1.0, size=None), normal
Y1
=
(
1
-
X
/
float
(n
+
1
))
*
np.random.uniform(
0.5
,
1.0
,n)
Y2
=
(
1
-
X
/
float
(n
+
1
))
*
np.random.uniform(
0.5
,
1.0
,n)
# bar and barh
width
=
0.35
plt.bar(X, Y1, width
=
width, facecolor
=
'#9999ff'
, edgecolor
=
'white'
)
plt.bar(X
+
width, Y2, width
=
width, facecolor
=
'#ff9999'
, edgecolor
=
'white'
)
plt.bar(X,
-
Y2, width
=
width, facecolor
=
'#ff9999'
, edgecolor
=
'white'
)
# 柱状图添加说明文字
for
x,y
in
zip
(X,Y1):
plt.text(x, y
+
0.05
,
'%.2f'
%
y, ha
=
'center'
, va
=
'bottom'
)
for
x,y
in
zip
(X,
-
Y2):
plt.text(x
+
0.4
, y
-
0.15
,
'%.2f'
%
y, ha
=
'center'
, va
=
'bottom'
)
#plt.ylim(-1.25,+1.25)
plt.show()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
numpy as np
from
matplotlib
import
pyplot as plt
plt.figure(figsize
=
(
9
,
6
))
n
=
12
X
=
np.arange(n)
+
1
# numpy.random.uniform(low=0.0, high=1.0, size=None), normal
Y1
=
(
1
-
X
/
float
(n
+
1
))
*
np.random.uniform(
0.5
,
1.0
,n)
Y2
=
(
1
-
X
/
float
(n
+
1
))
*
np.random.uniform(
0.5
,
1.0
,n)
# bar and barh
width
=
0.35
# 方法barh和参数height能够实现横向的柱状图
plt.barh(X, Y1, height
=
width, facecolor
=
'#9999ff'
, edgecolor
=
'white'
)
plt.show()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from
matplotlib
import
pyplot as plt
import
numpy as np
mu
=
0
sigma
=
1
x
=
mu
+
sigma
*
np.random.randn(
10000
)
fig,(ax0,ax1)
=
plt.subplots(ncols
=
2
, figsize
=
(
9
,
6
))
ax0.hist(x,
20
, normed
=
1
, histtype
=
'bar'
, facecolor
=
'g'
, rwidth
=
0.8
, alpha
=
0.75
)
ax0.set_title(
'pdf'
)
# 累积几率密度分布
ax1.hist(x,
20
, normed
=
1
, histtype
=
'bar'
, rwidth
=
0.8
, cumulative
=
True
)
ax1.set_title(
'cdf'
)
plt.show()
|
atan2(a,b)是4象限反正切,它的取值不只取决于正切值a/b,还取决于点 (b, a) 落入哪一个象限: 当点(b, a) 落入第一象限时,atan2(a,b)的范围是 0 ~ pi/2; 当点(b, a) 落入第二象限时,atan2(a,b)的范围是 pi/2 ~ pi; 当点(b, a) 落入第三象限时,atan2(a,b)的范围是 -pi~-pi/2; 当点(b, a) 落入第四象限时,atan2(a,b)的范围是 -pi/2~0
而 atan(a/b) 仅仅根据正切值为a/b求出对应的角度 (能够看做仅仅是2象限反正切): 当 a/b > 0 时,atan(a/b)取值范围是 0 ~ pi/2; 当 a/b < 0 时,atan(a/b)取值范围是 -pi/2~0
故 atan2(a,b) = atan(a/b) 仅仅发生在 点 (b, a) 落入第一象限 (b>0, a>0)或 第四象限(b>0, a0 , 故 atan(a/b) 取值范围是 0 ~ pi/2,2atan(a/b) 的取值范围是 0 ~ pi,而此时atan2(a,b)的范围是 -pi~-pi/2,很显然,atan2(a,b) = 2atan(a/b)
举个最简单的例子,a = 1, b = -1,则 atan(a/b) = atan(-1) = -pi/4, 而 atan2(a,b) = 3*pi/4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
from
matplotlib
import
pyplot as plt
import
numpy as np
plt.figure(figsize
=
(
9
,
6
))
n
=
1024
# 均匀分布 高斯分布
# rand 和 randn
X
=
np.random.rand(
1
,n)
Y
=
np.random.rand(
1
,n)
# 设定颜色
T
=
np.arctan2(Y,X)
plt.scatter(X,Y, s
=
75
, c
=
T, alpha
=
.
4
, marker
=
'o'
)
#plt.xlim(-1.5,1.5), plt.xticks([])
#plt.ylim(-1.5,1.5), plt.yticks([])
plt.show()
|
# 定义子图区域
left, width = 0.1, 0.65
bottom, height = 0.1, 0.65
bottom_h = left_h = left + width + 0.02
rect_scatter = [left, bottom, width, height]
rect_histx = [left, bottom_h, width, 0.2]
rect_histy = [left_h, bottom, 0.2, height]
plt.figure(1, figsize=(6, 6))# 须要传入[左边起始位置,下边起始位置,宽,高]
# 根据子图区域来生成子图
axScatter = plt.axes(rect_scatter)
axHistx = plt.axes(rect_histx)
axHisty = plt.axes(rect_histy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# ref : http://matplotlib.org/examples/pylab_examples/scatter_hist.html
import
numpy as np
import
matplotlib.pyplot as plt
# the random data
x
=
np.random.randn(
1000
)
y
=
np.random.randn(
1000
)
# 定义子图区域
left, width
=
0.1
,
0.65
bottom, height
=
0.1
,
0.65
bottom_h
=
left_h
=
left
+
width
+
0.02
rect_scatter
=
[left, bottom, width, height]
rect_histx
=
[left, bottom_h, width,
0.2
]
rect_histy
=
[left_h, bottom,
0.2
, height]
plt.figure(
1
, figsize
=
(
6
,
6
))
# 根据子图区域来生成子图
axScatter
=
plt.axes(rect_scatter)
axHistx
=
plt.axes(rect_histx)
axHisty
=
plt.axes(rect_histy)
# no labels
#axHistx.xaxis.set_ticks([])
#axHisty.yaxis.set_ticks([])
# now determine nice limits by hand:
N_bins
=
20
xymax
=
np.
max
([np.
max
(np.fabs(x)), np.
max
(np.fabs(y))])
binwidth
=
xymax
/
N_bins
lim
=
(
int
(xymax
/
binwidth)
+
1
)
*
binwidth
nlim
=
-
lim
# 画散点图,几率分布图
axScatter.scatter(x, y)
axScatter.set_xlim((nlim, lim))
axScatter.set_ylim((nlim, lim))
bins
=
np.arange(nlim, lim
+
binwidth, binwidth)
axHistx.hist(x, bins
=
bins)
axHisty.hist(y, bins
=
bins, orientation
=
'horizontal'
)
# 共享刻度
axHistx.set_xlim(axScatter.get_xlim())
axHisty.set_ylim(axScatter.get_ylim())
plt.show()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import
numpy as np
import
matplotlib.pyplot as plt
fig
=
plt.figure(figsize
=
(
9
,
6
),facecolor
=
'white'
)
# Number of ring
n
=
50
size_min
=
50
size_max
=
50
*
50
# Ring position
P
=
np.random.rand(n,
2
)
# Ring colors R,G,B,A
C
=
np.ones((n,
4
))
*
(
0.5
,
0.5
,
0
,
1
)
# Alpha color channel goes from 0 (transparent) to 1 (opaque),很厉害的实现
C[:,
3
]
=
np.linspace(
0
,
1
,n)
# Ring sizes
S
=
np.linspace(size_min, size_max, n)
# Scatter plot
plt.scatter(P[:,
0
], P[:,
1
], s
=
S, lw
=
0.5
,
edgecolors
=
C, facecolors
=
C)
plt.xlim(
0
,
1
), plt.xticks([])
plt.ylim(
0
,
1
), plt.yticks([])
plt.show()
|
1
2
3
4
5
6
7
8
|
# 美化matplotlib绘出的图,导入后自动美化
import
seaborn as sns
# matplotlib自带美化风格
# 打印可选风格
print
(plt.style.available
#ggplot, bmh, dark_background, fivethirtyeight, grayscale)
# 激活风格
plt.style.use(
'bmh'
)
|
『Python』Numpy学习指南第九章_使用Matplotlib绘图
from mpl_toolkits.mplot3d import Axes3D
ax = fig.add_subplot(111,projection='3d')
ax.plot() 绘制3维线
ax.plot_surface绘制三维网格(面)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
from
mpl_toolkits.mplot3d
import
Axes3D
#<-----导入3D包
import
numpy as np
import
matplotlib.pyplot as plt
fig
=
plt.figure(figsize
=
(
9
,
6
))
ax
=
fig.add_subplot(
111
,projection
=
'3d'
)
#<-----设置3D模式子图
<br>
# 新思路,以前都是生成x和y绘制z=f(x,y)的函数,此次绘制x=f1(z),y=f2(z)
z
=
np.linspace(
0
,
6
,
1000
)
r
=
1
x
=
r
*
np.sin(np.pi
*
2
*
z)
y
=
r
*
np.cos(np.pi
*
2
*
z)
ax.plot(x, y, z, label
=
u
'螺旋线'
, c
=
'r'
)
ax.legend()
# dpi每英寸长度的点数
plt.savefig(
'3d_fig.png'
,dpi
=
200
)
plt.show()
|
# ax.plot 绘制的是3维线,ax.plot_surface绘制的是三维网格(也就是面)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
from
mpl_toolkits.mplot3d
import
axes3d
import
matplotlib.pyplot as plt
from
matplotlib
import
cm
fig
=
plt.figure()
ax
=
fig.add_subplot(
111
,projection
=
'3d'
)
X, Y, Z
=
axes3d.get_test_data(
0.05
)
print
(X,Y,Z)
# ax.plot 绘制的是3维线,ax.plot_surface绘制的是三维网格(也就是面)
ax.plot_surface(X, Y, Z, rstride
=
5
, cstride
=
5
, alpha
=
0.3
)
# 三维图投影制做,zdir选择投影方向坐标轴
cset
=
ax.contour(X, Y, Z,
10
, zdir
=
'z'
, offset
=
-
100
, cmap
=
cm.coolwarm)
cset
=
ax.contour(X, Y, Z, zdir
=
'x'
, offset
=
-
40
, cmap
=
cm.coolwarm)
cset
=
ax.contour(X, Y, Z, zdir
=
'y'
, offset
=
40
, cmap
=
cm.coolwarm)
ax.set_xlabel(
'X'
)
ax.set_xlim(
-
40
,
40
)
ax.set_ylabel(
'Y'
)
ax.set_ylim(
-
40
,
40
)
ax.set_zlabel(
'Z'
)
ax.set_zlim(
-
100
,
100
)
plt.show()
|
# 为等高线图添加标注
1
2
|
cs
=
ax2.contour(X,Y,Z)
ax2.clabel(cs, inline
=
1
, fontsize
=
5
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# -*- coding: utf-8 -*-
#**********************************************************
import
os
import
numpy as np
import
wlab
#pip install wlab
import
matplotlib
import
matplotlib.cm as cm
import
matplotlib.pyplot as plt
from
matplotlib.ticker
import
MultipleLocator
from
scipy.interpolate
import
griddata
matplotlib.rcParams[
'xtick.direction'
]
=
'out'
matplotlib.rcParams[
'ytick.direction'
]
=
'out'
#**********************************************************
FreqPLUS
=
[
'F06925'
,
'F10650'
,
'F23800'
,
'F18700'
,
'F36500'
,
'F89000'
]
#
FindPath
=
'/d3/MWRT/R20130805/'
#**********************************************************
fig
=
plt.figure(figsize
=
(
8
,
6
), dpi
=
72
, facecolor
=
"white"
)
axes
=
plt.subplot(
111
)
axes.cla()
#清空坐标轴内的全部内容
#指定图形的字体
font
=
{
'family'
:
'serif'
,
'color'
:
'darkred'
,
'weight'
:
'normal'
,
'size'
:
16
,
}
#**********************************************************
# 查找目录总文件名中保护F06925,EMS和txt字符的文件
for
fp
in
FreqPLUS:
FlagStr
=
[fp,
'EMS'
,
'txt'
]
FileList
=
wlab.GetFileList(FindPath,FlagStr)
#
LST
=
[]
#地表温度
EMS
=
[]
#地表发射率
TBH
=
[]
#水平极化亮温
TBV
=
[]
#垂直极化亮温
#
findex
=
0
for
fn
in
FileList:
findex
=
findex
+
1
if
(os.path.isfile(fn)):
print
(
str
(findex)
+
'-->'
+
fn)
#fn='/d3/MWRT/R20130805/F06925_EMS60.txt'
data
=
wlab.dlmread(fn)
EMS
=
EMS
+
list
(data[:,
1
])
#地表发射率
LST
=
LST
+
list
(data[:,
2
])
#温度
TBH
=
TBH
+
list
(data[:,
8
])
#水平亮温
TBV
=
TBV
+
list
(data[:,
9
])
#垂直亮温
#-----------------------------------------------------------
#生成格点数据,利用griddata插值
grid_x, grid_y
=
np.mgrid[
275
:
315
:
1
,
0.60
:
0.95
:
0.01
]
grid_z
=
griddata((LST,EMS), TBH, (grid_x, grid_y), method
=
'cubic'
)
#将横纵坐标都映射到(0,1)的范围内
extent
=
(
0
,
1
,
0
,
1
)
#指定colormap
cmap
=
matplotlib.cm.jet
#设定每一个图的colormap和colorbar所表示范围是同样的,即归一化
norm
=
matplotlib.colors.Normalize(vmin
=
160
, vmax
=
300
)
#显示图形,此处没有使用contourf #>>>ctf=plt.contourf(grid_x,grid_y,grid_z)
gci
=
plt.imshow(grid_z.T, extent
=
extent, origin
=
'lower'
,cmap
=
cmap, norm
=
norm)
#配置一下坐标刻度等
ax
=
plt.gca()
ax.set_xticks(np.linspace(
0
,
1
,
9
))
ax.set_xticklabels( (
'275'
,
'280'
,
'285'
,
'290'
,
'295'
,
'300'
,
'305'
,
'310'
,
'315'
))
ax.set_yticks(np.linspace(
0
,
1
,
8
))
ax.set_yticklabels( (
'0.60'
,
'0.65'
,
'0.70'
,
'0.75'
,
'0.80'
,
'0.85'
,
'0.90'
,
'0.95'
))
#显示colorbar
cbar
=
plt.colorbar(gci)
cbar.set_label(
'$T_B(K)$'
,fontdict
=
font)
cbar.set_ticks(np.linspace(
160
,
300
,
8
))
cbar.set_ticklabels( (
'160'
,
'180'
,
'200'
,
'220'
,
'240'
,
'260'
,
'280'
,
'300'
))
#设置label
ax.set_ylabel(
'Land Surface Emissivity'
,fontdict
=
font)
ax.set_xlabel(
'Land Surface Temperature(K)'
,fontdict
=
font)
#陆地地表温度LST
#设置title
titleStr
=
'$T_B$ for Freq = '
+
str
(
float
(fp[
1
:
-
1
])
*
0.01
)
+
'GHz'
plt.title(titleStr)
figname
=
fp
+
'.png'
plt.savefig(figname)
plt.clf()
#清除图形
#plt.show()
print
(
'ALL -> Finished OK'
)
|
上面的例子中,每一个保存的图,都是用一样的colormap,而且每一个图的颜色映射值都是同样的,也就是说第一个图中若是200表示蓝色,那么其余图中的200也表示蓝色。
示例的图形以下:
4. 样式美化(matplotlib.pyplot.style.use) 点击打开连接
使用matplotlib自带的几种美化样式,就能够很轻松的对生成的图形进行美化。
可使用matplotlib.pyplot.style.available获取全部的美化样式