数据可视化组队学习:《Task06 - 场景案例显神通》笔记
文章目錄
- 前言
- 1 展示趨勢變化(Evolution)
- 1.1 折線圖
- 1.1.1 簡單線圖
- 1.1.2 突出某一重點的多線圖
- 1.2 面積圖
- 1.3 堆積面積圖
- 2 展示分布關系
- 2.1 小提琴圖
- 2.2 箱型圖
- 2.3 直方圖
- 2.4 密度圖
- 3 展示相關關系
- 3.1 散點圖
- 3.2 熱力圖
- 3.3 氣泡圖
- 4 展示排序信息
- 4.1 柱狀圖
- 4.2 雷達圖
- 4.3 平行坐標圖
- 4.4 棒棒糖圖
- 4.5 圓形柱狀圖
- 5 展示組成關系
- 5.1 餅圖
- 5.2 甜甜圈圖
- 5.3 文氏圖
- 5.6 樹形圖
- 作業
前言
本文為《Task06 - 場景案例顯神通》筆記。
介紹用于不同場景的可視化圖表類型:
1)展示趨勢變化(Evolution)
2)展示分布關系(Distribution)
3)展示相關關系(Correlation)
4)展示排序信息(Ranking)
5)展示組成關系(Part of a whole)
1 展示趨勢變化(Evolution)
1.1 折線圖
通過用于呈現時間趨勢的變化(時間序列),所以x軸常用來代表時間。
使用折線圖使需要注意:
用plt繪制時,如果只輸入一列數則默認為y的值,而自動生成x。
1.1.1 簡單線圖
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('Basic line plot') # 設置標題 plt.show()1.1.2 突出某一重點的多線圖
當途中又多條線時,我們可以突出某條或幾條線。有兩種方法:
未突出重點的圖:
# 導入包 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 += 1plt.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()
突出了重點的圖:
多子圖:
多個子圖對比的時候,需要注意,X軸和Y軸的刻度大小需要嚴格一致,不然會帶來誤導。
1.2 面積圖
在折線圖下方區域填充顏色,相比于折線圖,面積圖能更明顯地反應數據的變化趨勢。
注意事項:
在python中,可以用 fill_between 和 stackplot 來實現。
這里更推薦使用 fill_between,在之后的定制化操作中更方便一點; stackplot更多的是用在堆積面積圖中。
1.3 堆積面積圖
特點如下:
stackplot函數繪制的方式有二:
- 一個X和多個Y
- 將多列Y的數據合并成一個
一個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') # 風格 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()
將多個y合并成一個:
2 展示分布關系
2.1 小提琴圖
小提琴圖是用來展示多組數據的分布狀態以及概率密度,它顯示了一個(或多個)分類變量多個屬性上的定量數據的分布,從而可以比較這些分布。
seaborn.violinplot 參數data可接受的數據類型:
dataDataFrame, array, or list of arrays, optional
參數x,y,hue的作用:
x,y是用作橫縱坐標的屬性,hue是在x,y取某組值(屬性x,屬性y)時要觀察其數據分布和概率密度的屬性。當hue屬性有不同的值時,在同一(屬性x,屬性y)情況下會展現出多個小提琴圖。
下小節的箱形圖同理。
注意事項:
在上圖中,可以看到,根據hue代表的屬性’smoker’‘的取值’‘No’和’Yes’,在每組(屬性x,屬性y)下展現了兩個小提琴圖。
2.2 箱型圖
箱形圖(或盒須圖)以一種利于變量之間比較或不同分類變量層次之間比較的方式來展示定量數據的分布。矩形框顯示數據集的上下四分位數,而矩形框中延伸出的線段(觸須)則用于顯示其余數據的分布位置,剩下超過上下四分位間距的數據點則被視為“異常值”。
作用:
同一數軸上,幾批數據的箱形圖并行排列,幾批數據的中位數、尾長、異常值、分布區間等形狀信息便一目了然。在一批數據中,哪幾個數據點出類拔萃,哪些數據點表現不及一般,這些數據點放在同類其它群體中處于什么位置,可以通過數據箱形圖的形狀看出。
箱型圖可以直接使用 seaborn.boxplot 方法來實現:
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")2.3 直方圖
直方圖只能接收數值類型的變量數據,該變量被切割成幾個箱子,每個箱子的高度代表處于分箱中的數量。
注意事項
可以使用seaborn.histplot方法繪制直方圖。
重要參數stat,element:
stat: {“count”, “frequency”, “density”, “probability”}
Aggregate statistic to compute in each bin.
- count shows the number of observations
- frequency shows the number of observations divided by the bin width
- density normalizes counts so that the area of the histogram is 1
- probability normalizes counts so that the sum of the bar heights is 1
element: {“bars”, “step”, “poly”}
Visual representation of the histogram statistic. Only relevant with univariate data.
2.4 密度圖
密度圖和直方圖很類似,同樣用來展示數值型變量的分布情況。
注意事項
可以使用 seaborn.deplot 方法繪制直方圖;
#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")3 展示相關關系
3.1 散點圖
散點圖常用于查看數值型變量之間的相關性,同時可以利用不同顏色來區分樣本所屬的類別。
注意事項
繪制散點圖時要避免Overplotting,意思是由于散點數量過多導致圖中的樣例點過度重合。
可以直接用 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)3.2 熱力圖
通常用于數值變量的總體信息,可以通過顏色深淺明顯地看出哪些數據更多。
通常和pandas一起使用。
注意事項
可以直接使用seaborn.heatmap方法繪制熱力圖,用seaborn.jointplot繪制蜂窩熱力圖:
# 類別變量的統計 res = pd.crosstab(df.cut, df.clarity) sns.heatmap(res, cmap='Greens', annot=True)補充,pd.crosstab()的用法:
補充,pd.qcut()的用法:
qcut()是按變量的數量來對變量進行分割,并且盡量保證每個分組里變量的個數相同。
在上述密度圖作圖時,由于原來的特征是長尾分布的,所以導致密度圖的偏向性很高,此時可以考慮使用對數變換、分位數截斷和標準差截斷。
其實上述三種方法,都是為了讓我們的密度圖能更好地反映出數據的有效信息。而針對于對數變換,我補充一些東西:
下圖可以看到,對數變換后數據近似于正態分布:
# 使用對數變換 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')3.3 氣泡圖
氣泡圖適用于超過二維特征的可視化,一般可以用氣泡的顏色和大小來表示第三維、第四維的特征,可以認為氣泡圖是散點圖的衍生。
注意事項
可以使用 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)4 展示排序信息
4.1 柱狀圖
柱狀圖用來展示一個類別變量和一個數值變量之間的關系,每個柱子代表一個類別,柱子的長度代表這個類別的數值。通常來說,柱狀圖是展示此類信息最有效的方式之一。
注意,直方圖展示的是某個變量取值是在某個范圍的數量。例如:[1,1,2,3,5,6]在[1,5)的取值有4個,分別是1 1 2 3 。
注意事項
可以直接用 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()4.2 雷達圖
較少使用。
可以使用極坐標系和多邊形填充的方式繪制雷達圖,具體用法如下:
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))4.3 平行坐標圖
用來比較樣本在一組數值型變量上的特征,它是雷達圖的另一種表現形式,在可視化中更推薦被使用。
注意事項
可以通過 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()
從上圖可以看到x軸上變量共用一個y坐標軸,此時因sepal_length、sepal_width、petal_length以及petal_width這四個變量的值得范圍相近,利用這種方式作出的共用y軸的平行坐標圖有著很好的可視化效果;但假如sepal_length、sepal_width、petal_length以及petal_width這些變量的值的范圍相差較大時,這種共用y軸的平行坐標圖就不再適用,此時我們需要的是y軸獨立的平行坐標圖。下面介紹的另一種方法實現的就是y軸獨立的平行坐標圖。
4.4 棒棒糖圖
棒棒糖圖本質上是柱狀圖的另一種表現形式,區別是把柱子用線和點來代替,但是從視覺上表現效果更好。
注意事項
可以使用 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')4.5 圓形柱狀圖
圓形柱狀圖相比于柱狀圖更吸引眼球,但同時也更難識別出柱子尺寸的差別,因此只有當你有大量類別需要展示,并且有一些明顯突出的類別時才會使用。
注意事項
5 展示組成關系
5.1 餅圖
餅圖在圖像上是一個被分成若干部分的圓,用于反映每個部分對于整體所占的比重。
注意事項
餅圖可以直接用 pyplot.pie 函數繪制,也可以調用pandas庫的繪圖接口 dataframe.plot,具體用法如下:
#繪制Pie chart import matplotlib.pyplot as plt import numpy as npfig, ax = plt.subplots() # 1*1畫布size = 0.3 vals = np.array([[60., 32.], [37., 40.], [29., 10.]]) # 3*2 arraycmap = 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))5.2 甜甜圈圖
甜甜圈圖和餅圖極為類似,都是用來反映幾個對象的組成比例,因而也有著相似的注意事項
注意事項
在繪圖時可以通過在餅圖的中心畫一個和底色相同的同心圓方式來繪制,具體用法如下:
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()5.3 文氏圖
文氏圖用于表示不同集合的有限集合之間所有可能的邏輯關系,每個集合用一個圓表示,圓的大小反映了該組的重要性,組與組之間通常會有交疊,交疊的部分體現了不同組之間的交叉數據。
不建議繪制超過3個集合的venn圖。
文氏圖可以利用matplotlib_venn包中的venn2和venn3方法繪制兩個集合或三個集合的之間的邏輯關系。文氏圖的數據類型可以是set或tuple
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'))5.6 樹形圖
通過矩形的面積反映其取值大小,使用配色方案,可以表示多個維度:組、子組。
注意事項
可以使用 squarify 包繪制樹圖,squarify的底層代碼也是基于matplotlib實現的:
#繪制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] # matplotlib.cm.Blues接受0~1的參數,所以需要歸一化# Change color squarify.plot(sizes=my_values, alpha=.8, color=colors ) plt.axis('off') plt.show()作業
注意,需要添加如下要素:
①添加每個子圖標題,在子圖右上方;
②添加整個畫布的總標題,在畫布左上方;
③添加X和Y軸的標簽。
總結
以上是生活随笔為你收集整理的数据可视化组队学习:《Task06 - 场景案例显神通》笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作者:曹建峰,男,腾讯研究院版权研究中心
- 下一篇: 作者:高丰,英国南安普敦大学计算机博士,