patches.Rectangle((x,y),width,height)参数
from matplotlib import patches
采用patches.Rectangle()绘制长方形
获得了长方形对象后,使用对画布添加对象的命令add_artist(),将矩形添加到我们的图像中;
例子:画有序条形图
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from matplotlib import patches
# step1 : 导入数据
df_raw = pd.read_excel("C:\\Users\\30565\\Documents\\Python Scripts\\data-visualization-50\\mpg_ggplot2.xlsx")
df_raw.head()

df = df_raw[['cty','manufacturer']].groupby("manufacturer").apply(lambda x:x.mean())
df

df.sort_values('cty',inplace=True) #排序
df.reset_index(inplace=True) #修正索引
# step2: 绘制有序条形图
fig,ax = plt.subplots(figsize=(16,10)) #往后均是对ax坐标系操作
# 绘制柱状图
ax.vlines(x=df.index #横坐标
,ymin=0 # 柱状图在y轴的起点
,ymax = df.cty # 柱状图在y轴的终点
,color = 'firebrick' # 柱状图的颜色
,alpha = 0.7 # 柱状图的透明度
,linewidth = 20) # 柱状图的线宽
# step3:添加文本
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,
for i, cty, in enumerate(df.cty):
ax.text(i, # 文本的横坐标位置
cty+0.5, # 文本的纵坐标位置
round(cty, 1), # 对文本中数据保留一位小数
horizontalalignment = 'center') # 相对于xy轴,水平对齐
# step4:添加补丁
# 添加绿色的补丁
p1 = patches.Rectangle((0.57, -0.005), # 矩形左下角坐标
width = 0.335, # 矩形的宽度
height = 0.13, # 矩形的高度
alpha = 0.1, # 矩阵的透明度
facecolor = 'green' # 是否填充矩阵(设置为绿色)
) # 保持矩形显示在图像最上方
# 添加红色的补丁
p2 = patches.Rectangle((0.124, -0.005), # 矩形左下角坐标
width = 0.446, # 矩形的宽度
height = 0.13, # 矩形的高度
alpha = 0.1, # 矩阵的透明度
facecolor = 'red' # 是否填充矩阵(设置为红色)
) # 保持矩形显示在图像最上方
# 将补丁添加至画布
fig.add_artist(p1) # 获取子图,并且将补丁添加至子图
fig.add_artist(p2) # 获取子图,并且将补丁添加至子图
# step5:装饰
ax.set(ylabel='Miles Per Gallon',ylim=(0, 30))
# 横坐标的刻度标尺
plt.xticks(df.index, # 横坐标的刻度位置
df.manufacturer.str.upper(), # 刻度标尺的内容(先转化为字符串,再转换为大写)
rotation = 60, # 旋转角度
horizontalalignment = 'right', # 相对于刻度标尺右移
fontsize = 12) # 字体尺寸
plt.title('Bar Chart for Highway Mileage', # 子图标题名称
fontdict = {'size': 22}) # 标题字体尺寸
plt.show() # 显示图像

观察 patches.Rectangle((x,y),width,height)参数
发现其中的x,y和坐标轴中的x,y是不一致的,也就是我们建立的坐标轴是没用的!
我们发现,x,y,width,height均是小于1的数据,通过测试发现,其实整个画布的左下角坐标是(0,0),width=1,height=1
如

问题1 :请使用Rectangle和add_artist,画出NASSAN和TOYOTA柱子之间,和NASSAN一样高的长方形
p0 = patches.Rectangle((0.62, 0.127), # 矩形左下角坐标
width = 0.037, # 矩形的宽度
height = 0.453, # 矩形的高度
alpha = 0.1, # 矩阵的透明度
facecolor = 'blue' # 是否填充矩阵(设置为绿色)
) # 保持矩形显示在图像最上方

问题2: 之前学过add_patch(),那么这里可以用add_patch()替换?
p1 = patches.Rectangle((-2.0, -1), # 补丁左下角的坐标
width = .3, # 补丁的宽度
height = 3, # 补丁的高度
alpha = .2, # 补丁的透明度
facecolor = 'red') # 补丁内部的颜色
p2 = patches.Rectangle((1.5, 27), # 补丁左下角的坐标
width = .8, # 补丁的宽度
height = 5, # 补丁的高度
alpha = .2, # 补丁的透明度
facecolor = 'green') # 补丁内部的颜色
plt.gca().add_patch(p1) # 获取子图,并且将补丁添加至子图
plt.gca().add_patch(p2) # 获取子图,并且将补丁添加至子图

这里也遇到过:
def encircle(x, y, ax=None, **kw):
if not ax: ax = plt.gca() # 如果没有子图对象,那么就创建一个新的子图对象
# np.c_中的c是column(列)的缩写,是按列叠加两个矩阵的意思,也可以说是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等,类似于pandas中的merge()。
p = np.c_[x, y]
hull = ConvexHull(p) # 将数据集输入到ConverHull中,自动生成凸包类型的对象(hull)
ploy = plt.Polygon(p[hull.vertices, :], **kw) # 利用plt.Polygon绘制多边形
ax.add_patch(ploy) # 将多边形ploy修补到当前子图中

无论是plt.gca().add_patch()或者是ax.add_patch()操作对象均是ax,也就是坐标轴内的范围和标题/坐标轴的名称这些字,但是不包括名称后面的画布
因此ax.add_patch()只能对坐标轴内的范围有效,因此我们相对轴外的范围(画布的领域)进行操作,需要对fig操作!
而fig上是没有add_patch()这个方法的,因此只能采用add_artist(),如
fig.add_patch(p0)

相对的,ax上却可以使用add_artist(),其功能和add_patch()一样,知识在轴内显示图像,如
p1 = patches.Rectangle((-2.0, -1), # 补丁左下角的坐标
width = .3, # 补丁的宽度
height = 3, # 补丁的高度
alpha = .2, # 补丁的透明度
facecolor = 'red') # 补丁内部的颜色
p2 = patches.Rectangle((1.5, 27), # 补丁左下角的坐标
width = .8, # 补丁的宽度
height = 5, # 补丁的高度
alpha = .2, # 补丁的透明度
facecolor = 'green') # 补丁内部的颜色
# plt.gca().add_patch(p1) # 获取子图,并且将补丁添加至子图
# plt.gca().add_patch(p2) # 获取子图,并且将补丁添加至子图
plt.gca().add_artist(p1)
plt.gca().add_artist(p2)
依然可以获得正确的结果;

浙公网安备 33010602011771号