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)
依然可以獲得正確的結果;