程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python數據分析 ——Matplotlib數據可視化

編輯:Python

Matplotlib使用和Matlab中繪圖方法類似,如果使用過Matlab會更容易理解一些。

目錄

1.前言

2.Matplotlib概念

3.Matplotlib.pyplot基本使用

3.數據展示

3.1如何選擇展示方式

3.2繪制折線圖

3.3繪制柱狀圖

3.3.1普通柱狀圖

3.3.2堆疊柱狀圖

 3.3.3分組柱狀圖

3.3.4餅圖

4.繪制子圖


1.前言

        數據展示,即數據可視化,是數據分析的第五個步驟,大部分人對圖形敏感度高於數字,好的數據展示方式能讓人快速發現問題或規律,找到數據背後隱藏的價值。

2.Matplotlib概念

        Matplotlib 是 Python 中常用的 2D 繪圖庫,它能輕松地將數據進行可視化,作出精美的圖表。Matplotlib 模塊很龐大,其中最常用的一個子模塊是 pyplot,通常以一下方式將其導入:

 import matplotlib.pyplot as plt

        因為在程序中經常使用,所以給 matplotlib.pyplot 起了個別名plt,以減少大量重復代碼

3.Matplotlib.pyplot基本使用

        pyplot 中最基礎的作圖方式是以點作圖,即給出每個點的坐標,pyplot 會將這些點在坐標系中畫出,並用線將這些點連起來。以正弦函數為例,用 pyplot 畫出圖像:

代碼段1:

 import numpy as np
 import matplotlib.pyplot as plt
 ​
 x = np.arange(0,2*np.pi,0.1) #生成一個0到2pi、步長為0.1的數組x
 y = np.sin(x) #將x的值傳入正弦函數,得到對應的值存入數組y
 plt.plot(x,y) #傳入plt.plot(),將x,y轉換成對應坐標。
 plt.show() #顯示圖像

        上面程序畫出了以下圖像:

        注:選擇x的步長為0.1是為了讓每個點間隔較小,讓圖像更加接近真實情況,否則如果步長過大,則會變成折線,若步長為1則會變成以下情況:

        除了 np.sin()方法外,numpy 中也有 np.cos()np.tan()等計算三角函數的方法。上面這些方法,最重要的是 plt.plot()方法,plt.plot()方法可以接收任意對數的 x 和 y ,它會將這些圖像在一張圖上都畫出來,例如在原來的正弦圖像上增加余弦圖像,可以這樣寫:

 import numpy as np
 import matplotlib.pyplot as plt
 ​
 x = np.arange(0,2*np.pi,0.1) #生成一個0到2pi,步長為0.1的數組x
 y1 = np.sin(x) #將x的值傳入正弦函數,得到對應的值存入數組y1
 y2 = np.cos(x) #將x的值傳入余弦函數,得到對應的值存入數組y1
 plt.plot(x,y1,x,y2) #傳入plt.plot(),將(x,y1)、(x,y2)轉換成對應坐標。
 plt.show() #顯示圖像

        以上程序公用了同一個x,當然也可以重新定義一個新的 x,最終得到的圖像如下。

         代碼段2使用一次 plt.plot()方法直接將兩個數字轉換成對應坐標,當然也可以調用兩次,以下兩行代碼和上面第7行代碼是等價的。

 plt.plot(x,y1)
 plt.plot(x,y2)

        對每一對 x 和 y,有一個可選格式化參數,進行指定線條的顏色、點標記和線條的類型。

代碼段3:

 import numpy as np
 import matplotlib.pyplot as plt
 ​
 x = np.arange(0,2*np.pi,0.1) #生成一個0到2pi,步長為0.1的數組x
 y1 = np.sin(x) #將x的值傳入正弦函數,得到對應的值存入數組y1
 y2 = np.cos(x) #將x的值傳入余弦函數,得到對應的值存入數組y1
 plt.plot(x,y1,'ro--',x,y2,'b*-.') #將(x,y1)、(x,y2)轉換成對應坐標,並選用格式化參數
 plt.show() #顯示圖像

        將代碼段2傳入了格式化參數後,最終圖像如下所示:

         以其中的參數'ro--'為例,它分為三部分:r 代表紅色(red),o 代表在坐標點采用圓點標記,-- 代表虛線。'ro--'整體來說就是線條為虛線、坐標點標記為圓點。格式化參數這三部分都是可選的,即傳入一部分也是可以的,並且沒有順序要求,格式化參數常用的選型及含義如下表所示:

