目錄
- 前言
- 1.基礎知識
- 1.1 圖形繪制
- 1.2 標題、標簽、坐標軸刻度
- 1.2.1 標題的設定
- 1.2.2 標簽的設定
- 1.2.3 坐標軸刻度的設定
- 1.3 圖例
- 1.4 脊柱移動
- 1.5 圖片保存
- 2.風格和樣式
- 2.1 顏色、線形、點形、線寬、透明度
- 2.2 更多屬性設定
- 3.訓練場
- 3.1 繪制如下圖形
- 3.2 根據提供資料,進行分組聚合運算,繪制如下圖形
前言
本文其實屬于:Python的進階之道【AIoT階段一】的一部分內容,本篇把這部分內容單獨截取出來,方便大家的觀看,本文介紹Matplotlib資料可視化入門,后續還會單獨發一篇Matplotlib資料可視化高級以及Matplotlib資料可視化進階內容供讀者學習,
在資料分析與機器學習中,我們經常要用到大量的可視化操作,一張制作精美的資料圖片,可以展示大量的資訊,一圖頂千言,

而在可視化中,Matplotlib算得上是最常用的工具,Matplotlib 是 python 最著名的繪圖庫,它提供了一整套 API,十分適合繪制圖表,或修改圖表的一些屬性,如字體、標簽、范圍等,

Matplotlib 是一個 Python 的 2D 繪圖庫,它互動式環境生成出版質量級別的圖形,通過 Matplotlib這個標準類別庫,開發者只需要幾行代碼就可以實作生成繪圖,折線圖、散點圖、柱狀圖、餅圖、直方圖、組合圖等資料分析可視化圖表,

🌟 學習本文之前,需要先自修:NumPy從入門到進階,pandas從入門到進階本文中很多的操作在 NumPy從入門到進階 ,pandas從入門到進階二文中有詳細的介紹,包含一些軟體以及擴展庫,圖片的安裝和下載流程,本文會直接進行使用,
下載 M a t p l o t l i b Matplotlib Matplotlib 見博客:matplotlib的安裝教程以及簡單呼叫,這里不再贅述
1.基礎知識
1.1 圖形繪制
🚩資料可視化其實就是把抽象不容易看出規律的資料轉換為人眼更能接受的圖片,下面我們來簡單的繪制一個圖形
import numpy as np
import matplotlib.pyplot as plt
# 橫坐標
# 等引數列,把[0,2π]等分成100份
x = np.linspace(0, 2 * np.pi, 100)
# 縱坐標:正弦波; x:Numpy陣列
y = np.sin(x)
# 畫線形圖
plt.plot(x, y)

接下來我們對這個圖進行簡單的引數設定:
# 設定橫坐標的范圍是 -1 ~ 10
plt.xlim(-1, 10)
# 設定縱坐標的范圍是 -1.5 ~ 1.5
plt.ylim(-1.5, 1.5)
# 設定網格線,網格線顏色設為綠色,透明度為0.5,線的樣式為虛線:--,寬度為2
plt.grid(color = 'green', alpha = 0.5, linestyle = '--', linewidth = 2)
plt.plot(x, y)

1.2 標題、標簽、坐標軸刻度
1.2.1 標題的設定
🚩標題其實就是圖片的名字,即這個圖片是什么,表達的是什么樣的含義
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 圖的標題設定為 Sin(x),字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('Sin(x)', fontsize = 18, color = 'red', pad = 20)

那么我們是否可以把標題設定為中文呢?
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 圖的標題設定為正弦波,字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)

WTF??? 居然亂碼報錯了,下面我們來介紹解決的方法:
首先先來查看一下我們電腦都有哪些字體:
# 找到電腦的字體
from matplotlib import font_manager
fm = font_manager.FontManager()
# 用串列生成式獲取字體
[font.name for font in fm.ttflist]

我們的電腦有很多的字體,這個截圖只展示了一部分字體,其中有英文字體,中文字體…
我們可以找找有沒有
K
a
i
T
i
KaiTi
KaiTi(楷體)
瀏覽器頁面搜索(Google瀏覽器),按下 Ctrl + F,輸入 KaiTi:

