長條圖與直方圖

Da-Wei Chiang

大綱

  • 長條圖
  • 直方圖

長條圖

  • 主要繪製類別型資料型態
  • 可由次數分配表繪製

長條圖

import matplotlib.pyplot as plt  #引用

plt.bar(group_number, data, color)
In [114]:
## 範例 - 假資料

import matplotlib.pyplot as plt
from pylab import mpl

plt.title("Example", fontsize=24)
plt.bar([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], color=["black", 'blue', 'red', 'yellow', 'orange'])
plt.xticks([1, 2, 3, 4, 5], ['one', 'two', 'three', 'four', 'five'], fontsize=14)
plt.yticks(fontsize=12)
plt.show()

設定文字

plt.text(x, y, "文字")
In [115]:
## 範例 - 假資料

import matplotlib.pyplot as plt
from pylab import mpl

plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號

plt.title("Example", fontsize=24)
plt.bar([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], color=["black", 'blue', 'red', 'yellow', 'orange'])
plt.xticks([1, 2, 3, 4, 5], ['one', 'two', 'three', 'four', 'five'], fontsize=14)

plt.text(0.9, 10, "10")
plt.text(1.9, 20, "20")
plt.text(2.9, 30, "30")
plt.text(3.9, 40, "40")
plt.text(4.9, 50, "50")

plt.xticks(fontsize=14)
plt.yticks(fontsize=12)
plt.show()
In [106]:
## 查看資料

import pandas as pd

data = pd.read_csv('BarChart_Data.csv')
data
Out[106]:
統計年度 按照別 區域別 出生者性別 生母原屬國籍(地區) 生母年齡 生母教育程度 嬰兒出生數
0 108 按發生日期分 新北市板橋區 本國 15~19歲 高中畢業 2
1 108 按發生日期分 新北市板橋區 本國 15~19歲 國中畢業 15
2 108 按發生日期分 新北市板橋區 本國 20~24歲 大學畢業 22
3 108 按發生日期分 新北市板橋區 本國 20~24歲 專科畢業 6
4 108 按發生日期分 新北市板橋區 本國 20~24歲 高中畢業 67
... ... ... ... ... ... ... ... ...
21834 108 按發生日期分 連江縣東引鄉 本國 40~44歲 碩士畢業 1
21835 108 按發生日期分 連江縣東引鄉 大陸地區 25~29歲 專科畢業 1
21836 108 按發生日期分 連江縣東引鄉 大陸地區 30~34歲 大學畢業 1
21837 108 按發生日期分 連江縣東引鄉 大陸地區 30~34歲 國小畢業以下 1
21838 108 按發生日期分 連江縣東引鄉 東南亞地區 25~29歲 國中畢業 1

21839 rows × 8 columns

練習

  • 請繪製男、女嬰兒出生總人數的長條圖

水平長條圖

import matplotlib.pyplot as plt  #引用

plt.barh(group_number, data, color)
In [2]:
## 範例 - 假資料

import matplotlib.pyplot as plt
from pylab import mpl

plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號

plt.title("Example", fontsize=24)
plt.barh([1, 2, 3, 4, 5], [10, 20, 30, 40, 50], color=["black", 'blue', 'red', 'yellow', 'orange'])
plt.yticks([1, 2, 3, 4, 5], ['one', 'two', 'three', 'four', 'five'], fontsize=14)
plt.text(10, 0.9, "10")
plt.text(20, 1.9, "20")
plt.text(30, 2.9, "30")
plt.text(40, 3.9, "40")
plt.text(50, 4.9, "50")
plt.xticks(fontsize=14)
plt.yticks(fontsize=12)
plt.show()

練習

  • 請繪製這份資料中男女比例的水平長條圖

分組長條圖

  • 依據兩類別資料觀察資料狀況

    • 堆疊長條圖(Clustered Bar Graph)
    • 集群長條圖(Stacked Bar Graph)
  • 會使用到累計次數函數

    • dataframe_Variable.cumsum()
In [106]:
## cumsum函數範例

import random
import pandas as pd

rand_data = [random.randint(1, 10) for i in range(1, 11)]
dic_data = {
    "count": rand_data
}
print(rand_data)
df = pd.DataFrame(dic_data)

df.cumsum()
[2, 8, 1, 7, 9, 4, 8, 10, 10, 7]
Out[106]:
count
0 2
1 10
2 11
3 18
4 27
5 31
6 39
7 49
8 59
9 66
In [158]:
## 範例 - 堆疊長條圖
import pandas as pd

data = {
    "gender": ["男", "女", "男", "女", "女", "男", "男", "男", "女", "女"],
    "marriage": ["已婚", "已婚", "已婚", "未婚", "已婚", "未婚", "未婚", "未婚", "已婚", "已婚"]
}

