重點(diǎn)內(nèi)容:
- 數(shù)據(jù)采集及清理
- 運(yùn)用各類圖形函數(shù),調(diào)用數(shù)據(jù)繪制對(duì)應(yīng)可視化圖表
數(shù)據(jù)采集
本案例應(yīng)用的是UCI的華盛頓自行車租賃數(shù)據(jù),數(shù)據(jù)表地址如下:https://archive.ics.uci.edu/ml/datasets/Bike+Sharing+Dataset
對(duì)于在線的數(shù)據(jù)表壓縮包,需要在引用代碼中制定路徑名扛。為避免數(shù)據(jù)量過大、占用內(nèi)存資源等問題,通常會(huì)定義臨時(shí)文件夾來存放數(shù)據(jù)抚岗。
import pandas as pd #讀取數(shù)據(jù)到dataframe
import urllib #獲取url數(shù)據(jù)
import tempfile #創(chuàng)建臨時(shí)文件夾,大量臨時(shí)數(shù)據(jù)放在內(nèi)存中會(huì)占用大量資源哪怔,可以使用臨時(shí)文件來進(jìn)行儲(chǔ)存宣蔚。臨時(shí)文件不用命名,且使用后會(huì)被自動(dòng)刪除
import shutil #文件操作
import zipfile #壓縮解壓
#獲取數(shù)據(jù)
temp_dir = tempfile.mkdtemp() #建立臨時(shí)目錄认境,用于下載線上的zip數(shù)據(jù)表并解壓
data_source = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip'
zipname = temp_dir + '/Bike-Sharing-Dataset.zip' #拼接文件和路徑
try:
urllib.urlretrieve(data_source,zipname) #獲取數(shù)據(jù)
except:
urllib.request.urlretrieve(data_source,zipname)
zip_ref = zipfile.ZipFile(zipname,'r') #創(chuàng)建zipefile對(duì)象處理壓縮文件
zip_ref.extractall(temp_dir) #解壓
zip_ref.close()
#清理數(shù)據(jù)
daily_path = temp_dir + "/day.csv"
daily_data = pd.read_csv(daily_path) #讀取csv
daily_data['dteday']=pd.to_datetime(daily_data['dteday']) #把時(shí)間字符串轉(zhuǎn)換為日期格式
drop_list = ['instant','season','yr','mnth','holiday','workingday','weathersit','atemp','hum'] #去掉不關(guān)注的列
daily_data.drop(drop_list, inplace =True, axis=1)
shutil.rmtree(temp_dir) #刪除臨時(shí)文件目錄
#查看數(shù)據(jù)
daily_data.head()
數(shù)據(jù)表結(jié)果如下:
全局樣式參數(shù)配置
樣式可以做為獨(dú)立的模塊霍弹,方便后期對(duì)圖表全局的樣式進(jìn)行統(tǒng)一配置
import matplotlib
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
%matplotlib inline
#全局配置圖像
#設(shè)置圖片尺寸
matplotlib.rc('figure',figsize=(14,7)) #rc=resource configuration
#matplotlib.rc('figure',facecolor='red')
#設(shè)置全局字體
matplotlib.rc('font',size=14)
#設(shè)置背景網(wǎng)格
matplotlib.rc('axes',grid=False)
#設(shè)置背景顏色
matplotlib.rc('axes',facecolor='white')
可視化
在了解數(shù)據(jù)以及數(shù)據(jù)之間的關(guān)系以后叠赐,通過不同類型的圖表可視化數(shù)據(jù)之間的關(guān)系,說明要表達(dá)的內(nèi)容觀點(diǎn)。
用matplotlib實(shí)現(xiàn)圖表可視化分為兩塊內(nèi)容:
- 配置基礎(chǔ)圖表函數(shù)(模版化)
- 調(diào)用數(shù)據(jù)賦予給圖表变汪,生成根據(jù)數(shù)據(jù)繪制的圖表
案例:散點(diǎn)圖
- 配置散點(diǎn)圖函數(shù)模版
#散點(diǎn)圖函數(shù)模版,單獨(dú)列出便于復(fù)用
def scatterplot(x_data,y_data,x_label,y_label,title,ax = None):
if ax:
pass
else:
fig,ax = plt.subplots() #fig翘贮,ax是figure和axes的縮寫迂曲,使用該函數(shù)來確定圖的位置,fig是圖像對(duì)象佳遂,ax是坐標(biāo)軸對(duì)象
#不顯示頂部和右側(cè)的坐標(biāo)線
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.scatter(x_data,y_data,s=10,color="blue",alpha=0.7)
#添加標(biāo)題和坐標(biāo)說明
ax.set_title(title)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
- 調(diào)用數(shù)據(jù)繪制圖表
#調(diào)用數(shù)據(jù)繪制圖表营袜,觀點(diǎn):表達(dá)溫度和租車人數(shù)的正相關(guān)關(guān)系
scatterplot(x_data = daily_data['temp'],
y_data = daily_data['cnt'],
x_label = 'normalized temperature',
y_label = 'check outs', #租車量
title = 'numbers of check outs vs temperature')
圖表函數(shù)模版
下面分享一下各類圖表的函數(shù)模版,具體調(diào)用數(shù)據(jù)部分不再列出
1.雙軸曲線圖
#雙軸曲線圖
def lineplot(x_data,x_label,y1_data,y1_label,y1_color,y2_data,y2_label,y2_color,title):
ax1=plt.subplot() #一個(gè)figure里面可以包含多個(gè)axes
ax1.plot(x_data,y1_data,color=y1_color)
ax2=ax1.twinx()#關(guān)鍵函數(shù)丑罪,表示ax2和ax1共用x軸
ax2.plot(x_data,y2_data,color=y2_color)
#不顯示頂部的坐標(biāo)線
ax1.spines['top'].set_color('none')
ax2.spines['top'].set_color('none')
#添加標(biāo)題和坐標(biāo)說明
ax1.set_title(title)
ax1.set_xlabel(x_label)
ax1.set_ylabel(y1_label)
ax2.set_ylabel(y2_label)
2.直方圖
#直方圖
def histoplot(data,x_label,y_label,title):
_,ax = plt.subplots() # _,多個(gè)變量時(shí)需使用
res = ax.hist(data,color = '#539caf',bins=10) #res輸出圖形的細(xì)節(jié)值
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_title(title)
return res
3.堆疊直方圖
#堆疊直方圖,比較兩個(gè)數(shù)據(jù)的分布
def overlaid_histoplot(data1,data1_name,data2,data2_name,x_label,y_label,title):
max_nbins = 10
data_range = [min(min(data1),min(data2)),max(max(data1),max(data2))] #對(duì)齊兩組數(shù)據(jù)的起止位置
binwidth = (data_range[1] - data_range[0])/max_nbins
bins = np.arange(data_range[0],data_range[1]+binwidth,binwidth)
_,ax = plt.subplots()
ax.hist(data1,bins=bins,color = 'black',alpha=0.7,label=data1_name)
ax.hist(data2,bins=bins,color ='blue',alpha=0.7,label=data2_name)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_title(title)
ax.legend(loc='best')
4.柱狀圖
#繪制柱狀圖:數(shù)據(jù)處理荚板,按照周來查看租車量的分布趨勢
mean_data=daily_data[['weekday','cnt']].groupby('weekday').agg([np.mean,np.std])
mean_data.columns = mean_data.columns.droplevel()
#mean_data.head()#查看mean_data的數(shù)據(jù)
#定義繪制柱狀圖的函數(shù)
def barplot(x_data,y_data,x_label,y_label,title):
_,ax = plt.subplots()
ax.bar(x_data,y_data,align='center')
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_title(title)
barplot(x_data=mean_data.index.values,#為什么不用直接取weekday column?
y_data=mean_data['mean'],
x_label='day of weekdays',
y_label='number of mean check outs',
title="check outs by day of week")
5.堆積柱狀圖
#堆積柱狀圖
#數(shù)據(jù)處理吩屹,按照register和causual來查看不同類別用戶的租車量分布趨勢
mean_data_by_type =daily_data[['weekday','registered','casual']].groupby('weekday').mean()
mean_data_by_type['total']=mean_data_by_type['registered']+mean_data_by_type['casual']
mean_data_by_type['reg_%']=mean_data_by_type['registered']/mean_data_by_type['total']
mean_data_by_type['cas_%']=mean_data_by_type['casual']/mean_data_by_type['total']
#mean_data_by_type.head()#查看mean_data的數(shù)據(jù)
#定義堆積柱狀圖的函數(shù)
def stackedbarplot(x_data,x_label,y_data_list,y_data_name,y_label,colors,title):
_,ax = plt.subplots()
#循環(huán)繪制堆積柱狀圖
for i in range(0,len(y_data_list)):
if i ==0:
ax.bar(x_data,y_data_list[i],color=colors[i],align='center',label=y_data_name[i])
else:
ax.bar(x_data,y_data_list[i],bottom=y_data_list[i-1],color=colors[i],align='center',label=y_data_name[i])
#定義標(biāo)題和圖例
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.set_title(title)
ax.legend()