或者你搜宋體什么的都是可以的,一般電腦都會有這些字體,接下來回到我們的報錯代碼上,我們來設定我們的字體:
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 設定字體為楷體
plt.rcParams['font.family'] = 'KaiTi'
# 圖的標題設定為正弦波,字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)

這下 正弦波 被顯示出來了,可是還是有報錯,這波啊~,這波叫做對了但沒完全對,我們通過觀察影像可以發現是負號有出了問題:

害,多大點事兒嘛,有 bug 咋們就接著改就完了:
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 設定字體為楷體
plt.rcParams['font.family'] = 'KaiTi'
# 設定數字的負號
plt.rcParams['axes.unicode_minus'] = False
# 圖的標題設定為正弦波,字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)

ok,這下所有的 bug 就完美的解決了,但是總看的不得勁,字體有點小了,看起來費眼睛,我們來把所有的字體都變得大一點:
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 設定字體為楷體
plt.rcParams['font.family'] = 'KaiTi'
# 設定數字的負號
plt.rcParams['axes.unicode_minus'] = False
# 把所有的字體都設定成 28 大小
plt.rcParams['font.size'] = 28
# 圖的標題設定為正弦波,字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)

好家伙,又出問題了,我們的字體雖然都變大了(圖片顯示的不明顯,讀者自己執行一下代碼會有明顯的變化),但是相對應的我們的圖變小了,我們來設定一下圖片的尺寸:
# 設定圖片的大小
plt.figure(figsize = (12, 9))
# 資料還是剛付訓制的正弦圖
plt.plot(x, y)
# 設定字體為楷體
plt.rcParams['font.family'] = 'KaiTi'
# 設定數字的負號
plt.rcParams['axes.unicode_minus'] = False
# 把所有的字體都設定成 28 大小
plt.rcParams['font.size'] = 28
# 圖的標題設定為正弦波,字體大小設為18,顏色設為紅色,標題離圖片的間距為20
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)

1.2.2 標簽的設定
🚩標簽對應到我們的上圖之中其實就是橫縱坐標
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
# 設定橫坐標為 X
plt.xlabel('X')
# 設定縱坐標為 f(x) = sin(x)
plt.ylabel('f(x) = sin(x)')

看著縱坐標豎著不舒服,我們把它橫過來:
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
# 設定橫坐標為 X
plt.xlabel('X')
# 設定縱坐標為 f(x) = sin(x)
plt.ylabel('f(x) = sin(x)', rotation = 0)

縱坐標離
y
y
y軸有點近,我們繼續調整一下:
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
# 設定橫坐標為 X
plt.xlabel('X')
# 設定縱坐標為 f(x) = sin(x)
plt.ylabel('f(x) = sin(x)', rotation = 0, horizontalalignment = 'right')

1.2.3 坐標軸刻度的設定
🚩接下來我們設定刻度,上圖中的 0 2 4 6 -1.0 -0.5 0.0 0.5 1.0 其實就是刻度,因為我們現在描繪的是正弦波,對于正弦波而言,我們
y
y
y軸上的刻度其實給-1 0 1就可以了:

我們的橫坐標刻度對于正弦波而言一般是
0
,
π
2
,
π
,
3
π
2
,
2
π
0, \frac{\pi}{2}, \pi,\frac{3\pi}{2},2π
0,2π?,π,23π?,2π:
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
plt.xlabel('X')
plt.ylabel('f(x) = sin(x)', rotation = 0, horizontalalignment = 'right')
# 設定y軸上的刻度為:-1 0 1
plt.yticks([-1, 0, 1])
# 設定x軸的刻度
plt.xticks([0, np.pi / 2, np.pi, 1.5 * np.pi, 2 * np.pi])