df = pd.DataFrame(data)
df_group = df.groupby(["gender", "marriage"])
#df_group["gender"].count()
## 注意: 畫累積次數需注意繪圖順序,累計先畫才不會覆蓋資料
plt.bar(list(range(1, len(set(data))+1)), \
    [df_group["gender"].count()[:2:].cumsum()[1], df_group["gender"].count()[2::].cumsum()[1]], label="未婚")#注意寫法
plt.bar(list(range(1, len(set(data))+1)), df_group["gender"].count()[::2], label="已婚")
plt.xticks(list(range(1, len(set(data))+1)), ["女", "男"])

plt.text(1, 2, "4")
plt.text(1, 4.5, "1")
plt.text(2, 1, "2")
plt.text(2, 3.5, "3")
plt.legend()
plt.xlabel("Gender", fontsize=14)
plt.ylabel("Value", fontsize=14)
plt.title("Gender vs Marriage", fontsize=16)
plt.show()
In [129]:
## 集群長條圖

import pandas as pd

data = {
    "gender": ["男", "女", "男", "女", "女", "男", "男", "男", "女", "女"],
    "marriage": ["已婚", "已婚", "已婚", "未婚", "已婚", "未婚", "未婚", "未婚", "已婚", "已婚"]
}

df = pd.DataFrame(data)
df_group = df.groupby(["gender", "marriage"])

index = range(1, 5)
plt.bar(index[::2], df_group["gender"].count()[::2], label="已婚")
plt.bar(index[1::2], df_group["gender"].count()[1::2], label="未婚")
plt.xticks(index[::2], [df_group["gender"].count().index[::2][0][0], df_group["gender"].count().index[::2][1][0]])
plt.legend()
plt.xlabel("Gender", fontsize=14)
plt.ylabel("Value", fontsize=14)
plt.title("Gender vs Marriage", fontsize=16)
plt.show()

練習

直方圖

  • 主要繪製連續型資料型態
  • 可由次數分配表繪製

直方圖

import matplotlib.pyplot as plt  #引用

n, bins, patches = plt.hist(data, group_number)

# n 為資料個數
# bins 為組界
# patches 為組數
# data 為預繪製資料
# group_number 為預分組個數(若沒寫預設為10)
In [229]:
# 範例 - 假資料
import matplotlib.pyplot as plt
import random

data = [random.randint(1, 50) for i in range(50)]

n, bins, patches=plt.hist(data, 20, color="orange")
plt.xlabel("Data")
plt.ylabel("Data Count")
plt.title("Histogram", fontsize=18)
print("data:", data)
print("n:", n)
print("bins:", bins)
print("patches:", patches)
plt.show()
data: [5, 17, 22, 14, 23, 34, 14, 29, 11, 10, 25, 13, 16, 6, 14, 12, 18, 6, 27, 21, 24, 11, 5, 13, 50, 18, 17, 15, 11, 37, 34, 43, 11, 9, 42, 18, 20, 2, 18, 33, 7, 33, 10, 33, 9, 17, 14, 27, 14, 5]
n: [1. 5. 3. 6. 3. 7. 7. 2. 2. 2. 2. 1. 3. 2. 1. 0. 1. 1. 0. 1.]
bins: [ 2.   4.4  6.8  9.2 11.6 14.  16.4 18.8 21.2 23.6 26.  28.4 30.8 33.2
 35.6 38.  40.4 42.8 45.2 47.6 50. ]
patches: <BarContainer object of 20 artists>

練習資料集

In [248]:
## 查看資料

import pandas as pd

data = pd.read_csv('pokemon.csv')
data

#Total:整體強度
Out[248]:
Name Total HP Attack Defence Sp_attack Sp_defence Speed
0 Bulbasaur 318 45 49 49 65 65 45
1 Ivysaur 405 60 62 63 80 80 60
2 Venusaur 525 80 82 83 100 100 80
3 Mega Venusaur 625 80 100 123 122 120 80
4 Charmander 309 39 52 43 60 50 65
... ... ... ... ... ... ... ... ...
1040 Glastrier 580 100 145 130 65 110 30
1041 Spectrier 580 100 65 60 145 80 130
1042 Calyrex 500 100 80 80 80 80 80
1043 Mega Calyrex 680 100 165 150 85 130 50
1044 Mega Calyrex X 680 100 85 80 165 100 150

1045 rows × 8 columns

練習

  • 使用Total欄位繪製直方圖
    • 該直方圖分為10
    • 每組資料的上方均有資料個數值
  • 繪圖完後回答以下問題
    • 大多數Total資料都被歸類在哪一組?資料量為多少?
    • 哪組資料量最少?