顏色點標記線條類型bblue 藍“.”點“:”..........ggreen 綠“,”像素點‘-.’_._._rred 紅“o”圓圈'--'-------ccyam 藍綠“v”向下的三角‘-’——mmaggnta 洋紅“^”向上的三角yyellow 黃“<”向左的三角kblack 黑“>”向右的三角wwhite 白"*"星星“+”加“×”乘

3.數據展示

3.1如何選擇展示方式

        我們通過數據分析來進行決策,那麼使用合適的圖表來准確地展示數據是至關重要的。實際使用中,我們會用到各種各樣地幾十種圖表,按照數據展示的目標可以把它們分為五種,分別是:趨勢、比較、構成、分布和聯系。

  • 趨勢:最常見的一種時間序列關系,關心數據如何隨時間變化,趨勢裡的圖標能直觀反映出每年、每月、每天的變化趨勢,增長、減少、上下波動還是基本不變,最常見的是折線圖,它能很好地表現指標隨時間呈現的趨勢。
  • 構成:主要關注每個部分整體的占比,如果逆向分析的目標如“份額”、“百分比”等。展示構成關系的圖表類型,最常見的是餅圖。
  • 比較:可以展示某個維度上的排列順序,分析某維度之間的對比是差不多,還是“大於”、“小於”,比如分析男生和女生的身高差別。
  • 分布:當你關心數據集中,頻率、分布時,比如根據地理位置數據,通過地圖來展示不同分布特征。比較常用的圖表有地圖、直方圖、散點圖。
  • 聯系:主要查看兩個變量之間是否表達出我們所要證明的相關關系,比如預期銷售額可能隨著優惠折扣的增長而增長,常用於表打“與......有關”、“隨......而增長”、“隨......而不同”等維度的關系。

        在進行數據可視化時,要先明確分析的目標,再來選擇五種合適的分類,最後選擇某個分類裡合適的圖表類型。

3.2繪制折線圖

        其實在前面已經用過折線圖了,就是使用 plot.plot() 方法。之前我們傳入的時x和y坐標點,而折線圖的 x 和 y 分別是時間點和對應的數據,下面以兩個商品的銷量走勢為例:

import numpy as np
import matplotlib.pyplot as plt
x = ['周一','周二','周三','周四','周五','周六','周日']
y1 = [61,42,52,72,86,91,73]
y2 = [23,26,67,38,46,55,33]
#傳入label參數
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
plt.plot(x, y1, label='商品A') #增加折線圖例“商品A”
plt.plot(x, y2, label='商品B') #增加折線圖例“商品B”
#設置x軸標簽
plt.xlabel('時間')
plt.ylabel('銷量')
#設置圖表標題
plt.title('商品銷量對比圖')
#顯示圖例、圖像
plt.legend(loc='best') #顯示圖例,並設置在“最佳位置”
plt.show()

得到的圖像如下圖所示:

       因為上圖中有中文,所以通過 plt.rcParams['font.family'] = ['SimHei'] 來設置中文字體來防止亂碼,如果想設置其他字體只需將 SimHei(黑體)替換成相應的名稱即可。通過一下代碼獲得,自己編譯器所在環境安裝的字體:

import matplotlib.font_manager as fm
for font in fm.fontManager.ttflist:
print(font.name)

        圖例位置是一個可選參數,默認 matplotlib 會自動選擇合適位置,也可以指定其他位置。具體的如下表所示:

plt.legend() 方法的 loc 參數選擇參數含義參數含義best最佳位置center居中upper right右上角center right靠右居中upper left左上角center left靠左居中lower left左下角lower center靠下居中lower right右下角upper center靠上居中

