一、认识matplotlib
Matplotlib是一个Python 2D绘图库,能够以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形。
二、一个最简单的绘图例子
import matplotlib.pyplot as plt
import numpy as np
plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
plt.show()#显示!!!
三、Figure的组成
Figure:顶层级,用来容纳所有绘图元素
Axes:matplotlib宇宙的核心,容纳了大量元素用来构造一幅幅子图,一个figure可以由一个或多个子图组成
Axis:axes的下属层级,用于处理所有和坐标轴,网格有关的元素
Tick:axis的下属层级,用来处理所有和刻度有关的元素
四、两种绘图接口
x = np.linspace(0, 2, 100)
fig, ax = plt.subplots()
ax.plot(x, x, label='linear')
ax.plot(x, x**2, label='quadratic')
ax.plot(x, x**3, label='cubic')
ax.set_xlabel('x label')
ax.set_ylabel('y label')
ax.set_title("Simple Plot")
ax.legend()
plt.show()
x = np.linspace(0, 2, 100)
plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
plt.show()
一、概述
import matplotlib.pyplot as plt
import numpy as np
# step 1
# 我们用 matplotlib.pyplot.figure() 创建了一个Figure实例
fig = plt.figure()
# step 2
# 然后用Figure实例创建了一个两行一列(即可以有两个subplot)的绘图区,并同时在第一个位置创建了一个subplot
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot
# step 3
# 然后用Axes实例的方法画了一条曲线
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax.plot(t, s, color='blue', lw=2)
二、自定义你的Artist对象
# .patch
plt.figure().patch
plt.axes().patch
import matplotlib
# Figure rectangle的属性
matplotlib.artist.getp(fig.patch)
三、基本元素 - primitives
前文介绍到,Artist包含两种对象:基本要素-primitives 和 容器-containers。
primitives:曲线Line2D,文本text,矩形Rectangle,图像image等
container是容器:图形figure、坐标系Axes和坐标轴Axis。
primitives 的几种类型:曲线-Line2D,矩形-Rectangle,图像-image 。
class matplotlib.lines.Line2D(xdata, ydata, linewidth=None, linestyle=None, color=None, marker=None, markersize=None, markeredgewidth=None, markeredgecolor=None, markerfacecolor=None, markerfacecoloralt='none', fillstyle=None, antialiased=None, dash_capstyle=None, solid_capstyle=None, dash_joinstyle=None, solid_joinstyle=None, pickradius=5, drawstyle=None, markevery=None, **kwargs)
xdata:需要绘制的line中点的在x轴上的取值,若忽略,则默认为range(1,len(ydata)+1)
ydata:需要绘制的line中点的在y轴上的取值
linewidth:线条的宽度
linestyle:线型
color:线条的颜色
marker:点的标记,详细可参考markers API
markersize:标记的size
a. 如何设置Line2D的属性
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x,y, linewidth=10) # 设置线的粗细参数为10
x = range(0,5)
y = [2,5,7,8,10]
line, = plt.plot(x, y, '-')
line.set_antialiased(False) # 关闭抗锯齿功能
x = range(0,5)
y = [2,5,7,8,10]
lines = plt.plot(x, y)
plt.setp(lines, color='r', linewidth=10)
b. 如何绘制lines
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x,y)
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
fig = plt.figure()
ax = fig.add_subplot(111)
line = Line2D(x, y)
ax.add_line(line)
ax.set_xlim(min(x), max(x))
ax.set_ylim(min(y), max(y))
plt.show()
import numpy as np
import matplotlib.pyplot as plt
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, label='both limits (default)')
import matplotlib.pyplot as plt
import numpy as np
x=np.random.randint(0,100,100) #生成【0-100】之间的100个数据,即 数据集
bins=np.arange(0,101,10) #设置连续的边界值,即直方图的分布区间[0,10],[10,20]...
plt.hist(x,bins,color='fuchsia',alpha=0.5)#alpha设置透明度,0为完全透明
plt.xlabel('scores')
plt.ylabel('count')
plt.xlim(0,100)#设置x轴分布范围 plt.show()
import pandas as pd
import re
df = pd.DataFrame(columns = ['data'])
df.loc[:,'data'] = x
df['fenzu'] = pd.cut(df['data'], bins=bins, right = False,include_lowest=True)
df_cnt = df['fenzu'].value_counts().reset_index()
df_cnt.loc[:,'mini'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\[(.*)\,',x)[0]).astype(int)
df_cnt.loc[:,'maxi'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\,(.*)\)',x)[0]).astype(int)
df_cnt.loc[:,'width'] = df_cnt['maxi']- df_cnt['mini']
df_cnt.sort_values('mini',ascending = True,inplace = True)
df_cnt.reset_index(inplace = True,drop = True)
#用Rectangle把hist绘制出来
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
#rect1 = plt.Rectangle((0,0),10,10)
#ax1.add_patch(rect)
#ax2 = fig.add_subplot(212)
for i in df_cnt.index:
rect = plt.Rectangle((df_cnt.loc[i,'mini'],0),df_cnt.loc[i,'width'],df_cnt.loc[i,'fenzu'])
#rect2 = plt.Rectangle((10,0),10,5)
ax1.add_patch(rect)
#ax1.add_patch(rect2)
ax1.set_xlim(0, 100)
ax1.set_ylim(0, 16)
plt.show()
2) bar-柱状图
left:x轴的位置序列,一般采用range函数产生一个序列,但是有时候可以是字符串
height:y轴的数值序列,也就是柱形图的高度,一般就是我们需要展示的数据;
alpha:透明度,值越小越透明
width:为柱形图的宽度,一般这是为0.8即可;
color或facecolor:柱形图填充的颜色;
edgecolor:图形边缘颜色
label:解释每个图像代表的含义,这个参数是为legend()函数做铺垫的,表示该次bar的标签
bar绘制柱状图
import matplotlib as mpl
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=3)
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in range(1,17):
rect = plt.Rectangle((i+0.25,0),0.5,i)
ax1.add_patch(rect)
ax1.set_xlim(0, 16)
ax1.set_ylim(0, 16)
plt.show()
import matplotlib.pyplot as plt
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)
c. Wedge-契形
x:契型的形状,一维数组。
explode:如果不是等于None,则是一个len(x)数组,它指定用于偏移每个楔形块的半径的分数。
labels:用于指定每个契型块的标记,取值是列表或为None。
colors:饼图循环使用的颜色序列。如果取值为None,将使用当前活动循环中的颜色。
startangle:饼状图开始的绘制的角度。
pie绘制饼状图:
import matplotlib.pyplot as plt
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') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Wedge
from matplotlib.collections import PatchCollection
fig = plt.figure()
ax1 = fig.add_subplot(111)
theta1 = 0
sizes = [15, 30, 45, 10]
patches = []
patches += [
Wedge((0.3, 0.3), .2, 0, 54), # Full circle
Wedge((0.3, 0.3), .2, 54, 162), # Full ring
Wedge((0.3, 0.3), .2, 162, 324), # Full sector
Wedge((0.3, 0.3), .2, 324, 360), # Ring sector
]
colors = 100 * np.random.rand(len(patches))
p = PatchCollection(patches, alpha=0.4)
p.set_array(colors)
ax1.add_collection(p)
plt.show()
x:数据点x轴的位置
y:数据点y轴的位置
s:尺寸大小
c:可以是单个颜色格式的字符串,也可以是一系列颜色
marker: 标记的类型
scatter绘制散点图:
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)
plt.show()
import matplotlib.pyplot as plt
import numpy as np
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()
plt.show()
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)
print(ax1)
print(fig.axes) # fig.axes 中包含了subplot和axes两个实例, 刚刚添加的
fig = plt.figure()
ax1 = fig.add_subplot(211)
for ax in fig.axes:
ax.grid(True)
Figure也有它自己的text、line、patch、image。你可以直接通过add primitive语句直接添加。
Figure容器的常见属性:
Figure.patch属性:Figure的背景矩形
Figure.axes属性:一个Axes实例的列表(包括Subplot)
Figure.images属性:一个FigureImages patch列表
Figure.lines属性:一个Line2D实例的列表(很少使用)
Figure.legends属性:一个Figure Legend实例列表(不同于Axes.legends)
Figure.texts属性:一个Figure Text实例列表
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch # axes的patch是一个Rectangle实例
rect.set_facecolor('green')
Axes容器的常见属性有:
artists: Artist实例列表 patch: Axes所在的矩形实例 collections: Collection实例 images: Axes图像 legends: Legend 实例 lines: Line2D 实例 patches: Patch 实例 texts: Text 实例 xaxis: matplotlib.axis.XAxis 实例 yaxis: matplotlib.axis.YAxis 实例
# 不用print,直接显示结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
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实例的列表)。 可以通过minor=True|False关键字参数控制输出minor还是major的tick label。
axis.get_ticklines() # 获取刻度线列表(一个Line2D实例的列表)。 可以通过minor=True|False关键字参数控制输出minor还是major的tick line。
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('red') # 颜色
label.set_rotation(45) # 旋转角度
label.set_fontsize(16) # 字体大小
for line in ax1.yaxis.get_ticklines():
# 调用y轴刻度线条实例, 是一个Line2D实例
line.set_color('green') # 颜色
line.set_markersize(25) # marker大小
line.set_markeredgewidth(2)# marker粗细
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
# 设置ticker的显示格式
formatter = matplotlib.ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)
# 设置ticker的参数,右侧为主轴,颜色为绿色
ax.yaxis.set_tick_params(which='major', labelcolor='green',
labelleft=False, labelright=True)
plt.show()
一、子图
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()
N = 150
r = 2 * np.random.rand(N)
theta = 2 * np.pi * np.random.rand(N)
area = 200 * 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=(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()
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])
ax.scatter(np.random.randn(10), np.random.randn(10))
# sub2
ax = fig.add_subplot(spec[0, 3: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()
二、子图上的方法
在 ax 对象上定义了和 plt 类似的图形绘制函数,常用的有: plot, hist, scatter, bar, barh, pie
fig, ax = plt.subplots(figsize=(4,3))
ax.plot([1,2],[2,1])
fig, ax = plt.subplots(figsize=(4,3))
ax.hist(np.random.randn(1000))
常用直线的画法为: axhline, axvline, axline (水平、垂直、任意方向)
fig, ax = plt.subplots(figsize=(4,3))
ax.axhline(0.5,0.2,0.8)
ax.axvline(0.5,0.2,0.8)
ax.axline([0.3,0.3],[0.7,0.7])
fig, ax = plt.subplots(figsize=(4,3))
ax.grid(True)
使用 set_xscale, set_title, set_xlabel 分别可以设置坐标轴的规度(指对数坐标等)、标题、轴名
fig, axs = plt.subplots(1, 2, figsize=(10, 4))
fig.suptitle('大标题', size=20)
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')
axs[j].set_title('子标题1')
axs[j].set_ylabel('对数坐标')
else:
axs[j].set_title('子标题1')
axs[j].set_ylabel('普通坐标')
fig.tight_layout()
与一般的 plt 方法类似, legend, annotate, arrow, text 对象也可以进行相应的绘制
fig, ax = plt.subplots()
ax.arrow(0, 0, 1, 1, head_width=0.03, head_length=0.05, facecolor='red', edgecolor='blue')
ax.text(x=0, y=0,s='这是一段文字', fontsize=16, rotation=70, rotation_mode='anchor', color='green')
ax.annotate('这是中点', xy=(0.5, 0.5), xytext=(0.8, 0.2), arrowprops=dict(facecolor='yellow', edgecolor='black'), fontsize=16)
fig, ax = plt.subplots()
ax.plot([1,2],[2,1],label="line1")
ax.plot([1,1],[1,2],label="line1")
ax.legend(loc=1)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import numpy as np
#fontdict学习的案例
#学习的过程中请尝试更换不同的fontdict字典的内容,以便于更好的掌握
#---------设置字体样式,分别是字体,颜色,宽度,大小
font1 = {'family': 'SimSun',#华文楷体
'alpha':0.7,#透明度
'color': 'purple',
'weight': 'normal',
'size': 16,
}
font2 = {'family': 'Times New Roman',
'color': 'red',
'weight': 'normal',
'size': 16,
}
font3 = {'family': 'serif',
'color': 'blue',
'weight': 'bold',
'size': 14,
}
font4 = {'family': 'Calibri',
'color': 'navy',
'weight': 'normal',
'size': 17,
}
#-----------四种不同字体显示风格-----
#-------建立函数----------
x = np.linspace(0.0, 5.0, 100)
y = np.cos(2*np.pi*x) * np.exp(-x/3)
#-------绘制图像,添加标注----------
plt.plot(x, y, '--')
plt.title('震荡曲线', fontdict=font1)
#------添加文本在指定的坐标处------------
plt.text(2, 0.65, r'$\cos(2 \pi x) \exp(-x/3)$', fontdict=font2)
#---------设置坐标标签
plt.xlabel('Y=time (s)', fontdict=font3)
plt.ylabel('X=voltage(mv)', fontdict=font4)
# 调整图像边距
plt.subplots_adjust(left=0.15)
plt.show()
title和set_title
该命令是用来设置axes的标题。
参数:此方法接受以下描述的参数:
label:str,此参数是要添加的文本
fontdict:dict,此参数是控制title文本的外观
loc:str,{‘center’, ‘left’, ‘right’}默认为center
pad:float,该参数是指标题偏离图表顶部的距离,默认为6。
y:float,该参数是title所在axes垂向的位置。默认值为1,即title位于axes的顶部。
kwargs:该参数是指可以设置的一些奇特文本的属性。
返回值:此方法返回作为创建的title实例的文本。
figtext和text
参数:此方法接受以下描述的参数:
x,y:float,此参数是指在figure中放置文本的位置。一般取值是在[0,1]范围内。使用transform关键字可以更改坐标系。
s:str,此参数是指文本
fontdict:dict,此参数是一个可选参数,并且是一个覆盖默认文本属性的字典。如果fontdict为None,则由rcParams确定默认值。
返回值:此方法返回作为创建的文本实例的文本。
suptitle
参数:此方法接受以下描述的参数:
t: str,标题的文本
x:float,默认值是0.5.该参数是指文本在figure坐标系下的x坐标
y:float,默认值是0.95.该参数是指文本在figure坐标系下的y坐标
horizontalalignment, ha:该参数是指选择文本水平对齐方式,有三种选择{‘center’, ‘left’, right’},默认值是 ‘center’
verticalalignment, va:该参数是指选择文本垂直对齐方式,有四种选择{‘top’, ‘center’, ‘bottom’, ‘baseline’},默认值是 ‘top’
fontsize, size:该参数是指文本的大小,默认值是依据rcParams的设置:rcParams[“figure.titlesize”] (default: ‘large’)
fontweight, weight:该参数是用来设置字重。默认值是依据rcParams的设置:rcParams[“figure.titleweight”] (default: ‘normal’)
fontproperties:None or dict,该参数是可选参数,如果该参数被指定,字体的大小将从该参数的默认值中提取。
返回值:此方法返回作为创建的title实例的文本。
xlabel和ylabel
参数:此方法接受以下描述的参数:
xlabel或者ylabel:label的文本
labelpad:设置label距离轴(axis)的距离
loc:{‘left’, ‘center’, ‘right’},默认为center
**kwargs:文本属性
返回值:此方法返回作为创建的xlabel和ylabel实例的文本。
#文本属性的输入一种是通过**kwargs属性这种方式,一种是通过操作 matplotlib.font_manager.FontProperties 方法
#该案例中对于x_label采用**kwargs调整字体属性,y_label则采用 matplotlib.font_manager.FontProperties 方法调整字体属性
#该链接是FontProperties方法的介绍 https://matplotlib.org/api/font_manager_api.html#matplotlib.font_manager.FontProperties
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
font = FontProperties()
font.set_family('serif')
font.set_name('Times New Roman')
font.set_style('italic')
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation [V]', fontproperties=font)
plt.show()
#此代码主要给示范了不同的arrowstyle以及FancyArrowPatch的样式
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
fig, axs = plt.subplots(2, 2)
x1, y1 = 0.3, 0.3
x2, y2 = 0.7, 0.7
ax = axs.flat[0]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)#在axes中创建一个artist
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",#箭头的样式
color="0.5",
patchB=None,
shrinkB=0,
connectionstyle="arc3,rad=0.3",
),
)
#在整个代码中使用Transform=ax.transAx表示坐标相对于axes的bounding box,其中(0,0)是轴的左下角,(1,1)是右上角。
ax.text(.05, .95, "connect", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[1]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",
color="0.5",
patchB=el,#箭头终点处的图形
shrinkB=0,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "clip", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[2]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="-",
color="0.5",
patchB=el,
shrinkB=5,
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "shrink", transform=ax.transAxes, ha="left", va="top")
ax = axs.flat[3]
ax.plot([x1, x2], [y1, y2], ".")
el = mpatches.Ellipse((x1, y1), 0.3, 0.4, angle=30, alpha=0.2)
ax.add_artist(el)
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="fancy",
color="0.5",
patchB=el,
shrinkB=5,#箭头终点的缩进点数
connectionstyle="arc3,rad=0.3",
),
)
ax.text(.05, .95, "mutate", transform=ax.transAxes, ha="left", va="top")
for ax in axs.flat:
ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1)
plt.show()
两个点之间的连接路径主要有connectionstyle和以下样式确定
其中angle3 和 arc3 中的 3 意味着所得到的路径是二次样条段( 三个控制点)
import matplotlib.pyplot as plt
def demo_con_style(ax, connectionstyle):
x1, y1 = 0.3, 0.2
x2, y2 = 0.8, 0.6
ax.plot([x1, x2], [y1, y2], ".")
ax.annotate("",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='data',
arrowprops=dict(arrowstyle="->", color="0.5",
shrinkA=5, shrinkB=5,
patchA=None, patchB=None,
connectionstyle=connectionstyle,
),
)
ax.text(.05, .95, connectionstyle.replace(",", ",\n"),
transform=ax.transAxes, ha="left", va="top")
fig, axs = plt.subplots(3, 5, figsize=(8, 4.8))
demo_con_style(axs[0, 0], "angle3,angleA=90,angleB=0")
demo_con_style(axs[1, 0], "angle3,angleA=0,angleB=90")
demo_con_style(axs[0, 1], "arc3,rad=0.")
demo_con_style(axs[1, 1], "arc3,rad=0.3")
demo_con_style(axs[2, 1], "arc3,rad=-0.3")
demo_con_style(axs[0, 2], "angle,angleA=-90,angleB=180,rad=0")
demo_con_style(axs[1, 2], "angle,angleA=-90,angleB=180,rad=5")
demo_con_style(axs[2, 2], "angle,angleA=-90,angleB=10,rad=5")
demo_con_style(axs[0, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=0")
demo_con_style(axs[1, 3], "arc,angleA=-90,angleB=0,armA=30,armB=30,rad=5")
demo_con_style(axs[2, 3], "arc,angleA=-90,angleB=0,armA=0,armB=40,rad=0")
demo_con_style(axs[0, 4], "bar,fraction=0.3")
demo_con_style(axs[1, 4], "bar,fraction=-0.3")
demo_con_style(axs[2, 4], "bar,angle=180,fraction=-0.2")
for ax in axs.flat:
ax.set(xlim=(0, 1), ylim=(0, 1), xticks=[], yticks=[], aspect=1)
fig.tight_layout(pad=0.2)
plt.show()
#以下两个block懂了之后,annotate基本懂了
#如果想更深入学习可以参看官网案例学习https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.annotate.html#matplotlib.axes.Axes.annotate
import numpy as np
import matplotlib.pyplot as plt
# 以步长0.005绘制一个曲线
x = np.arange(0, 10, 0.005)
y = np.exp(-x/2.) * np.sin(2*np.pi*x)
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim(0, 10)#设置x轴的范围
ax.set_ylim(-1, 1)#设置x轴的范围
# 被注释点的数据轴坐标和所在的像素
xdata, ydata = 5, 0
xdisplay, ydisplay = ax.transData.transform_point((xdata, ydata))
# 设置注释文本的样式和箭头的样式
bbox = dict(boxstyle="round", fc="0.8")
arrowprops = dict(
arrowstyle = "->",
connectionstyle = "angle,angleA=0,angleB=90,rad=10")
# 设置偏移量
offset = 72
# xycoords默认为'data'数据轴坐标,对坐标点(5,0)添加注释
# 注释文本参考被注释点设置偏移量,向左2*72points,向上72points
ax.annotate('data = (%.1f, %.1f)'%(xdata, ydata),
(xdata, ydata), xytext=(-2*offset, offset), textcoords='offset points',
bbox=bbox, arrowprops=arrowprops)
# xycoords以绘图区左下角为参考,单位为像素
# 注释文本参考被注释点设置偏移量,向右0.5*72points,向下72points
disp = ax.annotate('display = (%.1f, %.1f)'%(xdisplay, ydisplay),
(xdisplay, ydisplay), xytext=(0.5*offset, -offset),
xycoords='figure pixels',
textcoords='offset points',
bbox=bbox, arrowprops=arrowprops)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
# 绘制一个极地坐标,再以0.001为步长,画一条螺旋曲线
fig = plt.figure()
ax = fig.add_subplot(111, polar=True)
r = np.arange(0,1,0.001)
theta = 2 * 2*np.pi * r
line, = ax.plot(theta, r, color='#ee8d18', lw=3)
# 对索引为800处画一个圆点,并做注释
ind = 800
thisr, thistheta = r[ind], theta[ind]
ax.plot([thistheta], [thisr], 'o')
ax.annotate('a polar annotation',
xy=(thistheta, thisr), # 被注释点遵循极坐标系,坐标为角度和半径
xytext=(0.05, 0.05), # 注释文本放在绘图区的0.05百分比处
textcoords='figure fraction',
arrowprops=dict(facecolor='black', shrink=0.05),# 箭头线为黑色,两端缩进5%
horizontalalignment='left',# 注释文本的左端和低端对齐到指定位置
verticalalignment='bottom',
)
plt.show()
#首先可以查看matplotlib所有可用的字体
from matplotlib import font_manager
font_family = font_manager.fontManager.ttflist
font_name_list = [i.name for i in font_family]
for font in font_name_list:
print(f'{font}\n')
#该block讲述如何在matplotlib里面,修改字体默认属性,完成全局字体的更改。
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun'] # 指定默认字体为新宋体。
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时 负号'-' 显示为方块和报错的问题。
#局部字体的修改方法1
import matplotlib.pyplot as plt
import matplotlib.font_manager as fontmg
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) # 小示例图的字体设置
#局部字体的修改方法2
import matplotlib.pyplot as plt
import matplotlib.font_manager as fontmg
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plt.plot(x, label='小示例图标签')
#fname为你系统中的字体库路径
my_font1 = fontmg.FontProperties(fname=r'C:\Windows\Fonts\simhei.ttf') # 读取系统中的 黑体 字体。
my_font2 = fontmg.FontProperties(fname=r'C:\Windows\Fonts\simkai.ttf') # 读取系统中的 楷体 字体。
# fontproperties 设置中文显示,fontsize 设置字体大小
plt.xlabel('x 轴名称参数', fontproperties=my_font1, fontsize=16) # 设置x轴名称
plt.ylabel('y 轴名称参数', fontproperties=my_font1, fontsize=14) # 设置Y轴名称
plt.title('坐标系的标题', fontproperties=my_font2, fontsize=20) # 标题的字体设置
plt.legend(loc='lower right', prop=my_font1, fontsize=10) # 小示例图的字体设置
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.0, 2.0, 0.01)
s = np.sin(2*np.pi*t)
plt.plot(t, s)
plt.title(r'$\alpha_i > \beta_i$', fontsize=20)
plt.text(1, -0.6, r'$\sum_{i=0}^\infty x_i$', fontsize=20)
plt.text(0.6, 0.6, r'$\mathcal{A}\mathrm{sin}(2 \omega t)$',
fontsize=20)
plt.xlabel('time (s)')
plt.ylabel('volts (mV)')
plt.show()
#这是对前七节学习内容的总结案例
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
# 分别在figure和subplot上设置title
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# 设置x-axis和y-axis的范围都是[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})
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)
font1 = {'family': 'Times New Roman',
'color': 'purple',
'weight': 'normal',
'size': 10,
}
ax.text(3, 2, 'unicode: Institut für Festkörperphysik',fontdict=font1)
ax.text(0.95, 0.01, 'colored text in axes coords',
verticalalignment='bottom', horizontalalignment='right',
transform=ax.transAxes,
color='green', fontsize=15)
ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
# 使用axis的set_ticks方法手动设置标签位置的例子,该案例中由于tick设置过大,所以会影响绘图美观,不建议用此方式进行设置tick
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.))
plt.show()
# 使用axis的set_ticklabels方法手动设置标签格式的例子
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)
plt.show()
#一般绘图时会自动创建刻度,而如果通过上面的例子使用set_ticks创建刻度可能会导致tick的范围与所绘制图形的范围不一致的问题。
#所以在下面的案例中,axs[1]中set_xtick的设置要与数据范围所对应,然后再通过set_xticklabels设置刻度所对应的标签
import numpy as np
import matplotlib.pyplot as plt
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('bottom')#set_ticks_position()方法是用来设置刻度所在的位置,常用的参数有bottom、top、both、none
print(axs[1].xaxis.get_ticklines())
plt.show()
# 接收字符串格式的例子
fig, axs = plt.subplots(2, 2, figsize=(8, 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)
plt.show()
# 接收函数的例子
def formatoddticks(x, pos):
"""Format odd tick positions."""
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)
plt.show()
# 接收各种locator的例子
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=10)
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)
plt.show()
此外matplotlib.dates 模块还提供了特殊的设置日期型刻度格式和位置的方式
import matplotlib.dates as mdates
import datetime
# 特殊的日期型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)
plt.show()
line_up, = plt.plot([1, 2, 3], label='Line 2')
line_down, = plt.plot([3, 2, 1], label='Line 1')
plt.legend([line_up, line_down], ['Line Up', 'Line Down'],loc=5, title='line',frameon=False)#loc参数设置图例所在的位置,title设置图例的标题,frameon参数将图例边框给去掉
#这个案例是显示多图例legend
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-1, 1, 4)
y = np.random.uniform(-1, 1, 4)
p1, = plt.plot([1,2,3])
p2, = plt.plot([3,2,1])
l1 = plt.legend([p2, p1], ["line 2", "line 1"], loc='upper left')
p3 = plt.scatter(x[0:2], y[0:2], marker = 'D', color='r')
p4 = plt.scatter(x[2:], y[2:], marker = 'D', color='g')
# 下面这行代码由于添加了新的legend,所以会将l1从legend中给移除
plt.legend([p3, p4], ['label', 'label1'], loc='lower right', scatterpoints=1)
# 为了保留之前的l1这个legend,所以必须要通过plt.gca()获得当前的axes,然后将l1作为单独的artist
plt.gca().add_artist(l1)
一、matplotlib的绘图样式(style)
1.matplotlib预先定义样式
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('default')
plt.plot([1,2,3,4],[2,3,4,5])
plt.show()
plt.style.use('ggplot')
plt.plot([1,2,3,4],[2,3,4,5])
print(plt.style.available)
#['Solarize_Light2', '_classic_test_patch', '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('file/presentation.mplstyle')
plt.plot([1,2,3,4],[2,3,4,5])
值得特别注意的是,matplotlib支持混合样式的引用,只需在引用时输入一个样式列表,若是几个样式中涉及到同一个参数,右边的样式表会覆盖左边的值。
plt.style.use(['dark_background', 'file/presentation.mplstyle'])
plt.plot([1,2,3,4],[2,3,4,5])
plt.style.use('default') # 恢复到默认样式
plt.plot([1,2,3,4],[2,3,4,5])
mpl.rcParams['lines.linewidth'] = 2
mpl.rcParams['lines.linestyle'] = '--'
plt.plot([1,2,3,4],[2,3,4,5])
另外matplotlib也还提供了了一种更便捷的修改样式方式,可以一次性修改多个样式。
mpl.rc('lines', linewidth=4, linestyle='-.')
plt.plot([1,2,3,4],[2,3,4,5])
# 查找matplotlibrc文件的路径
mpl.matplotlib_fname()
二、matplotlib的色彩设置(color)
plt.style.use('default')
# 颜色用[0,1]之间的浮点数表示,四个分量按顺序分别为(red, green, blue, alpha),其中alpha透明度可省略
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))
# 用十六进制颜色码表示,同样最后两位表示透明度,可省略
plt.plot([1,2,3],[4,5,6],color='#0f0f0f')
plt.plot([4,5,6],[1,2,3],color='#0f0f0f80')
# 当只有一个位于[0,1]的值时,表示灰度色阶
plt.plot([1,2,3],[4,5,6],color='0.5')
# matplotlib有八个基本颜色,可以用单字符串来表示,分别是'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w',对应的是blue, green, red, cyan, magenta, yellow, black, and white的英文缩写
plt.plot([1,2,3],[4,5,6],color='m')
# matplotlib提供了颜色对照表,可供查询颜色对应的名称
plt.plot([1,2,3],[4,5,6],color='tan')
x = np.random.randn(50)
y = np.random.randn(50)
plt.scatter(x,y,c=x,cmap='RdPu')
一、展示趋势变化(Evolution)
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 创建数据,分别对应X轴和Y轴,注意X轴要是有序排列的
df=pd.DataFrame({'xdata': range(1,101), 'ydata': np.random.randn(100) })
# 绘图
plt.style.use('seaborn-darkgrid') # 也可以选择其他的风格式样 seaborn-whitegrid
plt.figure(figsize=(15, 10)) # 设置画布大小
# color: 控制线条颜色,red/skyblue/blue 等
# alpha: 控制线条透明度
# linestyle:控制线条式样,'--', '-', '-.', ':' 等
# linewidth:控制线条粗细大小
plt.plot( 'xdata', 'ydata', data=df, color='blue',alpha=0.3, linestyle='-.', linewidth=2, label='linestyle')
plt.legend(loc='upper left', frameon=False) # 设置标签
plt.title('Basi
# 导入包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 导入数据集并转成方便作图的格式
Dataset = pd.read_csv('data/Drugs.csv')
group = Dataset.groupby(['YYYY','State']).agg('sum').reset_index()
df = group.pivot(index='YYYY', columns='State', values='DrugReports').reset_index()
# 设定式样
plt.style.use('seaborn-darkgrid')
# 创建调色板, 色卡用来控制每条线的颜色
palette = plt.get_cmap('Set1')
# 绘图
plt.figure(figsize=(15, 7))
num=0
for column in df.drop('YYYY', axis=1):
num += 1
plt.plot(df['YYYY'], df[column], marker='', color=palette(num), linewidth=2, alpha=0.9, label=column)
plt.legend(loc=2, ncol=2)
plt.title("Multiple line plot", loc='center', fontsize=12, fontweight=0, color='orange')
plt.xlabel("year")
plt.ylabel("DrugReports")
plt.show()
# 导入包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 导入数据集并转成方便作图的格式
Dataset = pd.read_csv('data/Drugs.csv')
group = Dataset.groupby(['YYYY','State']).agg('sum').reset_index()
df = group.pivot(index='YYYY', columns='State', values='DrugReports').reset_index()
# 设定式样
plt.style.use('seaborn-darkgrid')
# 绘图
plt.figure(figsize=(10, 10), dpi=70)
# 所有的线条都画成灰色
for column in df.drop('YYYY', axis=1):
plt.plot(df['YYYY'], df[column], marker='', color='grey', linewidth=1, alpha=0.4)
# PA的特殊处理,用橘色且加粗
plt.plot(df['YYYY'], df['PA'], marker='', color='orange', linewidth=4, alpha=0.7)
# 设定每条线的label的位置,其他的都为灰色,PA的为橘色
num=0
for i in df.values[7][1:]:
num+=1
name=list(df)[num]
if name != 'PA':
plt.text(2017.02, i, name, horizontalalignment='left', size='small', color='grey')
# 特殊处理PA
plt.text(2017.02, df.PA.tail(1), 'PA', horizontalalignment='left', size='small', color='orange')
# 添加图的标题和XY轴的标签
plt.title("Evolution of PA vs other states", loc='left', fontsize=12, fontweight=0, color='orange')
plt.xlabel("Year")
plt.ylabel("DrugReports")
多子图
需要注意,X轴和Y轴的刻度大小需要严格一致,不然会带来误导。
# 导入包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 导入数据集并转成方便作图的格式
Dataset = pd.read_csv('data/Drugs.csv')
group = Dataset.groupby(['YYYY','State']).agg('sum').reset_index()
df = group.pivot(index='YYYY', columns='State', values='DrugReports').reset_index()
# 初始化画布的设定
plt.style.use('seaborn-darkgrid') # 风格
palette = plt.get_cmap('Set1') # 颜色卡
plt.figure(figsize=(15, 10)) # 画布大小
# 绘制
num=0
for column in df.drop('YYYY', axis=1):
num+=1
# 设定子图在画布的位置
plt.subplot(3,3, num)
# 画线图
plt.plot(df['YYYY'], df[column], marker='', color=palette(num), linewidth=1.9, alpha=0.9, label=column)
# 设定子图的X轴和Y轴的范围,注意,这里所有的子图都是用同一套X轴和Y轴
plt.xlim(2009.3,2017.3)
plt.ylim(0,50000)
# 添加每个子图的标题
plt.title(column, loc='left', fontsize=12, fontweight=0, color=palette(num) )
# 添加整个画布的标题
plt.suptitle("How many DrugReports the 5 states have in past few years?", fontsize=13, fontweight=0, color='black', style='italic', y=0.95)
# 添加整个画布的横纵坐标的名称
plt.text(2014, -9500, 'Year', ha='center', va='center')
plt.text(1998, 60000, 'DrugReports', ha='center', va='center', rotation='vertical')
# 导入包
import numpy as np
import matplotlib.pyplot as plt
# 创建数据
x=range(1,15)
y=[1,4,6,7,4,9,3,2,4,1,5,4,8,7]
# 绘图
# facecolor:控制填充颜色,red/skyblue/blue 等
# alpha: 控制填充透明度
# hatch: 控制阴影式样{'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
plt.fill_between( x, y, facecolor="skyblue", alpha=0.4, hatch='/')
plt.show()
# 在填充的基础上,添加一条折线,图形更加清晰
plt.fill_between( x, y, facecolor="skyblue", alpha=0.2)
plt.plot(x, y, color="skyblue", alpha=0.6, linewidth=1.5) # 线的更多设置可以参考 line plot文档
plt.show()
# library
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-darkgrid') # 风格
plt.figure(figsize=(10, 6)) # 画布大小
# 方式一, y由三个序列组成
x=range(1,6)
y=[ [1,4,6,8,9], [2,2,7,10,12], [2,8,5,10,6] ]
# 绘图
plt.stackplot(x,y, labels=['A','B','C'])
plt.legend(loc='upper left')
plt.show()
# 导入包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 导入数据集并转成方便作图的格式
Dataset = pd.read_csv('data/Drugs.csv')
group = Dataset.groupby(['YYYY','State']).agg('sum').reset_index()
df = group.pivot(index='YYYY', columns='State', values='DrugReports').reset_index()
plt.style.use('seaborn-darkgrid') # 风格
plt.figure(figsize=(10, 6)) # 画布大小
plt.stackplot(df['YYYY'],df['KY'],df['OH'],df['PA'],df['VA'],df['WV'], labels=df.iloc[:, 1:6].columns)
plt.legend(loc='upper left')
plt.show()
import seaborn as sns
df = pd.read_csv('data/iris.csv')
#根据分类变量分组绘制一个纵向的小提琴图:
sns.violinplot( x=df['species'],y=df["sepal_length"],inner='quartile' )#x代表不同的类别特征,y代表连续特征,inner代表在小提琴图中显示四分位数线
tips = pd.read_csv('data/tips.csv')
#根据2个分类变量嵌套分组绘制一个小提琴图
ax = sns.violinplot(x="day", y="total_bill", hue="smoker",data=tips, palette="muted")
#绘制分割的小提琴图以比较不同的色调变量
ax = sns.violinplot(x="day", y="total_bill", hue="smoker",data=tips, palette="muted", split=True)
import seaborn as sns
sns.set(style="whitegrid")
tips = pd.read_csv('data/tips.csv')
#根据分类变量分组绘制一个纵向的箱型图
ax = sns.boxplot(x="day", y="total_bill", data=tips)
# 根据2个分类变量嵌套分组绘制一个箱型图
ax = sns.boxplot(x="day", y="total_bill", hue="smoker",data=tips, palette="Set2")
# 使用 swarmplot() 展示箱型图顶部的数据点
ax = sns.boxplot(x="day", y="total_bill", data=tips)
ax = sns.swarmplot(x="day", y="total_bill", data=tips, color=".25")
import pandas as pd
from sklearn.datasets import load_boston
boston=load_boston()
y = boston['target']
f, axs = plt.subplots(3,1,figsize=(10,10))
# 计数标准直方图
sns.histplot(y,stat='count',ax=axs[0])
# 归一化的直方图
sns.histplot(y,stat='probability',ax=axs[1])
# 在直方图上同时画出密度曲线
sns.histplot(y,stat='probability',kde=True,ax=axs[2])
可以使用seaborn中的kdeplot方法绘制直方图
#kdeplot()中的bw参数控制着估计值与真实数据之间的贴近程度
#它与我们的KDE图的宽度相关。它提供了默认的规则来确定一个取值
x = np.random.normal(size=100)
sns.kdeplot(x, label="bw: default")
sns.kdeplot(x, bw_method=0.2, label="bw: 0.2")
sns.kdeplot(x, bw_method=2, label="bw: 2")
plt.legend();
mean, cov = [0, 1], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, 200)
df = pd.DataFrame(data, columns=["x", "y"])
#核密度估计也适用于二元的情况。在seaborn中,这种图会以等高线的方式展示出来,我们可以用jointplot(kind="kde")来绘制
sns.jointplot(x="x", y="y", data=df, kind="kde")
可以直接用matplotlib的scatter方法绘制散点图
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
df = pd.read_csv('data\diamonds.csv').sample(1000)
# 绘制标准散点图
plt.scatter(df.carat, df.price, s=0.2)
# 用颜色区别不同类别的散点
sns.lmplot(x='carat', y='price', data=df, hue='cut', fit_reg=False)
# 类别变量的统计
res = pd.crosstab(df.cut, df.clarity)
sns.heatmap(res, cmap='Greens', annot=True)
# 类别变量和数值变量分箱统计
res = pd.crosstab(pd.qcut(df.price, 5), df.clarity)
sns.heatmap(res, cmap='Greens', annot=True)
# 数值变量之间的密度图
sns.jointplot(x=df["price"], y=df["carat"], kind='hex')
# 使用对数变换
sns.jointplot(x=np.log(df["price"]), y=np.log(df["carat"]), kind='hex')
# 使用标准差截断
s1, s2 = df.price, df.carat
s1 = s1.mask((s1>(s1.median()+1*s1.std()))|(s1<(s1.median()-s1.std())))
s2 = s2.mask((s2>(s2.median()+1*s2.std()))|(s2<(s2.median()-s2.std())))
sns.jointplot(x=s1, y=s2, kind='hex')
# 使用分位数截断
s1, s2 = df.price, df.carat
s1 = s1.mask((s1>(s1.quantile(0.5)))|(s1<(s1.quantile(0.05))))
s2 = s2.mask((s2>(s2.quantile(0.5)))|(s2<(s2.quantile(0.05))))
sns.jointplot(x=s1, y=s2, kind='hex')
可以使用matplotlib的scatter方法绘制气泡图,同时用颜色和尺寸参数控制第三,第四维度
new_feature1 = np.random.randint(0, 10, 10) # 用气泡大小显示该feature大小
new_feature2 = np.random.randint(0, 10, 10) # 用气泡深浅显示该feature大小
plt.scatter(df.carat.sample(10), df.price.sample(10), s=new_feature1*100, c=new_feature2, cmap="Blues", alpha=0.8, edgecolors="grey", linewidth=2)
在plt.scatter(df.cut.sample(10), df.price.sample(10), s=new_feature1*100, c=new_feature2, cmap="Blues", alpha=0.8, edgecolors="grey", linewidth=2)
四、展示排序信息(Ranking)
可以直接用matplotlib的bar方法绘制柱状图
# 计算分类别的平均属性值
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
pokemon = pd.read_csv('data/pokemon.csv')
data=pokemon.groupby('Type 1')['Total'].mean().sort_values(ascending=False).reset_index()
# 绘制柱状图
bars = data['Type 1']
pos = np.arange(len(bars))
plt.bar(pos, data['Total'])
plt.xticks(pos, bars,rotation=270)
plt.show()
可以使用极坐标系和多边形填充的方式绘制雷达图,具体用法如下
from math import pi
# 绘制背景,选择2只口袋妖怪,比较六维属性值
data = pokemon.loc[[0,4]]
categories=['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed']
N=6
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
ax = plt.subplot(111, polar=True)
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
plt.xticks(angles[:-1], categories)
ax.set_rlabel_position(0)
plt.yticks([20,40,60,80], ["20","40","60","80"], color="grey", size=7)
plt.ylim(0,80)
# 分别添加两个变量的雷达曲线
values= data.loc[0, ['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed','HP']]
ax.plot(angles, values, linewidth=1, linestyle='solid', label=data.loc[0,'Name'])
ax.fill(angles, values, 'b', alpha=0.1)
values= data.loc[4, ['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed','HP']]
ax.plot(angles, values, linewidth=1, linestyle='solid', label=data.loc[4,'Name'])
ax.fill(angles, values, 'r', alpha=0.1)
# 图例
plt.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
可以通过pandas.plotting中的parallel_coordinates方法绘制平行坐标图
from pandas.plotting import parallel_coordinates
import seaborn as sns
import matplotlib.pyplot as plt
data =pd.read_csv('data/iris.csv')
# Make the plot
parallel_coordinates(data, 'species', colormap=plt.get_cmap("Set2"))
plt.show()
可以使用pyplot.hlines方法来展示棒棒糖图
# 计算分类别的平均属性值
data=pokemon.groupby('Type 1')['Total'].mean().reset_index()
# 绘制棒棒糖图
data = data.sort_values(by='Total')
my_range=range(1,len(data.index)+1)
plt.hlines(y=my_range, xmin=0, xmax=data['Total'], color='skyblue')
plt.plot(data['Total'], my_range, "o")
plt.yticks(my_range, data['Type 1'])
plt.title("A vertical lolipop plot", loc='left')
plt.xlabel('Average value of Total')
plt.ylabel('Type')
# 计算分类别的平均属性值
data=pokemon.groupby('Type 1')['Total'].mean().reset_index()
# 绘制圆形柱状图
N = len(data)
bottom = 250
value = data['Total']
theta = np.linspace(0.0, 2 * pi, N, endpoint=False)
width = (2*pi) / N-0.02
plt.figure(figsize = (16, 10))
ax = plt.subplot(111, polar=True)
bars = ax.bar(theta, value, width=width, bottom=bottom)
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
ticks =data['Type 1']
for theta,tick,value in zip(theta,ticks,value):
ax.text(theta+0.03, value+380,tick)
plt.axis('off')
plt.show()
#绘制Pie chart
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots() # 1*1画布
size = 0.3
vals = np.array([[60., 32.], [37., 40.], [29., 10.]]) # 3*2 array
cmap = plt.get_cmap("tab20c") # Get a colormap instance, matplotlib.cm
outer_colors = cmap(np.arange(3)*4) # cmap([0,4,8]), len(cmap.colors) -> 20
inner_colors = cmap(np.array([1,2,5,6,9,10]))
# 第一个环
ax.pie(vals.sum(axis=1)) # wedge object 控制圆环的宽度
plt.show()
import pandas as pd
# --- dataset 1: just 4 values for 4 groups:
df = pd.DataFrame([8,8,1,2], index=['a', 'b', 'c', 'd'], columns=['x'])
# make the plot
df.plot(kind='pie', subplots=True, figsize=(8, 8))
import matplotlib.pyplot as plt
# 创建数据
names='groupA', 'groupB', 'groupC', 'groupD',
size=[12,11,3,30]
# 在中心画一个白色的圆
my_circle=plt.Circle( (0,0), 0.7, color='white')
# 画外围的饼图
plt.pie(size, labels=names, colors=['red','green','blue','skyblue'])
p=plt.gcf()
p.gca().add_artist(my_circle)
plt.show()
import matplotlib.pyplot as plt
# Make data: I have 3 groups and 7 subgroups
group_names=['groupA', 'groupB', 'groupC']
group_size=[12,11,30]
subgroup_names=['A.1', 'A.2', 'A.3', 'B.1', 'B.2', 'C.1', 'C.2', 'C.3', 'C.4', 'C.5']
subgroup_size=[4,3,5,6,5,10,5,5,4,6]
# Create colors
a, b, c=[plt.cm.Blues, plt.cm.Reds, plt.cm.Greens]
# First Ring (outside)
fig, ax = plt.subplots()
ax.axis('equal')
mypie, _ = ax.pie(group_size, radius=1.3, labels=group_names, colors=[a(0.6), b(0.6), c(0.6)] )
plt.setp( mypie, width=0.3, edgecolor='white')
# Second Ring (Inside)
mypie2, _ = ax.pie(subgroup_size, radius=1.3-0.3, labels=subgroup_names, labeldistance=0.7, colors=[a(0.5), a(0.4), a(0.3), b(0.5), b(0.4), c(0.6), c(0.5), c(0.4), c(0.3), c(0.2)])
plt.setp( mypie2, width=0.4, edgecolor='white')
plt.margins(0,0)
plt.show()
import matplotlib.pyplot as plt
from matplotlib_venn import venn2
from matplotlib_venn import venn3
venn3(subsets=[set([3, 2, 1,4,5,6]),set([2,3,4]),set([1,2,3,4,5])], set_labels=('A', 'B','C'),set_colors = ('lightpink','pink','pink'))
import matplotlib.pyplot as plt
from matplotlib_venn import venn2
from matplotlib_venn import venn3
venn2(subsets=(3, 2,4,1), set_labels=('A', 'B'),set_colors = ('r','g'))
import matplotlib.pyplot as plt
from matplotlib_venn import venn2
from matplotlib_venn import venn3
venn3(subsets=(1,2,3,4,5,6,0), set_labels=('A', 'B','C'),set_colors = ('r','g','b'))
#绘制treemap
import matplotlib.pyplot as plt
import squarify # pip install squarify (algorithm for treemap)
# Change color
squarify.plot(sizes=[13,22,10,5], label=["group A", "group B", "group C", "group D"], color=["red","green","blue", "grey"], alpha=.4 )
plt.axis('off')
plt.show()
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import squarify # pip install squarify (algorithm for treemap)</pre>
# Create a dataset:
my_values=[i**3 for i in range(1,100)]
# create a color palette, mapped to these values
cmap = matplotlib.cm.Blues
mini=min(my_values)
maxi=max(my_values)
norm = matplotlib.colors.Normalize(vmin=mini, vmax=maxi)
colors = [cmap(norm(value)) for value in my_values]
# Change color
squarify.plot(sizes=my_values, alpha=.8, color=colors )
plt.axis('off')
plt.show()