這好像和我們希望的不太一樣,這編譯器太實誠了,直接把
π
\pi
π 帶入計算了,我們希望的顯然不是這樣,我們希望
π
\pi
π 用希臘字母進行顯示:
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
plt.xlabel('X')
plt.ylabel('f(x) = sin(x)', rotation = 0, horizontalalignment = 'right')
# 設定y軸上的刻度為:-1 0 1
plt.yticks([-1, 0, 1])
# 設定x軸的刻度
plt.xticks([0, np.pi / 2, np.pi, 1.5 * np.pi, 2 * np.pi],
[0, r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'])

當然我們可以設定顏色,比如我們設定橫坐標刻度為紅色:
plt.figure(figsize = (9, 6))
plt.plot(x, y)
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.size'] = 28
plt.title('正弦波', fontsize = 18, color = 'red', pad = 20)
plt.xlabel('X')
plt.ylabel('f(x) = sin(x)', rotation = 0, horizontalalignment = 'right')
# 設定y軸上的刻度為:-1 0 1
plt.yticks([-1, 0, 1])
# 設定x軸的刻度
plt.xticks([0, np.pi / 2, np.pi, 1.5 * np.pi, 2 * np.pi],
[0, r'$\frac{\pi}{2}$', r'$\pi$', r'$\frac{3\pi}{2}$', r'$2\pi$'],
color = 'red')

1.3 圖例
🚩圖例就是在同一個表中顯示多個圖,我們要區分它們所對應的小框框:

import numpy as np
import matplotlib.pyplot as plt
# x軸
x = np.linspace(0, 2 * np.pi)
# y軸
y = np.sin(x) # 正弦
# 繪制線形圖
# 調整尺寸
plt.figure(figsize=(9,6))
# 繪制正弦波
plt.plot(x,y)
# 繪制余弦波
plt.plot(x,np.cos(x))
plt.legend(['Sin', 'Cos'],fontsize = 18, # 字體大小
loc = 'center', # 圖例居中
ncol = 2, # 圖例展示時2個為一行
# 設定圖例的位置 [x,y,width,height]
bbox_to_anchor = [0, 1.05, 1, 0.2])
# 我們規定圖形左下角為(0,0),右上角為(1,1)
# 表示圖例的位置在(0,1.05)的位置,且我們設定了居中

1.4 脊柱移動
🚩脊柱移動翻譯成大白話就是黑色邊框的移動
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi, np.pi, 50)
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize = (9 ,6))
# plot繪制了兩個圖形,x-y成對出現就可以!!!
plt.plot(x,np.sin(x),x,np.cos(x))
# 獲取當前視圖
ax = plt.gca()
# 右邊和上面脊柱消失,白色就是消失
ax.spines['right'].set_color('white') # 白色
ax.spines['top'].set_color('#FFFFFF') # 白色
# 設定下面左邊脊柱位置,data表示資料,axes表示相對位置0~1
ax.spines['bottom'].set_position(('data', 0)) # 中間(豎直)
ax.spines['left'].set_position(('data' , 0)) # 中間(水平)
plt.yticks([-1,0,1],labels = ['-1', '0', '1'],fontsize = 18)
plt.xticks([-np.pi, -np.pi / 2, np.pi / 2, np.pi],
labels = [r'$-\pi$', r'$-\frac{\pi}{2}$', r'$\frac{\pi}{2}$', r'$\pi$'],
fontsize = 18)

1.5 圖片保存
🚩我們可以把我們繪制好的圖形進行保存:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi, np.pi, 50)
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize = (9 ,6))
# plot繪制了兩個圖形,x-y成對出現就可以!!!
plt.plot(x,np.sin(x),x,np.cos(x))
# 獲取當前視圖
ax = plt.gca()
# 右邊和上面脊柱消失,白色就是消失
ax.spines['right'].set_color('white') # 白色
ax.spines['top'].set_color('#FFFFFF') # 白色
# 設定下面左邊脊柱位置,data表示資料,axes表示相對位置0~1
ax.spines['bottom'].set_position(('data', 0)) # 中間(豎直)
ax.spines['left'].set_position(('data' , 0)) # 中間(水平)
plt.yticks([-1,0,1],labels = ['-1', '0', '1'],fontsize = 18)
plt.xticks([-np.pi, -np.pi / 2, np.pi / 2, np.pi],
labels = [r'$-\pi$', r'$-\frac{\pi}{2}$', r'$\frac{\pi}{2}$', r'$\pi$'],
fontsize = 18)
# 圖片保存到當前路徑下,命名為 1.png
plt.savefig('./1.png')

我們在保存的時候,可以修改螢屏像素密度:
d
p
i
dpi
dpi(默認為100)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi, np.pi, 50)
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize = (9 ,6))
# plot繪制了兩個圖形,x-y成對出現就可以!!!
plt.plot(x,np.sin(x),x,np.cos(x))
# 獲取當前視圖
ax = plt.gca()
# 右邊和上面脊柱消失,白色就是消失
ax.spines['right'].set_color('white') # 白色
ax.spines['top'].set_color('#FFFFFF') # 白色
# 設定下面左邊脊柱位置,data表示資料,axes表示相對位置0~1
ax.spines['bottom'].set_position(('data', 0)) # 中間(豎直)
ax.spines['left'].set_position(('data' , 0)) # 中間(水平)
plt.yticks([-1,0,1],labels = ['-1', '0', '1'],fontsize = 18)
plt.xticks([-np.pi, -np.pi / 2, np.pi / 2, np.pi],
labels = [r'$-\pi$', r'$-\frac{\pi}{2}$', r'$\frac{\pi}{2}$', r'$\pi$'],
fontsize = 18)
# 圖片保存到當前路徑下,命名為 2.png,像素密度設為 300
plt.savefig('./2.png', dpi = 300)

從兩張圖片的大小上其實就能看出清晰度的高低,因為保存的是同一張圖
當然,我們也可以保存成
p
d
f
pdf
pdf
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi, np.pi, 50)
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize = (9 ,6))
# plot繪制了兩個圖形,x-y成對出現就可以!!!
plt.plot(x,np.sin(x),x,np.cos(x))
# 獲取當前視圖
ax = plt.gca()
# 右邊和上面脊柱消失,白色就是消失
ax.spines['right'].set_color('white') # 白色
ax.spines['top'].set_color('#FFFFFF') # 白色
# 設定下面左邊脊柱位置,data表示資料,axes表示相對位置0~1
ax.spines['bottom'].set_position(('data', 0)) # 中間(豎直)
ax.spines['left'].set_position(('data' , 0)) # 中間(水平)
plt.yticks([-1,0,1],labels = ['-1', '0', '1'],fontsize = 18)
plt.xticks([-np.pi, -np.pi / 2, np.pi / 2, np.pi],
labels = [r'$-\pi$', r'$-\frac{\pi}{2}$', r'$\frac{\pi}{2}$', r'$\pi$'],
fontsize = 18)
# 圖片保存到當前路徑下,格式為 pdf,命名為 1.pdf
plt.savefig('./1.pdf')


如果你覺得白底太過于單調,我們在設定字體大小的時候可以設定顏色(改變邊框的顏色):
# 設定一個綠邊框
plt.figure(figsize = (9 ,6), facecolor = 'green')

如果我們想改變的是底色,我們可以在獲取視圖后進行更改:
# 獲取當前視圖
ax = plt.gca()
# 底色改為綠色
ax.set_facecolor('green')

查看我們可以設定哪些顏色可以撰寫代碼:
# 查看所有顏色
plt.colormaps()

2.風格和樣式
2.1 顏色、線形、點形、線寬、透明度
🚩下圖代表我們可以使用的顏色:

接下來我們結合代碼去進行講解:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 20)
y1 = np.sin(x)
y2 = np.cos(x)
# 設定顏色,線型,點型
# 繪制x,y1的圖形,顏色是 indigo,線形為'-.',影像上點的型別是五邊形'p
plt.plot(x, y1, color = 'indigo', ls = '-.', marker = 'p')
# 繪制x,y2的圖形,顏色是 #FF00EE,線形為'-',影像上點的型別是圓圈'o'
plt.plot(x, y2, color = '#FF00EE', ls = '--', marker = 'o')
# 繪制x,y1+y2的圖形,顏色是(0.2, 0.7, 0.2),線形為':',影像上點的型別是五角星'*'
plt.plot(x, y1 + y2, color = (0.2, 0.7, 0.2), marker = '*',ls = ':')
# 繪制x,y1+2*y2的圖形,線寬為3,透明度為0.7,顏色為 orange
plt.plot(x, y1 + 2 * y2, linewidth = 3, alpha = 0.7, color = 'orange') # 線寬、透明度
# 引數連用
# 繪制x,2*y1-y2的圖形,b代表color:blue;o代表marker:'o';--代表ls:'--'
plt.plot(x, 2 * y1 - y2, 'bo--')

2.2 更多屬性設定
import numpy as np
import pandas as pd
def f(x):
return np.exp(-x) * np.cos(2 * np.pi * x)
x = np.linspace(0, 5, 50)
plt.figure(figsize = (9, 6))
plt.plot(x, f(x), color = 'purple', # 線顏色
marker = 'o', # 影像中的點的形狀
ls = '--', # 線形
lw = 2, # 線寬
alpha = 0.6, # 透明度
markerfacecolor = 'red', # 點顏色
markersize = 10, # 影像中點的大小
markeredgecolor = 'green', # 點邊緣顏色
markeredgewidth = 3) # 點邊緣寬度
plt.xticks(size = 18) # 設定刻度大小
plt.yticks(size = 18)

3.訓練場
3.1 繪制如下圖形

要求:
- 設定背景顏色為:灰色
- 設定視圖顏色為:灰色
- 設定網格線顏色:白色
- 設定網格線樣式:虛線
- 函式關系如下:y = np.sin(x + i * 0.5) * (7 - i)
- 方程中的i可以給定范圍1~6,表示圖片中的6條線
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize = (9, 6), facecolor = 'gray')
def fun(x):
for i in range(1, 7):
y = np.sin(x - 0.5 * i) * (7 - i)
plt.plot(x, y)
# 畫圖范圍從 0~14,分成200份
x= np.linspace(0, 14, 200)
fun(x)
# 獲取當前視圖
ax = plt.gca()
ax.set_facecolor('gray')
# 添加網格線
plt.grid(color = 'white', linestyle = '--')

3.2 根據提供資料,進行分組聚合運算,繪制如下圖形

要求:
- 分組聚合求各個城市春夏秋冬的PM2.5的平均值
- 對分組聚合結果進行資料重塑
- 調整行索引順序按照:北京、上海、廣州、沈陽、成都
- 調整列索引順序:春夏秋冬
- 使用DataFrame方法繪制條形圖
首先我們需要下載一個 Excel 檔案:
鏈接: https://pan.baidu.com/s/1ns8p3xD_EVS2GNNKApDtLg?pwd=eu4u
提取碼: eu4u
下載完成之后,把該檔案和我們的代碼放到同一個檔案夾下,這一操作我們在之前的博客中已經反復說到,這里就不再進行演示
注:代碼處于運行中將顯示:

下列代碼運行幾十秒甚至幾分鐘都是正常的,耐心等待運行結果即可,
我們先來加載我們的資料
%%time
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_excel('./PM2.5.xlsx')
display(df.head(10))
df.shape

# 根據 城市,季節進行分組,獲取PM2.5的資料并求平均
df.groupby(by = ['城市', '季節'])['PM2.5'].mean()

資料看起來不太舒服,把它變成
D
a
t
a
F
r
a
m
e
DataFrame
DataFrame 格式,并保留兩位小數
df2 = df.groupby(by = ['城市', '季節'])[['PM2.5']].mean().round(2)
df2

資料還是看起來不美觀,資料重塑:
df2 = df2.unstack(level = -1)
df2

洗掉掉 PM2.5:
df2.columns = df2.columns.droplevel(level = 0)
df2

調整列索引的順序:
df2 = df2[list('春夏秋冬')]
df2 = df2.loc[['北京', '上海', '廣州', '成都', '沈陽']]
df2

繪圖:
plt.rcParams['font.family'] = 'KaiTi'
plt.rcParams['font.size'] = 18
df2.plot.bar(figsize = (12, 9))
plt.grid(color = 'gray', ls = '--')

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/420003.html
標籤:AI
上一篇:pandas使用replace函式移除dataframe數值資料中的逗號并基于處理后的資料生成新的整型資料列(remove comma from column values in Pandas)
下一篇:python使用openCV影像加載(轉化為灰度影像)、使用filter2D函式對影像進行銳化(Sharpen Images)