3.3繪制柱狀圖

        柱狀圖描述的是分類數據,展示的是每一類的數量。柱狀圖分為很多種,有普通柱狀圖、堆疊柱狀圖、分組柱狀圖等。

3.3.1普通柱狀圖

        普通柱狀圖調用 plt.bar() 方式實現。我們至少需要傳入兩個參數,第一個參數是 x 軸上刻度的標簽序列(列表、元組、數組等),第二個參數用於指定每個柱子的高度,也就是具體的數據。下面以一個班級體育課選課的情況為例:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
name = ['乒乓球','羽毛球','網球']
nums = [26,20,19]
plt.bar(name, nums)
plt.show()

 得到如下圖像:

         plt.bar() 前兩個參數是必選的,當然還有一些可選參數,常用的有 width 和 color ,分別是用於設置柱子的寬度(默認0.8)和顏色。比如我們將柱子寬度改成0.6,將柱子的顏色設成好看的天藍色只需將 plt.bar() 改為 plt.bar(names, nums, width=0.6, color='skyblue') 即可。之前在折線圖部分用到的 plt.xlabel() 、plt.ylabel() 、plt.title() 和 plt.legend() 方法都是通用方法,並不局限於一種圖表,所有的圖表都適用。

3.3.2堆疊柱狀圖

        柱狀圖能直觀地展現出不同數據上的差異,但有時候我們需要進一步分析數據的分布,比如每門選修課的男女比例,這時就需要用到堆疊柱狀圖。下面就是進一步分析每一門選修課中男女比例為例編寫程序:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
name = ['乒乓球','羽毛球','網球']
nums_boy = [16,5,11]
nums_girl = [10,15,8]
plt.bar(name, nums_boy, width=0.6, color='skyblue', label='男')
plt.bar(name, nums_girl, bottom=nums_boy, width=0.6, color='pink', label='女')
plt.legend()
plt.show()

最終得到圖像:

        上面的代碼和普通柱狀圖相比,多調用了一次,plt.bar() 方法,並傳入了 bottom 參數,每調用一次 plt.bar() 方法都會畫出對應的柱狀圖,而 bottom 參數作用就是控制柱狀圖低端的位置。我們將前一個柱狀圖的高度傳進去,這樣就形成了堆疊柱狀圖。而如果沒有 bottom 參數,後面的圖形會蓋在原來的圖形之上,就像下面這樣:

 3.3.3分組柱狀圖

        分組柱狀圖經常用於不同組間數據的比較,這些組都包含了相同分類的數據。先來看一下效果圖:

 繪制上圖的代碼如下:

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(3)
width = 0.3
names = ['籃球', '羽毛球', '乒乓球']
nums_boy = [16, 5, 11]
nums_girl = [10, 15, 8]
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
plt.bar(x - width / 2, nums_boy, width=width, color='skyblue', label='男')
plt.bar(x + width / 2, nums_girl, width=width, color='pink', label='女')
plt.xticks(x, names)
plt.legend()
plt.show()

        這次的方法和之前有些不同,首先使用 np.arange(3) 方法創建了一個數組 x ,值為[0,1,2]。並定義了一個變量 width 用於指定柱子的寬度。在調用 plt.bar() 時,第一個參數不再是刻度線上的標簽,而是對應的刻度。以[0,1,2]為基准,分別加上或減去柱子的寬度得到[-0.15,0.85,1,85]和[0.15,1.15,2.15],這些刻度將分別作為兩組柱子的中點,並且柱子的寬度為0.3。

         因為傳入的是刻度,而不是刻度的標簽。所以調用 plt.xticks() 方法來將 x 軸上刻度改為對應的標簽,該方法第一個參數時要改的刻度序列,第二個參數時與之對於的標簽序列。同理,使用plt.yticks() 方法來更改y軸上刻度的標簽。

3.3.4餅圖

        餅圖廣泛地應用在各個領域,用於表示不同分類的占比情況,通過弧度大小來對比各種分類。餅圖通過將一個圓餅按照分類的占比劃分成多個區塊,整個圓餅代表數據的總量,每個區塊(圓弧)表示該分類占總體的比例大小,所有區塊(圓弧)的加和等於100%。

        餅圖的繪制很簡單,只需要傳入數據和對於的標簽給 plt.pie() 方法即可。以2018年國內生產總值(GDP)三大產業的占比為例,可以畫出這樣的餅圖:

  繪制上圖的代碼如下:

import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
data = [64745.2, 364835.2, 489700.8]
labels = ['第一產業', '第二產業', '第三產業']
explode = (0.1, 0, 0)
plt.pie(data, explode=explode, labels=labels,autopct='%0.1f%%')
plt.show()

        plt.pie() 方法的第一個參數是繪圖需要的數據;參數 explode 是可選參數,用於突出顯示某一區塊,默認數值都是0,數值越大,區塊抽離越明顯;參數 lables 是數據對應的標簽;參數 autopct 則給餅圖自動添加百分比顯示。

參數 autopct 的格式用到了字符串格式化輸出的知識,代碼中 '%0.1f%%' 可以分成兩部分。一部分是 %0.1f 表示保留一位小數,同理 %0.2f 表示保留兩位小數;另一部分是 %% ,它表示輸出一個 %,因為% 在字符串格式化輸出中有特殊的含義,所以想要輸出 % 就得寫成 %% 。所以,'%0.1f%%' 的含義是保留一位小數的百分數,例如:66.6%。

4.繪制子圖

        Matplotlib 提供了子圖的概念,通過使用子圖,可以在一張圖裡繪制多個圖表。在 matplotlib 中,調用 plt.subplot() 方法來添加子圖。plt.subplot() 方法的前兩個參數分別是子圖的行數和列數,第三個參數是子圖的序號(從1開始)。

ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 2)
ax3 = plt.subplot(2, 2, 3)
ax4 = plt.subplot(2, 2, 4)

        plt.subplot(2,2,1) 的作用是生成一個兩行兩列的子圖,並選擇其中序號為1的子圖,所以上面四行代碼將一張圖分成了4個子圖,並用1、2、3、4來選擇對應的子圖。

        我們也可以繪制不規則的子圖,比如上面兩張子圖,下面一張子圖。方法如下:

ax1 = plt.subplot(2, 2, 1)
ax2 = plt.subplot(2, 2, 2)
ax3 = plt.subplot(2, 1, 2)

         之所以第三行代碼是 plt.subplot(2, 1, 2) ,因為子圖序號是獨立的,與之前創建的子圖沒有關系。plt.subplot(2, 2, 1) 選擇並展示了2*2的子圖中的第一個。plt.subplot(2, 2, 2) 選擇並展示了2*2的子圖中的第二個,它們兩個合起來占了2*2子圖的第一行。而 plt.subplot(2, 1, 2) 則是生成了兩行一列的子圖,並選擇了第二行。即占滿第二行的子圖,正好填補了之前2*2子圖第二行剩下的空間,因此生成的圖表是這樣的:

         圖表的框架畫好了,就可以往裡面填充圖像了,之前調用的是 plt 上的方法繪圖,只要將其改成 plt.subplot() 方法的返回值上調用相應的方法繪圖即可。 舉個栗子,下面是在一張圖上繪制了 sin、cos 和 tan 三個函數的圖像的代碼:

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['SimHei'] #設置字體防止亂碼
x = np.arange(0, 2 * np.pi, 0.1)
plt.suptitle('三角函數可視化')
ax1 = plt.subplot(2,2,1)
ax1.set_title('sin函數')
y1 = np.sin(x)
ax1.plot(x,y1)
ax2 = plt.subplot(2,2,2)
ax2.set_title('cos函數')
y2 = np.cos(x)
ax2.plot(x,y2)
ax3 = plt.subplot(2,1,2)
ax3.set_title('tan函數')
y3 = np.tan(x)
ax3.plot(x,y3)
plt.show()

  得到的圖像是:

        上面程序中,使用 set_title() 方法為每個子圖設置單獨的標題。需要注意的是,如果想要給帶有子圖的圖表設置總的標題的話,不是使用的 plt.titie() 方法,而是通過 plt.suptitile() 方法來設置帶有子圖的圖表標題。 

 


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved