python:matplotlib數(shù)據(jù)可視化(上)

第一章 Matplotlib 簡介

這里涉及Matplotlib 數(shù)據(jù)可視化模塊的多個方面嘲碱。 Matplotlib 能夠創(chuàng)建多數(shù)類型的圖表手蝎,如條形圖,散點圖喷兼,條形圖,餅圖后雷,堆疊圖季惯,3D 圖和地圖圖表。

首先臀突,為了實際使用 Matplotlib勉抓,我們需要安裝它。

如果你安裝了更高版本的 Python候学,你應(yīng)該能夠打開cmd.exe或終端藕筋,然后執(zhí)行:

pip install matplotlib

注意:如果上面的較短命令不工作,你可能需要執(zhí)行C:/Python34/Scripts/pip install matplotlib梳码。

如果在導(dǎo)入matplotlib時隐圾,你會收到類似『無命名模塊』和模塊名稱的錯誤,這意味著你還需要安裝該模塊掰茶。 一個常見的問題是缺少名為six的模塊暇藏。 這意味著你需要使用pip安裝six

或者濒蒋,你可以前往 Matplotlib.org 并通過訪問下載頁面下載適當(dāng)?shù)陌姹具M(jìn)行安裝盐碱。 請記住,因為你的操作系統(tǒng)為 64 位沪伙,你不一定需要 64 位版本的 Python甸各。 如果你不打算嘗試 64 位,你可以使用 32 位焰坪。 打開 IDLE 并閱讀頂部趣倾。 如果它說你是 64 位,你就是 64 位某饰,如果它說是 32 位儒恋,那么你就是 32 位。 一旦你安裝了 Python黔漂,你就做好了準(zhǔn)備诫尽,你可以編寫任何你想要的邏輯。 我喜歡使用 IDLE 來編程炬守,但你可以隨意使用任何你喜歡的東西牧嫉。

import matplotlib.pyplot as plt

這一行導(dǎo)入集成的pyplot,我們將在整個系列中使用它。 我們將pyplot導(dǎo)入為plt酣藻,這是使用pylot的 python 程序的傳統(tǒng)慣例曹洽。

plt.plot([1,2,3],[5,7,4])

接下來,我們調(diào)用plot.plot方法繪制一些坐標(biāo)辽剧。 這個.plot需要許多參數(shù)送淆,但前兩個是'x''y'坐標(biāo),我們放入列表怕轿。 這意味著偷崩,根據(jù)這些列表我們擁有 3 個坐標(biāo):1,5 2,73,4

plt.plot在后臺『繪制』這個繪圖撞羽,但繪制了我們想要的一切之后阐斜,當(dāng)我們準(zhǔn)備好的時候,我們需要把它帶到屏幕上诀紊。

plt.show()

這樣谒出,應(yīng)該彈出一個圖形。 如果沒有渡紫,有時它可以彈出到推,或者你可能得到一個錯誤。 你的圖表應(yīng)如下所示:

image

這個窗口是一個 matplotlib 窗口惕澎,它允許我們查看我們的圖形莉测,以及與它進(jìn)行交互和訪問。 你可以將鼠標(biāo)懸停在圖表上唧喉,并查看通常在右下角的坐標(biāo)捣卤。 你也可以使用按鈕。 它們可能在不同的位置八孝,但在上圖中董朝,這些按鈕在左下角。

Home(主頁)

image

一旦你開始瀏覽你的圖表干跛,主頁按鈕會幫助你子姜。 如果你想要返回原始視圖,可以單擊它楼入。 在瀏覽圖表之前單擊此按鈕將不會生效哥捕。

Forward/Back(前進(jìn)/后退)

image

這些按鈕可以像瀏覽器中的前進(jìn)和后退按鈕一樣使用。 你可以單擊這些來移回到你之前的位置嘉熊,或再次前進(jìn)遥赚。

Pan(平移)

image

你可以點擊平移按鈕,之后點擊并拖拽你的圖表阐肤。

Zoom(縮放)

image

縮放按鈕可讓你單擊它凫佛,然后單擊并拖動出要放大的方形區(qū)域讲坎。 放大需要左鍵單擊并拖動。 你也可以右鍵單擊并拖動來縮小愧薛。

Configure Subplots(配置子圖)

image

此按鈕允許你對圖形和繪圖配置各種間距選項晨炕。 點擊它會彈出:

image

每個藍(lán)色條形都是一個滑塊,它允許你調(diào)整內(nèi)邊距厚满。 其中有些現(xiàn)在沒有任何效果府瞄,因為沒有任何其他子圖碧磅。 前四個值調(diào)整圖形到窗口邊緣的邊距碘箍。 之后wspacehspace對應(yīng)于當(dāng)你繪制多個子圖時,它們的水平或豎直間距鲸郊。

Save(保存)

image

此按鈕允許你以各種形式保存圖形丰榴。

所以這是 matplotlib 的快速介紹,我們之后會涉及更多秆撮。

第二章 圖例四濒、標(biāo)題和標(biāo)簽

在本教程中,我們將討論 Matplotlib 中的圖例职辨,標(biāo)題和標(biāo)簽盗蟆。 很多時候,圖形可以不言自明舒裤,但是圖形帶有標(biāo)題喳资,軸域上的標(biāo)簽和圖例,來解釋每一行是什么非常必要腾供。

注:軸域(Axes)即兩條坐標(biāo)軸圍城的區(qū)域仆邓。

從這里開始:

import matplotlib.pyplot as plt

x = [1,2,3]
y = [5,7,4]

x2 = [1,2,3]
y2 = [10,14,12]

這樣我們可以畫出兩個線條,接下來:

plt.plot(x, y, label='First Line')
plt.plot(x2, y2, label='Second Line')

在這里伴鳖,我們繪制了我們已經(jīng)看到的東西节值,但這次我們添加另一個參數(shù)label。 這允許我們?yōu)榫€條指定名稱榜聂,我們以后可以在圖例中顯示它搞疗。 我們的其余代碼為:

plt.xlabel('Plot Number')
plt.ylabel('Important var')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

使用plt.xlabelplt.ylabel,我們可以為這些相應(yīng)的軸創(chuàng)建標(biāo)簽须肆。 接下來匿乃,我們可以使用plt.title創(chuàng)建圖的標(biāo)題,然后我們可以使用plt.legend()生成默認(rèn)圖例休吠。 結(jié)果圖如下:

image

第三章 條形圖和直方圖

這個教程中我們會涉及條形圖和直方圖扳埂。我們先來看條形圖:

import matplotlib.pyplot as plt

plt.bar([1,3,5,7,9],[5,2,7,8,2], label="Example one")

plt.bar([2,4,6,8,10],[8,6,2,5,6], label="Example two", color='g')
plt.legend()
plt.xlabel('bar number')
plt.ylabel('bar height')

plt.title('Epic Graph\nAnother Line! Whoa')

plt.show()

plt.bar為我們創(chuàng)建條形圖。 如果你沒有明確選擇一種顏色瘤礁,那么雖然做了多個圖阳懂,所有的條看起來會一樣。 這讓我們有機(jī)會使用一個新的 Matplotlib 自定義選項。 你可以在任何類型的繪圖中使用顏色岩调,例如g為綠色巷燥,b為藍(lán)色,r為紅色号枕,等等缰揪。 你還可以使用十六進(jìn)制顏色代碼,如#191970葱淳。

image

接下來钝腺,我們會講解直方圖。 直方圖非常像條形圖赞厕,傾向于通過將區(qū)段組合在一起來顯示分布艳狐。 這個例子可能是年齡的分組,或測試的分?jǐn)?shù)皿桑。 我們并不是顯示每一組的年齡毫目,而是按照 20 ~ 25,25 ~ 30... 等等來顯示年齡诲侮。 這里有一個例子:

import matplotlib.pyplot as plt

population_ages = [22,55,62,45,21,22,34,42,42,4,99,102,110,120,121,122,130,111,115,112,80,75,65,54,44,43,42,48]

bins = [0,10,20,30,40,50,60,70,80,90,100,110,120,130]

plt.hist(population_ages, bins, histtype='bar', rwidth=0.8)

plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

產(chǎn)生的圖表為:

image

對于plt.hist镀虐,你首先需要放入所有的值,然后指定放入哪個桶或容器沟绪。 在我們的例子中刮便,我們繪制了一堆年齡,并希望以 10 年的增量來顯示它們近零。 我們將條形的寬度設(shè)為 0.8诺核,但是如果你想讓條形變寬,或者變窄久信,你可以選擇其他的寬度窖杀。

第四章 散點圖

接下來,我們將介紹散點圖裙士。散點圖通常用于比較兩個變量來尋找相關(guān)性或分組入客,如果你在 3 維繪制則是 3 個。

散點圖的一些示例代碼:

import matplotlib.pyplot as plt

x = [1,2,3,4,5,6,7,8]
y = [5,2,4,2,1,4,5,2]

plt.scatter(x,y, label='skitscat', color='k', s=25, marker="o")

plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

結(jié)果為:

image

plt.scatter不僅允許我們繪制xy腿椎,而且還可以讓我們決定所使用的標(biāo)記顏色桌硫,大小和類型。 有一堆標(biāo)記選項啃炸,請參閱 Matplotlib 標(biāo)記文檔中的所有選項铆隘。

第五章 堆疊圖

在這篇 Matplotlib 數(shù)據(jù)可視化教程中,我們要介紹如何創(chuàng)建堆疊圖南用。 堆疊圖用于顯示『部分對整體』隨時間的關(guān)系膀钠。 堆疊圖基本上類似于餅圖掏湾,只是隨時間而變化。

讓我們考慮一個情況肿嘲,我們一天有 24 小時融击,我們想看看我們?nèi)绾位ㄙM時間。 我們將我們的活動分為:睡覺雳窟,吃飯尊浪,工作和玩耍。

我們假設(shè)我們要在 5 天的時間內(nèi)跟蹤它封救,因此我們的初始數(shù)據(jù)將如下所示:

import matplotlib.pyplot as plt

days = [1,2,3,4,5]

sleeping = [7,8,6,11,7]
eating =   [2,3,4,3,2]
working =  [7,8,7,2,2]
playing =  [8,5,7,8,13]

因此拇涤,我們的x軸將包括day變量,即 1, 2, 3, 4 和 5兴泥。然后工育,日期的各個成分保存在它們各自的活動中虾宇。 像這樣繪制它們:

plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k'])

plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.show()

image

在這里搓彻,我們可以至少在顏色上看到,我們?nèi)绾位ㄙM我們的時間嘱朽。 問題是旭贬,如果不回頭看代碼,我們不知道什么顏色是什么搪泳。 下一個問題是稀轨,對于多邊形來說,我們實際上不能為數(shù)據(jù)添加『標(biāo)簽』岸军。 因此奋刽,在任何不止是線條,帶有像這樣的填充或堆疊圖的地方艰赞,我們不能以固有方式標(biāo)記出特定的部分佣谐。 這不應(yīng)該阻止程序員。 我們可以解決這個問題:

import matplotlib.pyplot as plt

days = [1,2,3,4,5]

sleeping = [7,8,6,11,7]
eating =   [2,3,4,3,2]
working =  [7,8,7,2,2]
playing =  [8,5,7,8,13]

plt.plot([],[],color='m', label='Sleeping', linewidth=5)
plt.plot([],[],color='c', label='Eating', linewidth=5)
plt.plot([],[],color='r', label='Working', linewidth=5)
plt.plot([],[],color='k', label='Playing', linewidth=5)

plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k'])

plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

image

我們在這里做的是畫一些空行方妖,給予它們符合我們的堆疊圖的相同顏色狭魂,和正確標(biāo)簽。 我們還使它們線寬為 5党觅,使線條在圖例中顯得較寬雌澄。 現(xiàn)在,我們可以很容易地看到杯瞻,我們?nèi)绾位ㄙM我們的時間镐牺。

第六章 餅圖

餅圖很像堆疊圖,只是它們位于某個時間點魁莉。 通常睬涧,餅圖用于顯示部分對于整體的情況卒废,通常以%為單位。 幸運的是宙地,Matplotlib 會處理切片大小以及一切事情摔认,我們只需要提供數(shù)值。

import matplotlib.pyplot as plt

slices = [7,2,2,13]
activities = ['sleeping','eating','working','playing']
cols = ['c','m','r','b']

plt.pie(slices,
        labels=activities,
        colors=cols,
        startangle=90,
        shadow= True,
        explode=(0,0.1,0,0),
        autopct='%1.1f%%')

plt.title('Interesting Graph\nCheck it out')
plt.show()

image

plt.pie中宅粥,我們需要指定『切片』参袱,這是每個部分的相對大小。 然后秽梅,我們指定相應(yīng)切片的顏色列表抹蚀。 接下來,我們可以選擇指定圖形的『起始角度』企垦。 這使你可以在任何地方開始繪圖环壤。 在我們的例子中,我們?yōu)轱瀳D選擇了 90 度角钞诡,這意味著第一個部分是一個豎直線條郑现。 接下來,我們可以選擇給繪圖添加一個字符大小的陰影荧降,然后我們甚至可以使用explode拉出一個切片接箫。

我們總共有四個切片,所以對于explode朵诫,如果我們不想拉出任何切片辛友,我們傳入0,0,0,0。 如果我們想要拉出第一個切片剪返,我們傳入0.1,0,0,0废累。

最后,我們使用autopct脱盲,選擇將百分比放置到圖表上面邑滨。

第七章 從文件加載數(shù)據(jù)

很多時候,我們想要繪制文件中的數(shù)據(jù)宾毒。 有許多類型的文件驼修,以及許多方法,你可以使用它們從文件中提取數(shù)據(jù)來圖形化诈铛。 在這里乙各,我們將展示幾種方法纯续。 首先梆暖,我們將使用內(nèi)置的csv模塊加載CSV文件,然后我們將展示如何使用 NumPy(第三方模塊)加載文件窜司。

import matplotlib.pyplot as plt
import csv

x = []
y = []

with open('example.txt','r') as csvfile:
    plots = csv.reader(csvfile, delimiter=',')
    for row in plots:
        x.append(int(row[0]))
        y.append(int(row[1]))

plt.plot(x,y, label='Loaded from file!')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

image

這里焕毫,我們打開樣例文件蹲坷,包含以下數(shù)據(jù):

1,5
2,3
3,4
4,7
5,4
6,3
7,5
8,7
9,4
10,4

接下來驶乾,我們使用csv模塊讀取數(shù)據(jù)。 csv讀取器自動按行分割文件循签,然后使用我們選擇的分隔符分割文件中的數(shù)據(jù)级乐。 在我們的例子中,這是一個逗號县匠。 注意:csv模塊和csv reader不需要文件在字面上是一個.csv文件风科。 它可以是任何具有分隔數(shù)據(jù)的簡單的文本文件。

一旦我們這樣做了乞旦,我們將索引為 0 的元素存儲到x列表贼穆,將索引為 1 的元素存儲到y列表中。 之后兰粉,我們都設(shè)置好了故痊,準(zhǔn)備繪圖,然后顯示數(shù)據(jù)玖姑。

雖然使用 CSV 模塊是完全正常的愕秫,但使用 NumPy 模塊來加載我們的文件和數(shù)據(jù),可能對我們更有意義客峭。 如果你沒有 NumPy豫领,你需要按下面的步驟來獲取它。 為了了解安裝模塊的更多信息舔琅,請參閱 pip 教程。 大多數(shù)人應(yīng)該都能打開命令行洲劣,并執(zhí)行pip install numpy备蚓。

如果不能,請參閱鏈接中的教程囱稽。

一旦你安裝了 NumPy郊尝,你可以編寫如下代碼:

import matplotlib.pyplot as plt
import numpy as np

x, y = np.loadtxt('example.txt', delimiter=',', unpack=True)
plt.plot(x,y, label='Loaded from file!')

plt.xlabel('x')
plt.ylabel('y')
plt.title('Interesting Graph\nCheck it out')
plt.legend()
plt.show()

結(jié)果應(yīng)該是相同的圖表。 稍后战惊,當(dāng)我們加載數(shù)據(jù)時流昏,我們可以利用 NumPy 為我們做一些更多的工作,但這是教程未來的內(nèi)容吞获。 就像csv模塊不需要一個特地的.csv一樣况凉,loadtxt函數(shù)不要求文件是一個.txt文件,它可以是一個.csv各拷,它甚至可以是一個 python 列表對象刁绒。

第八章 從網(wǎng)絡(luò)加載數(shù)據(jù)

除了從文件加載數(shù)據(jù),另一個流行的數(shù)據(jù)源是互聯(lián)網(wǎng)烤黍。 我們可以用各種各樣的方式從互聯(lián)網(wǎng)加載數(shù)據(jù)知市,但對我們來說傻盟,我們只是簡單地讀取網(wǎng)站的源代碼,然后通過簡單的拆分來分離數(shù)據(jù)嫂丙。

import matplotlib.pyplot as plt
import numpy as np
import urllib
import matplotlib.dates as mdates

def graph_data(stock):

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'

    source_code = urllib.request.urlopen(stock_price_url).read().decode()

    stock_data = []
    split_source = source_code.split('\n')

    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line:
                stock_data.append(line)

這里有很多步驟娘赴。首先,我們看到import跟啤。 pyplot像往常一樣導(dǎo)入筝闹,然后導(dǎo)入了numpy,然后是用于訪問互聯(lián)網(wǎng)的urllib腥光,然后導(dǎo)入了matplotlib.dates作為mdates关顷,它對于將日期戳轉(zhuǎn)換為 matplotlib 可以理解的日期很有用。

接下來武福,我們開始構(gòu)建我們的graph_data函數(shù)议双。在這里,我們首先定義包含股票數(shù)據(jù)的網(wǎng)址捉片。之后平痰,我們寫一些urllib代碼來訪問該 URL,然后使用.read讀取源代碼伍纫,之后我們繼續(xù)解碼該數(shù)據(jù)宗雇。如果你使用 Python 2,則不必使用decode莹规。

然后赔蒲,我們定義一個空列表,這是我們將要放置股票數(shù)據(jù)的地方良漱,我們也開始使用split_source變量拆分?jǐn)?shù)據(jù)舞虱,以換行符拆分。

現(xiàn)在母市,如果你去看源代碼矾兜,用stock替換 URL 中的+stock+,像 AAPL 那樣患久,你可以看到大多數(shù)頁面數(shù)據(jù)確實是股票定價信息椅寺,但有一些頭信息我們需要過濾掉。為此蒋失,我們使用一些基本的過濾返帕,檢查它們來確保每行有 6 個數(shù)據(jù)點,然后確保術(shù)語values不在行中高镐。

現(xiàn)在溉旋,我們已經(jīng)解析了數(shù)據(jù),并做好了準(zhǔn)備嫉髓。我們將使用 NumPy:

date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                      delimiter=',',
                                                      unpack=True,
                                                      # %Y = full year. 2015
                                                      # %y = partial year 15
                                                      # %m = number month
                                                      # %d = number day
                                                      # %H = hours
                                                      # %M = minutes
                                                      # %S = seconds
                                                      # 12-06-2014
                                                      # %m-%d-%Y
                                                      converters={0: bytespdate2num('%Y%m%d')})

我們在這里所做的是观腊,使用numpyloadtxt函數(shù)邑闲,并將這六個元素解構(gòu)到六個變量。 這里的第一個參數(shù)是stock_data梧油,這是我們加載的數(shù)據(jù)苫耸。 然后,我們指定delimiter(這里是逗號)儡陨,然后我們指定我們確實想要在這里解包變量褪子,不是一個變量,而是我們定義的這組變量骗村。 最后嫌褪,我們使用可選的converters參數(shù)來指定我們要轉(zhuǎn)換的元素(0),以及我們打算要怎么做胚股。 我們傳遞一個名為bytespdate2num的函數(shù)笼痛,它還不存在,但我們下面會編寫它琅拌。

第九章 時間戳的轉(zhuǎn)換

本教程的重點是將來自 Yahoo finance API 的日期轉(zhuǎn)換為 Matplotlib 可理解的日期缨伊。 為了實現(xiàn)它,我們要寫一個新的函數(shù)进宝,bytespdate2num刻坊。

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

此函數(shù)接受數(shù)據(jù),基于編碼來解碼數(shù)據(jù)党晋,然后返回它谭胚。

將此應(yīng)用于我們的程序的其余部分:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          # %Y = full year. 2015
                                                          # %y = partial year 15
                                                          # %m = number month
                                                          # %d = number day
                                                          # %H = hours
                                                          # %M = minutes
                                                          # %S = seconds
                                                          # 12-06-2014
                                                          # %m-%d-%Y
                                                          converters={0: bytespdate2num('%Y%m%d')})

    plt.plot_date(date, closep,'-', label='Price')

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title('Interesting Graph\nCheck it out')
    plt.legend()
    plt.show()

graph_data('TSLA')

如果你繪制 TSLA,結(jié)果圖應(yīng)該看起來像這樣:

image

第十章 基本的自定義

在 Matplotlib 教程中隶校,我們將討論一些可能的圖表自定義漏益。 為了開始修改子圖,我們必須定義它們深胳。 我們很快會談?wù)撍麄儯袃煞N定義并構(gòu)造子圖的主要方法铜犬。 現(xiàn)在舞终,我們只使用其中一個,但我們會很快解釋它們癣猾。

現(xiàn)在敛劝,修改我們的graph_data函數(shù):

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

為了修改圖表,我們需要引用它纷宇,所以我們將它存儲到變量fig夸盟。 然后我們將ax1定義為圖表上的子圖。 我們在這里使用subplot2grid像捶,這是獲取子圖的兩種主要方法之一上陕。 我們將深入討論這些東西桩砰,但現(xiàn)在,你應(yīng)該看到我們有 2 個元組释簿,它們提供了(1,1)(0,0)亚隅。 1,1表明這是一個 1×1 網(wǎng)格。 然后0,0表明這個子圖的『起點』將為0,0庶溶。

接下來煮纵,通過我們已經(jīng)編寫的代碼來獲取和解析數(shù)據(jù):

stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
source_code = urllib.request.urlopen(stock_price_url).read().decode()
stock_data = []
split_source = source_code.split('\n')
for line in split_source:
    split_line = line.split(',')
    if len(split_line) == 6:
        if 'values' not in line and 'labels' not in line:
            stock_data.append(line)

date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                      delimiter=',',
                                                      unpack=True,
                                                      converters={0: bytespdate2num('%Y%m%d')})

下面,我們這樣繪制數(shù)據(jù):

ax1.plot_date(date, closep,'-', label='Price')

現(xiàn)在偏螺,由于我們正在繪制日期行疏,我們可能會發(fā)現(xiàn),如果我們放大套像,日期會在水平方向上移動酿联。但是,我們可以自定義這些刻度標(biāo)簽凉夯,像這樣:

for label in ax1.xaxis.get_ticklabels():
    label.set_rotation(45)

這將使標(biāo)簽轉(zhuǎn)動到對角線方向货葬。 接下來,我們可以添加一個網(wǎng)格:

ax1.grid(True)

然后劲够,其它東西我們保留默認(rèn)震桶,但我們也可能需要略微調(diào)整繪圖,因為日期跑到了圖表外面征绎。 記不記得我們在第一篇教程中討論的configure subplots按鈕蹲姐? 我們不僅可以以這種方式配置圖表,我們還可以在代碼中配置它們人柿,以下是我們設(shè)置這些參數(shù)的方式:

plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)

現(xiàn)在柴墩,為了防止我們把你遺留在某個地方,這里是完整的代碼:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    ax1.plot_date(date, closep,'-', label='Price')
    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)
    ax1.grid(True)#, color='g', linestyle='-', linewidth=5)

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title('Interesting Graph\nCheck it out')
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('TSLA')

結(jié)果為:

image

第十一章 Unix 時間

在這個 Matplotlib 教程中凫岖,我們將介紹如何處理 unix 時間戳的轉(zhuǎn)換江咳,然后在圖形中繪制日期戳。 使用 Yahoo Finance API哥放,你會注意到歼指,如果你使用較大的時間間隔,如1y(一年)甥雕,你會得到我們一直在使用的日期戳踩身,但如果你使用10d(10 天),反之你會得到 unix 時間的時間戳社露。

Unix 時間是 1970 年 1 月 1 日以后的秒數(shù)挟阻,它是跨程序的標(biāo)準(zhǔn)化時間表示方法。 也就是說,Matplotlib 并不歡迎 unix 時間戳附鸽。 這里是你可以使用 Matplotlib 來處理 unix 時間的方式:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import datetime as dt
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10d/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True)
    dateconv = np.vectorize(dt.datetime.fromtimestamp)
    date = dateconv(date)

##    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
##                                                          delimiter=',',
##                                                          unpack=True,
##                                                          converters={0: bytespdate2num('%Y%m%d')})

    ax1.plot_date(date, closep,'-', label='Price')
    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)
    ax1.grid(True)#, color='g', linestyle='-', linewidth=5)

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title('Interesting Graph\nCheck it out')
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('TSLA')

所以在這里脱拼,我們所做的是 unix 時間的寫入處理,并注釋掉我們以前的代碼拒炎,因為我們?yōu)橹蟮氖褂枚4嫠?這里的主要區(qū)別是:

dateconv = np.vectorize(dt.datetime.fromtimestamp)
date = dateconv(date)

這里挪拟,我們將時間戳轉(zhuǎn)換為日期戳,然后將其轉(zhuǎn)換為 Matplotlib 想要的時間击你。

現(xiàn)在玉组,由于某些原因,我的 unix 時間帶有另一行包含 6 個元素的數(shù)據(jù)丁侄,并且它包含了術(shù)語label惯雳,因此,在我們解析數(shù)據(jù)的for循環(huán)中鸿摇,我們?yōu)槟阍偬砑右粋€需要注意的檢查:

for line in split_source:
    split_line = line.split(',')
    if len(split_line) == 6:
        if 'values' not in line and 'labels' not in line:
            stock_data.append(line)

現(xiàn)在你的圖表應(yīng)該類似:

image

這里的所有扁平線條的原因是市場關(guān)閉石景。 有了這個短期數(shù)據(jù),我們可以得到日內(nèi)數(shù)據(jù)拙吉。 所以交易開放時有很多點潮孽,然后市場關(guān)閉時就沒有了,然后又是一堆筷黔,然后又是沒有往史。

第十二章 顏色和填充

在本教程中,我們將介紹一些更多的自定義佛舱,比如顏色和線條填充椎例。

我們要做的第一個改動是將plt.title更改為stock變量。

plt.title(stock)

現(xiàn)在请祖,讓我們來介紹一下如何更改標(biāo)簽顏色订歪。 我們可以通過修改我們的軸對象來實現(xiàn):

ax1.xaxis.label.set_color('c')
ax1.yaxis.label.set_color('r')

如果我們運行它,我們會看到標(biāo)簽改變了顏色肆捕,就像在單詞中那樣刷晋。

接下來,我們可以為要顯示的軸指定具體數(shù)字慎陵,而不是像這樣的自動選擇:

ax1.set_yticks([0,25,50,75])

接下來掏秩,我想介紹填充。 填充所做的事情荆姆,是在變量和你選擇的一個數(shù)值之間填充顏色。 例如映凳,我們可以這樣:

ax1.fill_between(date, 0, closep)

所以到這里胆筒,我們的代碼為:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import datetime as dt
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    ax1.fill_between(date, 0, closep)

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)
    ax1.grid(True)#, color='g', linestyle='-', linewidth=5)
    ax1.xaxis.label.set_color('c')
    ax1.yaxis.label.set_color('r')
    ax1.set_yticks([0,25,50,75])

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('EBAY')

結(jié)果為:

image

填充的一個問題是,我們可能最后會把東西都覆蓋起來。 我們可以用透明度來解決它:

ax1.fill_between(date, 0, closep)

現(xiàn)在仆救,讓我們介紹條件填充抒和。 讓我們假設(shè)圖表的起始位置是我們開始買入 eBay 的地方。 這里彤蔽,如果價格低于這個價格摧莽,我們可以向上填充到原來的價格,然后如果它超過了原始價格顿痪,我們可以向下填充镊辕。 我們可以這樣做:

ax1.fill_between(date, closep[0], closep)

會生成:

image

如果我們想用紅色和綠色填充來展示收益/損失,那么與原始價格相比蚁袭,綠色填充用于上升(注:國外股市的顏色和國內(nèi)相反)征懈,紅色填充用于下跌? 沒問題揩悄! 我們可以添加一個where參數(shù)卖哎,如下所示:

ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5)

這里,我們填充當(dāng)前價格和原始價格之間的區(qū)域删性,其中當(dāng)前價格高于原始價格亏娜。 我們給予它綠色的前景色,因為這是一個上升蹬挺,而且我們使用微小的透明度维贺。

我們?nèi)匀徊荒軐Χ噙呅螖?shù)據(jù)(如填充)應(yīng)用標(biāo)簽,但我們可以像以前一樣實現(xiàn)空線條汗侵,因此我們可以:

ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5)
ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5)

ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5)
ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5)

這向我們提供了一些填充幸缕,以及用于處理標(biāo)簽的空線條,我們打算將其顯示在圖例中晰韵。這里完整的代碼是:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import datetime as dt
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    ax1.plot_date(date, closep,'-', label='Price')

    ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5)
    ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5)

    ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5)
    ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5)

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)
    ax1.grid(True)#, color='g', linestyle='-', linewidth=5)
    ax1.xaxis.label.set_color('c')
    ax1.yaxis.label.set_color('r')
    ax1.set_yticks([0,25,50,75])

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('EBAY')

現(xiàn)在我們的結(jié)果是:

image

第十三章 邊框和水平線條

歡迎閱讀另一個定制教程发乔,在這里我們使用 Matplotlib 討論邊框和水平線條。 有時候你可能想做的事情是改變邊框的顏色雪猪,或者甚至完全刪除它們栏尚。

圖形的邊框基本上是圖形的邊界,其中有刻度線等東西只恨。為了改變邊框的顏色译仗,你可以做一些類似這樣的事情:

ax1.spines['left'].set_color('c')

在這里,我們引用了我們的邊框字典官觅,表示我們要調(diào)整左邊框纵菌,然后我們使用set_color方法將顏色設(shè)置為'c',它是青色休涤。

如果我們想刪除所有邊框怎么辦咱圆? 我們可以這樣做:

ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)

這是非常類似的代碼笛辟,刪除了右邊框和上邊框。

很難看到我們修改了左邊框的顏色序苏,所以讓我們通過修改線寬來使它變得很明顯:

ax1.spines['left'].set_linewidth(5)

現(xiàn)在手幢,左邊框變成了非常粗也非常顯眼的青色。 最后忱详,如果我們想修改刻度參數(shù)怎么辦围来? 假如不想要黑色的日期,我們想要一些橙色的日期匈睁? 沒問題监透!

ax1.tick_params(axis='x', colors='#f06215')

現(xiàn)在我們的日期是橙色了! 接下來软舌,讓我們來看看我們?nèi)绾卫L制一條水平線才漆。 你當(dāng)然可以將你創(chuàng)建的一組新數(shù)據(jù)繪制成一條水平線,但你不需要這樣做佛点。 你可以:

ax1.axhline(closep[0], color='k', linewidth=5)

所以在這里醇滥,我們的整個代碼是:

import matplotlib.pyplot as plt
import numpy as np
import urllib
import datetime as dt
import matplotlib.dates as mdates

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    ax1.plot_date(date, closep,'-', label='Price')
    ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5)
    ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5)
    ax1.axhline(closep[0], color='k', linewidth=5)
    ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5)
    ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5)

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)
    ax1.grid(True)
    #ax1.xaxis.label.set_color('c')
    #ax1.yaxis.label.set_color('r')
    ax1.set_yticks([0,25,50,75])

    ax1.spines['left'].set_color('c')
    ax1.spines['right'].set_visible(False)
    ax1.spines['top'].set_visible(False)
    ax1.spines['left'].set_linewidth(5)

    ax1.tick_params(axis='x', colors='#f06215')

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('ebay')

結(jié)果為:

image

第十四章 OHLC K 線圖

在 Matplotlib 教程中,我們將介紹如何在 Matplotlib 中創(chuàng)建開超营,高鸳玩,低,關(guān)(OHLC)的 K 線圖演闭。 這些圖表用于以精簡形式顯示時間序列股價信息不跟。 為了實現(xiàn)它,我們首先需要導(dǎo)入一些模塊:

import matplotlib.ticker as mticker
from matplotlib.finance import candlestick_ohlc

我們引入了ticker米碰,允許我們修改圖表底部的ticker信息窝革。 然后我們從matplotlib.finance模塊中引入candlestick_ohlc功能。

現(xiàn)在吕座,我們需要組織我們的數(shù)據(jù)來和 matplotlib 協(xié)作虐译。 如果你剛剛加入我們,我們得到的數(shù)據(jù)如下:

stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv'
source_code = urllib.request.urlopen(stock_price_url).read().decode()
stock_data = []
split_source = source_code.split('\n')
for line in split_source:
    split_line = line.split(',')
    if len(split_line) == 6:
        if 'values' not in line and 'labels' not in line:
            stock_data.append(line)

date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                      delimiter=',',
                                                      unpack=True,
                                                      converters={0: bytespdate2num('%Y%m%d')})

現(xiàn)在吴趴,我們需要構(gòu)建一個 Python 列表漆诽,其中每個元素都是數(shù)據(jù)。 我們可以修改我們的loadtxt函數(shù)锣枝,使其不解構(gòu)厢拭,但隨后我們還是希望引用特定的數(shù)據(jù)點。 我們可以解決這個問題撇叁,但是我們最后可能只擁有兩個單獨的數(shù)據(jù)集供鸠。 為此,我們執(zhí)行以下操作:

x = 0
y = len(date)
ohlc = []

while x < y:
    append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x]
    ohlc.append(append_me)
    x+=1

有了這個陨闹,我們現(xiàn)在將 OHLC 數(shù)據(jù)列表存儲到我們的變量ohlc回季。 現(xiàn)在我們可以這樣繪制:

candlestick_ohlc(ax1, ohlc)

圖表應(yīng)該是這樣:

image

不幸的是家制,x軸上的datetime數(shù)據(jù)不是日期戳的形式。 我們可以處理它:

ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

此外泡一,紅/黑著色依我看不是最好的選擇。 我們應(yīng)該使用綠色表示上升和紅色表示下降觅廓。 為此鼻忠,我們可以:

candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')

最后,我們可以將x標(biāo)簽設(shè)置為我們想要的數(shù)量杈绸,像這樣:

ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))

現(xiàn)在帖蔓,完整代碼現(xiàn)在是這樣:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mticker
from matplotlib.finance import candlestick_ohlc

import numpy as np
import urllib
import datetime as dt

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    x = 0
    y = len(date)
    ohlc = []

    while x < y:
        append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x]
        ohlc.append(append_me)
        x+=1

    candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)

    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
    ax1.grid(True)

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('EBAY')

結(jié)果為:

image

還要注意,我們從前面的教程中刪除了大部分ax1的修改瞳脓。

第十五章 樣式

在這個 Matplotlib 教程中塑娇,我們將討論樣式。 我們用于 Matplotlib 的樣式非常相似于用于 HTML 頁面的 CSS(層疊樣式表)劫侧。 正如你在這里可以看到的埋酬,我們對圖形所做的所有修改都會疊加,而且我們目前只有一個軸域烧栋。 我們可以使用for循環(huán)写妥,至少使代碼量降低,但我們也可以在 Matplotlib 中利用這些樣式审姓。

樣式頁的想法是將自定義樣式寫入文件珍特,然后,為了使用這些更改并將其應(yīng)用于圖形魔吐,所有你需要做的就是導(dǎo)入樣式扎筒,然后使用該特定樣式。 這樣酬姆,讓我們假設(shè)你發(fā)現(xiàn)自己總是改變圖形的各種元素嗜桌。 你不必為每個圖表編寫 25 ~ 200 行自定義代碼,只需將其寫入一個樣式轴踱,然后加載該樣式症脂,并以兩行應(yīng)用所有這些更改即可! 讓我們開始吧淫僻。

from matplotlib import style

接下來诱篷,我們指定要使用的樣式。 Matplotlib 已經(jīng)有了幾種樣式雳灵。

我們可以這樣來使用樣式:

style.use('ggplot')

image

除了標(biāo)題棕所,標(biāo)簽的顏色是灰色的,軸域的背景是淺灰色悯辙,我們可以立即分辨字體是不同的琳省。 我們還注意到迎吵,網(wǎng)格實際上是一個白色的實線。 我們的 K 線圖保持不變针贬,主要是因為我們在事后定制它击费。 在樣式中加載時,更改會生效桦他,但如果在加載樣式后編寫新的自定義代碼蔫巩,你的更改也會生效。

因為我們試圖展示樣式模塊快压,但是讓我們繼續(xù)圆仔,簡單繪制幾行,并暫且注釋掉 K 線圖:

#candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')
ax1.plot(date,closep)
ax1.plot(date,openp)

會生成:

image

已經(jīng)比默認(rèn)值好多了蔫劣!

樣式的另一個例子是fivethirtyeight

image

你可以這樣查看所有的可用樣式:

print(plt.style.available)

我這里它提供了['bmh', 'dark_background', 'ggplot', 'fivethirtyeight', 'grayscale']坪郭。

讓我們嘗試dark_background

style.use('dark_background')

image

現(xiàn)在,如果你想制作自己的風(fēng)格呢脉幢? 首先歪沃,你需要找到樣式目錄。 為了實現(xiàn)它鸵隧,如果你知道它在哪里绸罗,你可以前往你的 matplotlib 目錄,或者你可以找到該目錄豆瘫。 如果你不知道如何找到該目錄珊蟀,你可以執(zhí)行以下操作:

print(plt.__file__)

這至少會告訴你pyplot模塊的位置。

在 matplotlib 目錄中外驱,你需要尋找mpl-data育灸。 然后在那里,你需要尋找stylelib昵宇。 在 Windows 上 磅崭,我的完整路徑是:C:\Python34\Lib\site-packages\matplotlib\mpl-data\stylelib

那里應(yīng)該顯示了所有可用的.mplstyle文件瓦哎。 你可以編輯砸喻、復(fù)制或重命名它們,然后在那里修改為你想要的東西蒋譬。 然后割岛,無論你用什么來命名.mplstyle文件,都要放在style.use中犯助。

第十六章 實時圖表

在這篇 Matplotlib 教程中癣漆,我們將介紹如何創(chuàng)建實時更新圖表,可以在數(shù)據(jù)源更新時更新其圖表剂买。 你可能希望將此用于繪制股票實時定價數(shù)據(jù)惠爽,或者可以將傳感器連接到計算機(jī)癌蓖,并且顯示傳感器實時數(shù)據(jù)。 為此婚肆,我們使用 Matplotlib 的動畫功能租副。

最開始:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style

這里,唯一的新增導(dǎo)入是matplotlib.animation as animation旬痹。 這是一個模塊附井,允許我們在顯示之后對圖形進(jìn)行動畫處理。

接下來两残,我們添加一些你熟悉的代碼,如果你一直關(guān)注這個系列:

style.use('fivethirtyeight')

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

現(xiàn)在我們編寫動畫函數(shù):

def animate(i):
    graph_data = open('example.txt','r').read()
    lines = graph_data.split('\n')
    xs = []
    ys = []
    for line in lines:
        if len(line) > 1:
            x, y = line.split(',')
            xs.append(x)
            ys.append(y)
    ax1.clear()
    ax1.plot(xs, ys)

我們在這里做的是構(gòu)建數(shù)據(jù)把跨,然后繪制它人弓。 注意我們這里不調(diào)用plt.show()。 我們從一個示例文件讀取數(shù)據(jù)着逐,其內(nèi)容如下:

1,5
2,3
3,4
4,7
5,4
6,3
7,5
8,7
9,4
10,4

我們打開上面的文件崔赌,然后存儲每一行,用逗號分割成xsys耸别,我們將要繪制它健芭。 然后:

ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()

我們運行動畫,將動畫放到圖表中(fig),運行animate的動畫函數(shù),最后我們設(shè)置了 1000 的間隔括授,即 1000 毫秒或 1 秒券册。

運行此圖表的結(jié)果應(yīng)該像往常一樣生成圖表。 然后跃脊,你應(yīng)該能夠使用新的坐標(biāo)更新example.txt文件。 這樣做會生成一個自動更新的圖表,如下:

[圖片上傳失敗...(image-3aca35-1558443769838)]

第十七章 注解和文本

在本教程中伸头,我們將討論如何向 Matplotlib 圖形添加文本。 我們可以通過兩種方式來實現(xiàn)舷蟀。 一種是將文本放置在圖表上的某個位置恤磷。 另一個是專門注解圖表上的繪圖,來引起注意野宜。

這里的起始代碼是教程 15扫步,它在這里:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mticker
from matplotlib.finance import candlestick_ohlc
from matplotlib import style

import numpy as np
import urllib
import datetime as dt

style.use('fivethirtyeight')
print(plt.style.available)

print(plt.__file__)

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    x = 0
    y = len(date)
    ohlc = []

    while x < y:
        append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x]
        ohlc.append(append_me)
        x+=1

    candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)

    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
    ax1.grid(True)

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('ebay')

所以這里是 Yahoo Finance API 的 eBay 的 OHLC K 線圖。 這里我們要講解的第一件事是向圖形添加文本速缨。

font_dict = {'family':'serif',
             'color':'darkred',
             'size':15}
ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict)

在這里锌妻,我們需要做一些事情。 首先旬牲,我們使用ax1.text添加文本仿粹。 我們使用我們的數(shù)據(jù)搁吓,以坐標(biāo)形式給出此文本的位置。 首先給出文本的坐標(biāo)吭历,然后給出要放置的實際文本堕仔。 接下來,我們使用fontdict參數(shù)添加一個數(shù)據(jù)字典晌区,來使用所用的字體摩骨。 在我們的字體字典中,我們將字體更改為serif朗若,顏色為『深紅色』恼五,然后將字體大小更改為 15。這將全部應(yīng)用于我們的圖表上的文本哭懈,如下所示:

image

太棒了灾馒,接下來我們可以做的是,注解某個特定的繪圖遣总。 我們希望這樣做來給出更多的信息睬罗。 在 eBay 的例子中,也許我們想解釋某個具體繪圖旭斥,或給出一些關(guān)于發(fā)生了什么的信息容达。 在股價的例子中,也許有一些發(fā)生的新聞會影響價格垂券。 你可以注解新聞來自哪里花盐,這將有助于解釋定價變化。

ax1.annotate('Bad News!',(date[9],highp[9]),
             xytext=(0.8, 0.9), textcoords='axes fraction',
             arrowprops = dict(facecolor='grey',color='grey'))

這里圆米,我們用ax1.annotate來注解卒暂。 我們首先傳遞我們想要注解的文本,然后傳遞我們讓這個注解指向的坐標(biāo)娄帖。 我們這樣做也祠,是因為當(dāng)我們注釋時,我們可以繪制線條和指向特定點的箭頭近速。 接下來诈嘿,我們指定xytext的位置。 它可以是像我們用于文本放置的坐標(biāo)位置削葱,但是讓我們展示另一個例子奖亚。 它可以為軸域小數(shù),所以我們使用 0.8 和 0.9析砸。 這意味著文本的位置在x軸的80%和y軸的90%處昔字。 這樣,如果我們移動圖表,文本將保持在相同位置作郭。

執(zhí)行它陨囊,會生成:

image

根據(jù)你學(xué)習(xí)這個教程的時間,所指向的點可能有所不同夹攒,這只是一個注解的例子蜘醋,其中有一些合理的想法,即為什么我們需要注解一些東西咏尝。

當(dāng)圖表啟動時压语,請嘗試單擊平移按鈕(藍(lán)色十字),然后移動圖表编检。 你會看到文本保持不動胎食,但箭頭跟隨移動并繼續(xù)指向我們想要的具體的點。 這很酷吧允懂!

最后一個圖表的完整代碼:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as mticker
from matplotlib.finance import candlestick_ohlc
from matplotlib import style

import numpy as np
import urllib
import datetime as dt

style.use('fivethirtyeight')
print(plt.style.available)

print(plt.__file__)

def bytespdate2num(fmt, encoding='utf-8'):
    strconverter = mdates.strpdate2num(fmt)
    def bytesconverter(b):
        s = b.decode(encoding)
        return strconverter(s)
    return bytesconverter

def graph_data(stock):

    fig = plt.figure()
    ax1 = plt.subplot2grid((1,1), (0,0))

    stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv'
    source_code = urllib.request.urlopen(stock_price_url).read().decode()
    stock_data = []
    split_source = source_code.split('\n')
    for line in split_source:
        split_line = line.split(',')
        if len(split_line) == 6:
            if 'values' not in line and 'labels' not in line:
                stock_data.append(line)

    date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data,
                                                          delimiter=',',
                                                          unpack=True,
                                                          converters={0: bytespdate2num('%Y%m%d')})

    x = 0
    y = len(date)
    ohlc = []

    while x < y:
        append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x]
        ohlc.append(append_me)
        x+=1

    candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')

    for label in ax1.xaxis.get_ticklabels():
        label.set_rotation(45)

    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
    ax1.grid(True)
    ax1.annotate('Bad News!',(date[9],highp[9]),
                 xytext=(0.8, 0.9), textcoords='axes fraction',
                 arrowprops = dict(facecolor='grey',color='grey'))

##    # Text placement example:
##    font_dict = {'family':'serif',
##                 'color':'darkred',
##                 'size':15}
##    ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict)

    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title(stock)
    #plt.legend()
    plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
    plt.show()

graph_data('ebay')

現(xiàn)在斥季,使用注解,我們可以做一些其他事情累驮,如注解股票圖表的最后價格。 這就是我們接下來要做的舵揭。

python:matplotlib數(shù)據(jù)可視化(下)

參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谤专,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子午绳,更是在濱河造成了極大的恐慌置侍,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拦焚,死亡現(xiàn)場離奇詭異蜡坊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赎败,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門秕衙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人僵刮,你說我怎么就攤上這事据忘。” “怎么了搞糕?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵勇吊,是天一觀的道長。 經(jīng)常有香客問我窍仰,道長汉规,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任驹吮,我火速辦了婚禮针史,結(jié)果婚禮上晶伦,老公的妹妹穿的比我還像新娘。我一直安慰自己悟民,他們只是感情好坝辫,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著射亏,像睡著了一般近忙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上智润,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天及舍,我揣著相機(jī)與錄音,去河邊找鬼窟绷。 笑死锯玛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兼蜈。 我是一名探鬼主播攘残,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼为狸!你這毒婦竟也來了歼郭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤辐棒,失蹤者是張志新(化名)和其女友劉穎病曾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漾根,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡泰涂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辐怕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逼蒙。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秘蛇,靈堂內(nèi)的尸體忽然破棺而出其做,到底是詐尸還是另有隱情,我是刑警寧澤赁还,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布妖泄,位于F島的核電站,受9級特大地震影響艘策,放射性物質(zhì)發(fā)生泄漏蹈胡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罚渐。 院中可真熱鬧却汉,春花似錦、人聲如沸荷并。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽源织。三九已至翩伪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谈息,已是汗流浹背缘屹。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留侠仇,地道東北人轻姿。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像逻炊,于是被迫代替她去往敵國和親互亮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容