來源:Introduction to Matplotlib and basic linephp
譯者:飛龍css
協議:CC BY-NC-SA 4.0html
歡迎閱讀 Python 3+ Matplotlib 系列教程。 在本系列中,咱們將涉及 Matplotlib 數據可視化模塊的多個方面。 Matplotlib 可以建立多數類型的圖表,如條形圖,散點圖,條形圖,餅圖,堆疊圖,3D 圖和地圖圖表。python
首先,爲了實際使用 Matplotlib,咱們須要安裝它。git
若是你安裝了更高版本的 Python,你應該可以打開cmd.exe
或終端,而後執行:程序員
pip install matplotlib
注意:若是上面的較短命令不工做,你可能須要執行C:/Python34/Scripts/pip install matplotlib
。github
若是在導入matplotlib
時,你會收到相似『無命名模塊』和模塊名稱的錯誤,這意味着你還須要安裝該模塊。 一個常見的問題是缺乏名爲six
的模塊。 這意味着你須要使用pip
安裝six
。sql
或者,你能夠前往 Matplotlib.org 並經過訪問下載頁面下載適當的版本進行安裝。 請記住,由於你的操做系統爲 64 位,你不必定須要 64 位版本的 Python。 若是你不打算嘗試 64 位,你可使用 32 位。 打開 IDLE 並閱讀頂部。 若是它說你是 64 位,你就是 64 位,若是它說是 32 位,那麼你就是 32 位。 一旦你安裝了 Python,你就作好了準備,你能夠編寫任何你想要的邏輯。 我喜歡使用 IDLE 來編程,但你能夠隨意使用任何你喜歡的東西。編程
import matplotlib.pyplot as plt
這一行導入集成的pyplot
,咱們將在整個系列中使用它。 咱們將pyplot
導入爲plt
,這是使用pylot
的 python 程序的傳統慣例。api
plt.plot([1,2,3],[5,7,4])
接下來,咱們調用plot
的.plot
方法繪製一些座標。 這個.plot
須要許多參數,但前兩個是'x'
和'y'
座標,咱們放入列表。 這意味着,根據這些列表咱們擁有 3 個座標:1,5
2,7
和3,4
。
plt.plot
在後臺『繪製』這個繪圖,但繪製了咱們想要的一切以後,當咱們準備好的時候,咱們須要把它帶到屏幕上。
plt.show()
這樣,應該彈出一個圖形。 若是沒有,有時它能夠彈出,或者你可能獲得一個錯誤。 你的圖表應以下所示:
這個窗口是一個 matplotlib 窗口,它容許咱們查看咱們的圖形,以及與它進行交互和訪問。 你能夠將鼠標懸停在圖表上,並查看一般在右下角的座標。 你也可使用按鈕。 它們可能在不一樣的位置,但在上圖中,這些按鈕在左下角。
Home
(主頁)一旦你開始瀏覽你的圖表,主頁按鈕會幫助你。 若是你想要返回原始視圖,能夠單擊它。 在瀏覽圖表以前單擊此按鈕將不會生效。
Forward/Back
(前進/後退)這些按鈕能夠像瀏覽器中的前進和後退按鈕同樣使用。 你能夠單擊這些來移回到你以前的位置,或再次前進。
Pan
(平移)你能夠點擊平移按鈕,以後點擊並拖拽你的圖表。
Zoom
(縮放)縮放按鈕可以讓你單擊它,而後單擊並拖動出要放大的方形區域。 放大須要左鍵單擊並拖動。 你也能夠右鍵單擊並拖動來縮小。
Configure Subplots
(配置子圖)此按鈕容許你對圖形和繪圖配置各類間距選項。 點擊它會彈出:
每一個藍色條形都是一個滑塊,它容許你調整內邊距。 其中有些如今沒有任何效果,由於沒有任何其餘子圖。 前四個值調整圖形到窗口邊緣的邊距。 以後wspace
和hspace
對應於當你繪製多個子圖時,它們的水平或豎直間距。
Save
(保存)此按鈕容許你以各類形式保存圖形。
因此這是 matplotlib 的快速介紹,咱們以後會涉及更多。
在本教程中,咱們將討論 Matplotlib 中的圖例,標題和標籤。 不少時候,圖形能夠不言自明,可是圖形帶有標題,軸域上的標籤和圖例,來解釋每一行是什麼很是必要。
注:軸域(
Axes
)即兩條座標軸圍城的區域。
從這裏開始:
1 import matplotlib.pyplot as plt 2 3 x = [1,2,3] 4 y = [5,7,4] 5 6 x2 = [1,2,3] 7 y2 = [10,14,12]
這樣咱們能夠畫出兩個線條,接下來:
plt.plot(x, y, label='First Line') plt.plot(x2, y2, label='Second Line')
在這裏,咱們繪製了咱們已經看到的東西,但此次咱們添加另外一個參數label
。 這容許咱們爲線條指定名稱,咱們之後能夠在圖例中顯示它。 咱們的其他代碼爲:
1 plt.xlabel('Plot Number') 2 plt.ylabel('Important var') 3 plt.title('Interesting Graph\nCheck it out') 4 plt.legend() 5 plt.show()
使用plt.xlabel
和plt.ylabel
,咱們能夠爲這些相應的軸建立標籤。 接下來,咱們可使用plt.title
建立圖的標題,而後咱們可使用plt.legend()
生成默認圖例。 結果圖以下:
這個教程中咱們會涉及條形圖和直方圖。咱們先來看條形圖:
1 import matplotlib.pyplot as plt 2 3 plt.bar([1,3,5,7,9],[5,2,7,8,2], label="Example one") 4 5 plt.bar([2,4,6,8,10],[8,6,2,5,6], label="Example two", color='g') 6 plt.legend() 7 plt.xlabel('bar number') 8 plt.ylabel('bar height') 9 10 plt.title('Epic Graph\nAnother Line! Whoa') 11 12 plt.show()
plt.bar
爲咱們建立條形圖。 若是你沒有明確選擇一種顏色,那麼雖然作了多個圖,全部的條看起來會同樣。 這讓咱們有機會使用一個新的 Matplotlib 自定義選項。 你能夠在任何類型的繪圖中使用顏色,例如g
爲綠色,b
爲藍色,r
爲紅色,等等。 你還可使用十六進制顏色代碼,如#191970
。
接下來,咱們會講解直方圖。 直方圖很是像條形圖,傾向於經過將區段組合在一塊兒來顯示分佈。 這個例子多是年齡的分組,或測試的分數。 咱們並非顯示每一組的年齡,而是按照 20 ~ 25,25 ~ 30… 等等來顯示年齡。 這裏有一個例子:
1 import matplotlib.pyplot as plt 2 3 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] 4 5 bins = [0,10,20,30,40,50,60,70,80,90,100,110,120,130] 6 7 plt.hist(population_ages, bins, histtype='bar', rwidth=0.8) 8 9 plt.xlabel('x') 10 plt.ylabel('y') 11 plt.title('Interesting Graph\nCheck it out') 12 plt.legend() 13 plt.show()
產生的圖表爲:
對於plt.hist
,你首先須要放入全部的值,而後指定放入哪一個桶或容器。 在咱們的例子中,咱們繪製了一堆年齡,並但願以 10 年的增量來顯示它們。 咱們將條形的寬度設爲 0.8,可是若是你想讓條形變寬,或者變窄,你能夠選擇其餘的寬度。
接下來,咱們將介紹散點圖。散點圖一般用於比較兩個變量來尋找相關性或分組,若是你在 3 維繪製則是 3 個。
散點圖的一些示例代碼:
1 import matplotlib.pyplot as plt 2 3 x = [1,2,3,4,5,6,7,8] 4 y = [5,2,4,2,1,4,5,2] 5 6 plt.scatter(x,y, label='skitscat', color='k', s=25, marker="o") 7 8 plt.xlabel('x') 9 plt.ylabel('y') 10 plt.title('Interesting Graph\nCheck it out') 11 plt.legend() 12 plt.show()
結果爲:
plt.scatter
不只容許咱們繪製x
和y
,並且還可讓咱們決定所使用的標記顏色,大小和類型。 有一堆標記選項,請參閱 Matplotlib 標記文檔中的全部選項。
在這篇 Matplotlib 數據可視化教程中,咱們要介紹如何建立堆疊圖。 堆疊圖用於顯示『部分對總體』隨時間的關係。 堆疊圖基本上相似於餅圖,只是隨時間而變化。
讓咱們考慮一個狀況,咱們一天有 24 小時,咱們想看看咱們如何花費時間。 咱們將咱們的活動分爲:睡覺,吃飯,工做和玩耍。
咱們假設咱們要在 5 天的時間內跟蹤它,所以咱們的初始數據將以下所示:
1 import matplotlib.pyplot as plt 2 3 days = [1,2,3,4,5] 4 5 sleeping = [7,8,6,11,7] 6 eating = [2,3,4,3,2] 7 working = [7,8,7,2,2] 8 playing = [8,5,7,8,13]
所以,咱們的x
軸將包括day
變量,即 1, 2, 3, 4 和 5。而後,日期的各個成分保存在它們各自的活動中。 像這樣繪製它們:
1 plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k']) 2 3 plt.xlabel('x') 4 plt.ylabel('y') 5 plt.title('Interesting Graph\nCheck it out') 6 plt.show()
在這裏,咱們能夠至少在顏色上看到,咱們如何花費咱們的時間。 問題是,若是不回頭看代碼,咱們不知道什麼顏色是什麼。 下一個問題是,對於多邊形來講,咱們實際上不能爲數據添加『標籤』。 所以,在任何不止是線條,帶有像這樣的填充或堆疊圖的地方,咱們不能以固有方式標記出特定的部分。 這不該該阻止程序員。 咱們能夠解決這個問題:
1 import matplotlib.pyplot as plt 2 3 days = [1,2,3,4,5] 4 5 sleeping = [7,8,6,11,7] 6 eating = [2,3,4,3,2] 7 working = [7,8,7,2,2] 8 playing = [8,5,7,8,13] 9 10 11 plt.plot([],[],color='m', label='Sleeping', linewidth=5) 12 plt.plot([],[],color='c', label='Eating', linewidth=5) 13 plt.plot([],[],color='r', label='Working', linewidth=5) 14 plt.plot([],[],color='k', label='Playing', linewidth=5) 15 16 plt.stackplot(days, sleeping,eating,working,playing, colors=['m','c','r','k']) 17 18 plt.xlabel('x') 19 plt.ylabel('y') 20 plt.title('Interesting Graph\nCheck it out') 21 plt.legend() 22 plt.show()
咱們在這裏作的是畫一些空行,給予它們符合咱們的堆疊圖的相同顏色,和正確標籤。 咱們還使它們線寬爲 5,使線條在圖例中顯得較寬。 如今,咱們能夠很容易地看到,咱們如何花費咱們的時間。
餅圖很像堆疊圖,只是它們位於某個時間點。 一般,餅圖用於顯示部分對於總體的狀況,一般以%爲單位。 幸運的是,Matplotlib 會處理切片大小以及一切事情,咱們只須要提供數值。
1 import matplotlib.pyplot as plt 2 3 slices = [7,2,2,13] 4 activities = ['sleeping','eating','working','playing'] 5 cols = ['c','m','r','b'] 6 7 plt.pie(slices, 8 labels=activities, 9 colors=cols, 10 startangle=90, 11 shadow= True, 12 explode=(0,0.1,0,0), 13 autopct='%1.1f%%') 14 15 plt.title('Interesting Graph\nCheck it out') 16 plt.show()
在plt.pie
中,咱們須要指定『切片』,這是每一個部分的相對大小。 而後,咱們指定相應切片的顏色列表。 接下來,咱們能夠選擇指定圖形的『起始角度』。 這使你能夠在任何地方開始繪圖。 在咱們的例子中,咱們爲餅圖選擇了 90 度角,這意味着第一個部分是一個豎直線條。 接下來,咱們能夠選擇給繪圖添加一個字符大小的陰影,而後咱們甚至可使用explode
拉出一個切片。
咱們總共有四個切片,因此對於explode
,若是咱們不想拉出任何切片,咱們傳入0,0,0,0
。 若是咱們想要拉出第一個切片,咱們傳入0.1,0,0,0
。
最後,咱們使用autopct
,選擇將百分比放置到圖表上面。
不少時候,咱們想要繪製文件中的數據。 有許多類型的文件,以及許多方法,你可使用它們從文件中提取數據來圖形化。 在這裏,咱們將展現幾種方法。 首先,咱們將使用內置的csv
模塊加載CSV文件,而後咱們將展現如何使用 NumPy(第三方模塊)加載文件。
1 import matplotlib.pyplot as plt 2 import csv 3 4 x = [] 5 y = [] 6 7 with open('example.txt','r') as csvfile: 8 plots = csv.reader(csvfile, delimiter=',') 9 for row in plots: 10 x.append(int(row[0])) 11 y.append(int(row[1])) 12 13 plt.plot(x,y, label='Loaded from file!') 14 plt.xlabel('x') 15 plt.ylabel('y') 16 plt.title('Interesting Graph\nCheck it out') 17 plt.legend() 18 plt.show()
這裏,咱們打開樣例文件,包含如下數據:
1,5 2,3 3,4 4,7 5,4 6,3 7,5 8,7 9,4 10,4
接下來,咱們使用csv
模塊讀取數據。 csv
讀取器自動按行分割文件,而後使用咱們選擇的分隔符分割文件中的數據。 在咱們的例子中,這是一個逗號。 注意:csv
模塊和csv reader
不須要文件在字面上是一個.csv文件。 它能夠是任何具備分隔數據的簡單的文本文件。
一旦咱們這樣作了,咱們將索引爲 0 的元素存儲到x
列表,將索引爲 1 的元素存儲到y
列表中。 以後,咱們都設置好了,準備繪圖,而後顯示數據。
雖然使用 CSV 模塊是徹底正常的,但使用 NumPy 模塊來加載咱們的文件和數據,可能對咱們更有意義。 若是你沒有 NumPy,你須要按下面的步驟來獲取它。 爲了瞭解安裝模塊的更多信息,請參閱 pip 教程。 大多數人應該都能打開命令行,並執行pip install numpy
。
若是不能,請參閱連接中的教程。
一旦你安裝了 NumPy,你能夠編寫以下代碼:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 x, y = np.loadtxt('example.txt', delimiter=',', unpack=True) 5 plt.plot(x,y, label='Loaded from file!') 6 7 plt.xlabel('x') 8 plt.ylabel('y') 9 plt.title('Interesting Graph\nCheck it out') 10 plt.legend() 11 plt.show()
結果應該是相同的圖表。 稍後,當咱們加載數據時,咱們能夠利用 NumPy 爲咱們作一些更多的工做,但這是教程將來的內容。 就像csv
模塊不須要一個特意的.csv
同樣,loadtxt
函數不要求文件是一個.txt
文件,它能夠是一個.csv
,它甚至能夠是一個 python 列表對象。
除了從文件加載數據,另外一個流行的數據源是互聯網。 咱們能夠用各類各樣的方式從互聯網加載數據,但對咱們來講,咱們只是簡單地讀取網站的源代碼,而後經過簡單的拆分來分離數據。
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import matplotlib.dates as mdates 5 6 7 def graph_data(stock): 8 9 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 10 11 source_code = urllib.request.urlopen(stock_price_url).read().decode() 12 13 stock_data = [] 14 split_source = source_code.split('\n') 15 16 for line in split_source: 17 split_line = line.split(',') 18 if len(split_line) == 6: 19 if 'values' not in line: 20 stock_data.append(line)
這裏有不少步驟。首先,咱們看到import
。 pyplot
像往常同樣導入,而後導入了numpy
,而後是用於訪問互聯網的urllib
,而後導入了matplotlib.dates
做爲mdates
,它對於將日期戳轉換爲 matplotlib 能夠理解的日期頗有用。
接下來,咱們開始構建咱們的graph_data
函數。在這裏,咱們首先定義包含股票數據的網址。以後,咱們寫一些urllib
代碼來訪問該 URL,而後使用.read
讀取源代碼,以後咱們繼續解碼該數據。若是你使用 Python 2,則沒必要使用decode
。
而後,咱們定義一個空列表,這是咱們將要放置股票數據的地方,咱們也開始使用split_source
變量拆分數據,以換行符拆分。
如今,若是你去看源代碼,用stock
替換 URL 中的+stock+
,像 AAPL 那樣,你能夠看到大多數頁面數據確實是股票訂價信息,但有一些頭信息咱們須要過濾掉。爲此,咱們使用一些基本的過濾,檢查它們來確保每行有 6 個數據點,而後確保術語values
不在行中。
如今,咱們已經解析了數據,並作好了準備。咱們將使用 NumPy:
1 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 2 delimiter=',', 3 unpack=True, 4 # %Y = full year. 2015 5 # %y = partial year 15 6 # %m = number month 7 # %d = number day 8 # %H = hours 9 # %M = minutes 10 # %S = seconds 11 # 12-06-2014 12 # %m-%d-%Y 13 converters={0: bytespdate2num('%Y%m%d')})
咱們在這裏所作的是,使用numpy
的loadtxt
函數,並將這六個元素解構到六個變量。 這裏的第一個參數是stock_data
,這是咱們加載的數據。 而後,咱們指定delimiter
(這裏是逗號),而後咱們指定咱們確實想要在這裏解包變量,不是一個變量,而是咱們定義的這組變量。 最後,咱們使用可選的converters
參數來指定咱們要轉換的元素(0
),以及咱們打算要怎麼作。 咱們傳遞一個名爲bytespdate2num
的函數,它還不存在,但咱們下面會編寫它。
本教程的重點是未來自 Yahoo finance API 的日期轉換爲 Matplotlib 可理解的日期。 爲了實現它,咱們要寫一個新的函數,bytespdate2num
。
def bytespdate2num(fmt, encoding='utf-8'): strconverter = mdates.strpdate2num(fmt) def bytesconverter(b): s = b.decode(encoding) return strconverter(s) return bytesconverter
此函數接受數據,基於編碼來解碼數據,而後返回它。
將此應用於咱們的程序的其他部分:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import matplotlib.dates as mdates 5 6 def bytespdate2num(fmt, encoding='utf-8'): 7 strconverter = mdates.strpdate2num(fmt) 8 def bytesconverter(b): 9 s = b.decode(encoding) 10 return strconverter(s) 11 return bytesconverter 12 13 14 def graph_data(stock): 15 16 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 17 source_code = urllib.request.urlopen(stock_price_url).read().decode() 18 stock_data = [] 19 split_source = source_code.split('\n') 20 for line in split_source: 21 split_line = line.split(',') 22 if len(split_line) == 6: 23 if 'values' not in line and 'labels' not in line: 24 stock_data.append(line) 25 26 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 27 delimiter=',', 28 unpack=True, 29 # %Y = full year. 2015 30 # %y = partial year 15 31 # %m = number month 32 # %d = number day 33 # %H = hours 34 # %M = minutes 35 # %S = seconds 36 # 12-06-2014 37 # %m-%d-%Y 38 converters={0: bytespdate2num('%Y%m%d')}) 39 40 plt.plot_date(date, closep,'-', label='Price') 41 42 plt.xlabel('Date') 43 plt.ylabel('Price') 44 plt.title('Interesting Graph\nCheck it out') 45 plt.legend() 46 plt.show() 47 48 49 graph_data('TSLA')
若是你繪製 TSLA,結果圖應該看起來像這樣:
在 Matplotlib 教程中,咱們將討論一些可能的圖表自定義。 爲了開始修改子圖,咱們必須定義它們。 咱們很快會談論他們,但有兩種定義並構造子圖的主要方法。 如今,咱們只使用其中一個,但咱們會很快解釋它們。
如今,修改咱們的graph_data
函數:
def graph_data(stock): fig = plt.figure() ax1 = plt.subplot2grid((1,1), (0,0))
爲了修改圖表,咱們須要引用它,因此咱們將它存儲到變量fig
。 而後咱們將ax1
定義爲圖表上的子圖。 咱們在這裏使用subplot2grid
,這是獲取子圖的兩種主要方法之一。 咱們將深刻討論這些東西,但如今,你應該看到咱們有 2 個元組,它們提供了(1,1)
和(0,0)
。 1,1
代表這是一個 1×1 網格。 而後0,0
代表這個子圖的『起點』將爲0,0
。
接下來,經過咱們已經編寫的代碼來獲取和解析數據:
1 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 2 source_code = urllib.request.urlopen(stock_price_url).read().decode() 3 stock_data = [] 4 split_source = source_code.split('\n') 5 for line in split_source: 6 split_line = line.split(',') 7 if len(split_line) == 6: 8 if 'values' not in line and 'labels' not in line: 9 stock_data.append(line) 10 11 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 12 delimiter=',', 13 unpack=True, 14 converters={0: bytespdate2num('%Y%m%d')})
下面,咱們這樣繪製數據:
ax1.plot_date(date, closep,'-', label='Price')
如今,因爲咱們正在繪製日期,咱們可能會發現,若是咱們放大,日期會在水平方向上移動。可是,咱們能夠自定義這些刻度標籤,像這樣:
ax1.plot_date(date, closep,'-', label='Price')
這將使標籤轉動到對角線方向。 接下來,咱們能夠添加一個網格:
ax1.grid(True)
而後,其它東西咱們保留默認,但咱們也可能須要略微調整繪圖,由於日期跑到了圖表外面。 記不記得咱們在第一篇教程中討論的configure subplots
按鈕? 咱們不只能夠以這種方式配置圖表,咱們還能夠在代碼中配置它們,如下是咱們設置這些參數的方式:
plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0)
如今,爲了防止咱們把你遺留在某個地方,這裏是完整的代碼:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import matplotlib.dates as mdates 5 6 def bytespdate2num(fmt, encoding='utf-8'): 7 strconverter = mdates.strpdate2num(fmt) 8 def bytesconverter(b): 9 s = b.decode(encoding) 10 return strconverter(s) 11 return bytesconverter 12 13 14 def graph_data(stock): 15 16 fig = plt.figure() 17 ax1 = plt.subplot2grid((1,1), (0,0)) 18 19 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 20 source_code = urllib.request.urlopen(stock_price_url).read().decode() 21 stock_data = [] 22 split_source = source_code.split('\n') 23 for line in split_source: 24 split_line = line.split(',') 25 if len(split_line) == 6: 26 if 'values' not in line and 'labels' not in line: 27 stock_data.append(line) 28 29 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 30 delimiter=',', 31 unpack=True, 32 converters={0: bytespdate2num('%Y%m%d')}) 33 34 ax1.plot_date(date, closep,'-', label='Price') 35 for label in ax1.xaxis.get_ticklabels(): 36 label.set_rotation(45) 37 ax1.grid(True)#, color='g', linestyle='-', linewidth=5) 38 39 plt.xlabel('Date') 40 plt.ylabel('Price') 41 plt.title('Interesting Graph\nCheck it out') 42 plt.legend() 43 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 44 plt.show() 45 46 47 graph_data('TSLA')
結果爲:
在這個 Matplotlib 教程中,咱們將介紹如何處理 unix 時間戳的轉換,而後在圖形中繪製日期戳。 使用 Yahoo Finance API,你會注意到,若是你使用較大的時間間隔,如1y
(一年),你會獲得咱們一直在使用的日期戳,但若是你使用10d
(10 天),反之你會獲得 unix 時間的時間戳。
Unix 時間是 1970 年 1 月 1 日之後的秒數,它是跨程序的標準化時間表示方法。 也就是說,Matplotlib 並不歡迎 unix 時間戳。 這裏是你可使用 Matplotlib 來處理 unix 時間的方式:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import datetime as dt 5 import matplotlib.dates as mdates 6 7 def bytespdate2num(fmt, encoding='utf-8'): 8 strconverter = mdates.strpdate2num(fmt) 9 def bytesconverter(b): 10 s = b.decode(encoding) 11 return strconverter(s) 12 return bytesconverter 13 14 15 def graph_data(stock): 16 17 fig = plt.figure() 18 ax1 = plt.subplot2grid((1,1), (0,0)) 19 20 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10d/csv' 21 source_code = urllib.request.urlopen(stock_price_url).read().decode() 22 stock_data = [] 23 split_source = source_code.split('\n') 24 for line in split_source: 25 split_line = line.split(',') 26 if len(split_line) == 6: 27 if 'values' not in line and 'labels' not in line: 28 stock_data.append(line) 29 30 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 31 delimiter=',', 32 unpack=True) 33 dateconv = np.vectorize(dt.datetime.fromtimestamp) 34 date = dateconv(date) 35 36 ## date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 37 ## delimiter=',', 38 ## unpack=True, 39 ## converters={0: bytespdate2num('%Y%m%d')}) 40 41 ax1.plot_date(date, closep,'-', label='Price') 42 for label in ax1.xaxis.get_ticklabels(): 43 label.set_rotation(45) 44 ax1.grid(True)#, color='g', linestyle='-', linewidth=5) 45 46 plt.xlabel('Date') 47 plt.ylabel('Price') 48 plt.title('Interesting Graph\nCheck it out') 49 plt.legend() 50 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 51 plt.show() 52 53 54 graph_data('TSLA')
因此在這裏,咱們所作的是 unix 時間的寫入處理,並註釋掉咱們之前的代碼,由於咱們爲以後的使用而保存它。 這裏的主要區別是:
dateconv = np.vectorize(dt.datetime.fromtimestamp) date = dateconv(date)
這裏,咱們將時間戳轉換爲日期戳,而後將其轉換爲 Matplotlib 想要的時間。
如今,因爲某些緣由,個人 unix 時間帶有另外一行包含 6 個元素的數據,而且它包含了術語label
,所以,在咱們解析數據的for
循環中,咱們爲你再添加一個須要注意的檢查:
1 for line in split_source: 2 split_line = line.split(',') 3 if len(split_line) == 6: 4 if 'values' not in line and 'labels' not in line: 5 stock_data.append(line)
如今你的圖表應該相似:
這裏的全部扁平線條的緣由是市場關閉。 有了這個短時間數據,咱們能夠獲得日內數據。 因此交易開放時有不少點,而後市場關閉時就沒有了,而後又是一堆,而後又是沒有。
在本教程中,咱們將介紹一些更多的自定義,好比顏色和線條填充。
咱們要作的第一個改動是將plt.title
更改成stock
變量。
plt.title(stock)
如今,讓咱們來介紹一下如何更改標籤顏色。 咱們能夠經過修改咱們的軸對象來實現:
ax1.xaxis.label.set_color('c') ax1.yaxis.label.set_color('r')
若是咱們運行它,咱們會看到標籤改變了顏色,就像在單詞中那樣。
接下來,咱們能夠爲要顯示的軸指定具體數字,而不是像這樣的自動選擇:
ax1.set_yticks([0,25,50,75])
接下來,我想介紹填充。 填充所作的事情,是在變量和你選擇的一個數值之間填充顏色。 例如,咱們能夠這樣:
ax1.fill_between(date, 0, closep)
因此到這裏,咱們的代碼爲:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import datetime as dt 5 import matplotlib.dates as mdates 6 7 def bytespdate2num(fmt, encoding='utf-8'): 8 strconverter = mdates.strpdate2num(fmt) 9 def bytesconverter(b): 10 s = b.decode(encoding) 11 return strconverter(s) 12 return bytesconverter 13 14 15 def graph_data(stock): 16 17 fig = plt.figure() 18 ax1 = plt.subplot2grid((1,1), (0,0)) 19 20 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 21 source_code = urllib.request.urlopen(stock_price_url).read().decode() 22 stock_data = [] 23 split_source = source_code.split('\n') 24 for line in split_source: 25 split_line = line.split(',') 26 if len(split_line) == 6: 27 if 'values' not in line and 'labels' not in line: 28 stock_data.append(line) 29 30 31 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 32 delimiter=',', 33 unpack=True, 34 converters={0: bytespdate2num('%Y%m%d')}) 35 36 ax1.fill_between(date, 0, closep) 37 38 for label in ax1.xaxis.get_ticklabels(): 39 label.set_rotation(45) 40 ax1.grid(True)#, color='g', linestyle='-', linewidth=5) 41 ax1.xaxis.label.set_color('c') 42 ax1.yaxis.label.set_color('r') 43 ax1.set_yticks([0,25,50,75]) 44 45 plt.xlabel('Date') 46 plt.ylabel('Price') 47 plt.title(stock) 48 plt.legend() 49 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 50 plt.show() 51 52 53 graph_data('EBAY')
結果爲:
填充的一個問題是,咱們可能最後會把東西都覆蓋起來。 咱們能夠用透明度來解決它:
ax1.fill_between(date, 0, closep)
如今,讓咱們介紹條件填充。 讓咱們假設圖表的起始位置是咱們開始買入 eBay 的地方。 這裏,若是價格低於這個價格,咱們能夠向上填充到原來的價格,而後若是它超過了原始價格,咱們能夠向下填充。 咱們能夠這樣作:
ax1.fill_between(date, closep[0], closep)
會生成:
若是咱們想用紅色和綠色填充來展現收益/損失,那麼與原始價格相比,綠色填充用於上升(注:國外股市的顏色和國內相反),紅色填充用於下跌? 沒問題! 咱們能夠添加一個where
參數,以下所示:
ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5)
這裏,咱們填充當前價格和原始價格之間的區域,其中當前價格高於原始價格。 咱們給予它綠色的前景色,由於這是一個上升,並且咱們使用微小的透明度。
咱們仍然不能對多邊形數據(如填充)應用標籤,但咱們能夠像之前同樣實現空線條,所以咱們能夠:
1 ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5) 2 ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5) 3 4 ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5) 5 ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5)
這向咱們提供了一些填充,以及用於處理標籤的空線條,咱們打算將其顯示在圖例中。這裏完整的代碼是:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import datetime as dt 5 import matplotlib.dates as mdates 6 7 def bytespdate2num(fmt, encoding='utf-8'): 8 strconverter = mdates.strpdate2num(fmt) 9 def bytesconverter(b): 10 s = b.decode(encoding) 11 return strconverter(s) 12 return bytesconverter 13 14 15 def graph_data(stock): 16 17 fig = plt.figure() 18 ax1 = plt.subplot2grid((1,1), (0,0)) 19 20 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 21 source_code = urllib.request.urlopen(stock_price_url).read().decode() 22 stock_data = [] 23 split_source = source_code.split('\n') 24 for line in split_source: 25 split_line = line.split(',') 26 if len(split_line) == 6: 27 if 'values' not in line and 'labels' not in line: 28 stock_data.append(line) 29 30 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 31 delimiter=',', 32 unpack=True, 33 converters={0: bytespdate2num('%Y%m%d')}) 34 35 ax1.plot_date(date, closep,'-', label='Price') 36 37 ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5) 38 ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5) 39 40 ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5) 41 ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5) 42 43 for label in ax1.xaxis.get_ticklabels(): 44 label.set_rotation(45) 45 ax1.grid(True)#, color='g', linestyle='-', linewidth=5) 46 ax1.xaxis.label.set_color('c') 47 ax1.yaxis.label.set_color('r') 48 ax1.set_yticks([0,25,50,75]) 49 50 plt.xlabel('Date') 51 plt.ylabel('Price') 52 plt.title(stock) 53 plt.legend() 54 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 55 plt.show() 56 57 58 graph_data('EBAY')
如今咱們的結果是:
歡迎閱讀另外一個定製教程,在這裏咱們使用 Matplotlib 討論邊框和水平線條。 有時候你可能想作的事情是改變邊框的顏色,或者甚至徹底刪除它們。
圖形的邊框基本上是圖形的邊界,其中有刻度線等東西。爲了改變邊框的顏色,你能夠作一些相似這樣的事情:
ax1.spines['left'].set_color('c')
在這裏,咱們引用了咱們的邊框字典,表示咱們要調整左邊框,而後咱們使用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')
如今咱們的日期是橙色了! 接下來,讓咱們來看看咱們如何繪製一條水平線。 你固然能夠將你建立的一組新數據繪製成一條水平線,但你不須要這樣作。 你能夠:
ax1.axhline(closep[0], color='k', linewidth=5)
因此在這裏,咱們的整個代碼是:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 import urllib 4 import datetime as dt 5 import matplotlib.dates as mdates 6 7 def bytespdate2num(fmt, encoding='utf-8'): 8 strconverter = mdates.strpdate2num(fmt) 9 def bytesconverter(b): 10 s = b.decode(encoding) 11 return strconverter(s) 12 return bytesconverter 13 14 15 def graph_data(stock): 16 17 fig = plt.figure() 18 ax1 = plt.subplot2grid((1,1), (0,0)) 19 20 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=10y/csv' 21 source_code = urllib.request.urlopen(stock_price_url).read().decode() 22 stock_data = [] 23 split_source = source_code.split('\n') 24 for line in split_source: 25 split_line = line.split(',') 26 if len(split_line) == 6: 27 if 'values' not in line and 'labels' not in line: 28 stock_data.append(line) 29 30 31 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 32 delimiter=',', 33 unpack=True, 34 converters={0: bytespdate2num('%Y%m%d')}) 35 36 ax1.plot_date(date, closep,'-', label='Price') 37 ax1.plot([],[],linewidth=5, label='loss', color='r',alpha=0.5) 38 ax1.plot([],[],linewidth=5, label='gain', color='g',alpha=0.5) 39 ax1.axhline(closep[0], color='k', linewidth=5) 40 ax1.fill_between(date, closep, closep[0],where=(closep > closep[0]), facecolor='g', alpha=0.5) 41 ax1.fill_between(date, closep, closep[0],where=(closep < closep[0]), facecolor='r', alpha=0.5) 42 43 for label in ax1.xaxis.get_ticklabels(): 44 label.set_rotation(45) 45 ax1.grid(True) 46 #ax1.xaxis.label.set_color('c') 47 #ax1.yaxis.label.set_color('r') 48 ax1.set_yticks([0,25,50,75]) 49 50 ax1.spines['left'].set_color('c') 51 ax1.spines['right'].set_visible(False) 52 ax1.spines['top'].set_visible(False) 53 ax1.spines['left'].set_linewidth(5) 54 55 ax1.tick_params(axis='x', colors='#f06215') 56 57 58 59 60 plt.xlabel('Date') 61 plt.ylabel('Price') 62 plt.title(stock) 63 plt.legend() 64 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 65 plt.show() 66 67 68 graph_data('ebay')
結果爲:
在 Matplotlib 教程中,咱們將介紹如何在 Matplotlib 中建立開,高,低,關(OHLC)的 K 線圖。 這些圖表用於以精簡形式顯示時間序列股價信息。 爲了實現它,咱們首先須要導入一些模塊:
import matplotlib.ticker as mticker from matplotlib.finance import candlestick_ohlc
咱們引入了ticker
,容許咱們修改圖表底部的ticker
信息。 而後咱們從matplotlib.finance
模塊中引入candlestick_ohlc
功能。
如今,咱們須要組織咱們的數據來和 matplotlib 協做。 若是你剛剛加入咱們,咱們獲得的數據以下:
1 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 2 source_code = urllib.request.urlopen(stock_price_url).read().decode() 3 stock_data = [] 4 split_source = source_code.split('\n') 5 for line in split_source: 6 split_line = line.split(',') 7 if len(split_line) == 6: 8 if 'values' not in line and 'labels' not in line: 9 stock_data.append(line) 10 11 12 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 13 delimiter=',', 14 unpack=True, 15 converters={0: bytespdate2num('%Y%m%d')})
如今,咱們須要構建一個 Python 列表,其中每一個元素都是數據。 咱們能夠修改咱們的loadtxt
函數,使其不解構,但隨後咱們仍是但願引用特定的數據點。 咱們能夠解決這個問題,可是咱們最後可能只擁有兩個單獨的數據集。 爲此,咱們執行如下操做:
1 x = 0 2 y = len(date) 3 ohlc = [] 4 5 while x < y: 6 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 7 ohlc.append(append_me) 8 x+=1
有了這個,咱們如今將 OHLC 數據列表存儲到咱們的變量ohlc
。 如今咱們能夠這樣繪製:
candlestick_ohlc(ax1, ohlc)
圖表應該是這樣:
不幸的是,x
軸上的datetime
數據不是日期戳的形式。 咱們能夠處理它:
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
此外,紅/黑着色依我看不是最好的選擇。 咱們應該使用綠色表示上升和紅色表示降低。 爲此,咱們能夠:
candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f')
最後,咱們能夠將x
標籤設置爲咱們想要的數量,像這樣:
ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
如今,完整代碼如今是這樣:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 6 import numpy as np 7 import urllib 8 import datetime as dt 9 10 11 def bytespdate2num(fmt, encoding='utf-8'): 12 strconverter = mdates.strpdate2num(fmt) 13 def bytesconverter(b): 14 s = b.decode(encoding) 15 return strconverter(s) 16 return bytesconverter 17 18 19 def graph_data(stock): 20 21 fig = plt.figure() 22 ax1 = plt.subplot2grid((1,1), (0,0)) 23 24 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 25 source_code = urllib.request.urlopen(stock_price_url).read().decode() 26 stock_data = [] 27 split_source = source_code.split('\n') 28 for line in split_source: 29 split_line = line.split(',') 30 if len(split_line) == 6: 31 if 'values' not in line and 'labels' not in line: 32 stock_data.append(line) 33 34 35 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 36 delimiter=',', 37 unpack=True, 38 converters={0: bytespdate2num('%Y%m%d')}) 39 40 x = 0 41 y = len(date) 42 ohlc = [] 43 44 while x < y: 45 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 46 ohlc.append(append_me) 47 x+=1 48 49 50 candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 51 52 for label in ax1.xaxis.get_ticklabels(): 53 label.set_rotation(45) 54 55 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 56 ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 57 ax1.grid(True) 58 59 60 plt.xlabel('Date') 61 plt.ylabel('Price') 62 plt.title(stock) 63 plt.legend() 64 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 65 plt.show() 66 67 68 graph_data('EBAY')
結果爲:
還要注意,咱們從前面的教程中刪除了大部分ax1
的修改。
在這個 Matplotlib 教程中,咱們將討論樣式。 咱們用於 Matplotlib 的樣式很是類似於用於 HTML 頁面的 CSS(層疊樣式表)。 正如你在這裏能夠看到的,咱們對圖形所作的全部修改都會疊加,並且咱們目前只有一個軸域。 咱們可使用for
循環,至少使代碼量下降,但咱們也能夠在 Matplotlib 中利用這些樣式。
樣式頁的想法是將自定義樣式寫入文件,而後,爲了使用這些更改並將其應用於圖形,全部你須要作的就是導入樣式,而後使用該特定樣式。 這樣,讓咱們假設你發現本身老是改變圖形的各類元素。 你沒必要爲每一個圖表編寫 25 ~ 200 行自定義代碼,只需將其寫入一個樣式,而後加載該樣式,並以兩行應用全部這些更改便可! 讓咱們開始吧。
from matplotlib import style
接下來,咱們指定要使用的樣式。 Matplotlib 已經有了幾種樣式。
咱們能夠這樣來使用樣式:
style.use('ggplot')
除了標題,標籤的顏色是灰色的,軸域的背景是淺灰色,咱們能夠當即分辨字體是不一樣的。 咱們還注意到,網格其實是一個白色的實線。 咱們的 K 線圖保持不變,主要是由於咱們在過後定製它。 在樣式中加載時,更改會生效,但若是在加載樣式後編寫新的自定義代碼,你的更改也會生效。
由於咱們試圖展現樣式模塊,可是讓咱們繼續,簡單繪製幾行,並暫且註釋掉 K 線圖:
#candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') ax1.plot(date,closep) ax1.plot(date,openp)
會生成:
已經比默認值好多了!
樣式的另外一個例子是fivethirtyeight
:
你能夠這樣查看全部的可用樣式:
print(plt.style.available)
我這裏它提供了['bmh', 'dark_background', 'ggplot', 'fivethirtyeight', 'grayscale']
。
讓咱們嘗試dark_background
:
style.use('dark_background')
如今,若是你想製做本身的風格呢? 首先,你須要找到樣式目錄。 爲了實現它,若是你知道它在哪裏,你能夠前往你的 matplotlib 目錄,或者你能夠找到該目錄。 若是你不知道如何找到該目錄,你能夠執行如下操做:
print(plt.__file__)
這至少會告訴你pyplot
模塊的位置。
在 matplotlib 目錄中,你須要尋找mpl-data
。 而後在那裏,你須要尋找stylelib
。 在 Windows 上 ,個人完整路徑是:C:\Python34\Lib\site-packages\matplotlib\mpl-data\stylelib
。
那裏應該顯示了全部可用的.mplstyle
文件。 你能夠編輯、複製或重命名它們,而後在那裏修改成你想要的東西。 而後,不管你用什麼來命名.mplstyle
文件,都要放在style.use
中。
在這篇 Matplotlib 教程中,咱們將介紹如何建立實時更新圖表,能夠在數據源更新時更新其圖表。 你可能但願將此用於繪製股票實時訂價數據,或者能夠將傳感器鏈接到計算機,而且顯示傳感器實時數據。 爲此,咱們使用 Matplotlib 的動畫功能。
最開始:
import matplotlib.pyplot as plt import matplotlib.animation as animation from matplotlib import style
這裏,惟一的新增導入是matplotlib.animation as animation
。 這是一個模塊,容許咱們在顯示以後對圖形進行動畫處理。
接下來,咱們添加一些你熟悉的代碼,若是你一直關注這個系列:
style.use('fivethirtyeight') fig = plt.figure() ax1 = fig.add_subplot(1,1,1)
如今咱們編寫動畫函數:
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)
咱們在這裏作的是構建數據,而後繪製它。 注意咱們這裏不調用plt.show()
。 咱們從一個示例文件讀取數據,其內容以下:
1,5 2,3 3,4 4,7 5,4 6,3 7,5 8,7 9,4 10,4
咱們打開上面的文件,而後存儲每一行,用逗號分割成xs
和ys
,咱們將要繪製它。 而後:
ani = animation.FuncAnimation(fig, animate, interval=1000) plt.show()
咱們運行動畫,將動畫放到圖表中(fig
),運行animate
的動畫函數,最後咱們設置了 1000 的間隔,即 1000 毫秒或 1 秒。
運行此圖表的結果應該像往常同樣生成圖表。 而後,你應該可以使用新的座標更新example.txt
文件。 這樣作會生成一個自動更新的圖表,以下:
在本教程中,咱們將討論如何向 Matplotlib 圖形添加文本。 咱們能夠經過兩種方式來實現。 一種是將文本放置在圖表上的某個位置。 另外一個是專門註解圖表上的繪圖,來引發注意。
這裏的起始代碼是教程 15,它在這裏:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 17 def bytespdate2num(fmt, encoding='utf-8'): 18 strconverter = mdates.strpdate2num(fmt) 19 def bytesconverter(b): 20 s = b.decode(encoding) 21 return strconverter(s) 22 return bytesconverter 23 24 25 def graph_data(stock): 26 27 fig = plt.figure() 28 ax1 = plt.subplot2grid((1,1), (0,0)) 29 30 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 31 source_code = urllib.request.urlopen(stock_price_url).read().decode() 32 stock_data = [] 33 split_source = source_code.split('\n') 34 for line in split_source: 35 split_line = line.split(',') 36 if len(split_line) == 6: 37 if 'values' not in line and 'labels' not in line: 38 stock_data.append(line) 39 40 41 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 42 delimiter=',', 43 unpack=True, 44 converters={0: bytespdate2num('%Y%m%d')}) 45 46 x = 0 47 y = len(date) 48 ohlc = [] 49 50 while x < y: 51 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 52 ohlc.append(append_me) 53 x+=1 54 55 56 candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 57 58 for label in ax1.xaxis.get_ticklabels(): 59 label.set_rotation(45) 60 61 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 62 ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 63 ax1.grid(True) 64 65 66 plt.xlabel('Date') 67 plt.ylabel('Price') 68 plt.title(stock) 69 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 70 plt.show() 71 72 73 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
添加文本。 咱們使用咱們的數據,以座標形式給出此文本的位置。 首先給出文本的座標,而後給出要放置的實際文本。 接下來,咱們使用fontdict
參數添加一個數據字典,來使用所用的字體。 在咱們的字體字典中,咱們將字體更改成serif
,顏色爲『深紅色』,而後將字體大小更改成 15。這將所有應用於咱們的圖表上的文本,以下所示:
太棒了,接下來咱們能夠作的是,註解某個特定的繪圖。 咱們但願這樣作來給出更多的信息。 在 eBay 的例子中,也許咱們想解釋某個具體繪圖,或給出一些關於發生了什麼的信息。 在股價的例子中,也許有一些發生的新聞會影響價格。 你能夠註解新聞來自哪裏,這將有助於解釋訂價變化。
ax1.annotate('Bad News!',(date[9],highp[9]), xytext=(0.8, 0.9), textcoords='axes fraction', arrowprops = dict(facecolor='grey',color='grey'))
這裏,咱們用ax1.annotate
來註解。 咱們首先傳遞咱們想要註解的文本,而後傳遞咱們讓這個註解指向的座標。 咱們這樣作,是由於當咱們註釋時,咱們能夠繪製線條和指向特定點的箭頭。 接下來,咱們指定xytext
的位置。 它能夠是像咱們用於文本放置的座標位置,可是讓咱們展現另外一個例子。 它能夠爲軸域小數,因此咱們使用 0.8 和 0.9。 這意味着文本的位置在x
軸的80%和y
軸的90%處。 這樣,若是咱們移動圖表,文本將保持在相同位置。
執行它,會生成:
根據你學習這個教程的時間,所指向的點可能有所不一樣,這只是一個註解的例子,其中有一些合理的想法,即爲何咱們須要註解一些東西。
當圖表啓動時,請嘗試單擊平移按鈕(藍色十字),而後移動圖表。 你會看到文本保持不動,但箭頭跟隨移動並繼續指向咱們想要的具體的點。 這很酷吧!
最後一個圖表的完整代碼:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 17 def bytespdate2num(fmt, encoding='utf-8'): 18 strconverter = mdates.strpdate2num(fmt) 19 def bytesconverter(b): 20 s = b.decode(encoding) 21 return strconverter(s) 22 return bytesconverter 23 24 25 def graph_data(stock): 26 27 fig = plt.figure() 28 ax1 = plt.subplot2grid((1,1), (0,0)) 29 30 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 31 source_code = urllib.request.urlopen(stock_price_url).read().decode() 32 stock_data = [] 33 split_source = source_code.split('\n') 34 for line in split_source: 35 split_line = line.split(',') 36 if len(split_line) == 6: 37 if 'values' not in line and 'labels' not in line: 38 stock_data.append(line) 39 40 41 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 42 delimiter=',', 43 unpack=True, 44 converters={0: bytespdate2num('%Y%m%d')}) 45 46 x = 0 47 y = len(date) 48 ohlc = [] 49 50 while x < y: 51 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 52 ohlc.append(append_me) 53 x+=1 54 55 56 candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 57 58 for label in ax1.xaxis.get_ticklabels(): 59 label.set_rotation(45) 60 61 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 62 ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 63 ax1.grid(True) 64 ax1.annotate('Bad News!',(date[9],highp[9]), 65 xytext=(0.8, 0.9), textcoords='axes fraction', 66 arrowprops = dict(facecolor='grey',color='grey')) 67 68 ## # Text placement example: 69 ## font_dict = {'family':'serif', 70 ## 'color':'darkred', 71 ## 'size':15} 72 ## ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict) 73 74 plt.xlabel('Date') 75 plt.ylabel('Price') 76 plt.title(stock) 77 #plt.legend() 78 plt.subplots_adjust(left=0.09, bottom=0.20, right=0.94, top=0.90, wspace=0.2, hspace=0) 79 plt.show() 80 81 82 graph_data('ebay')
如今,使用註解,咱們能夠作一些其餘事情,如註解股票圖表的最後價格。 這就是咱們接下來要作的。
在這個 Matplotlib 教程中,咱們將展現如何跟蹤股票的最後價格的示例,經過將其註解到軸域的右側,就像許多圖表應用程序會作的那樣。
雖然人們喜歡在他們的實時圖表中看到歷史價格,他們也想看到最新的價格。 大多數應用程序作的是,在價格的y
軸高度處註釋最後價格,而後突出顯示它,並在價格變化時,在框中將其略微移動。 使用咱們最近學習的註解教程,咱們能夠添加一個bbox
。
咱們的核心代碼是:
bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax1.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+4, closep[-1]), bbox=bbox_props)
咱們使用ax1.annotate
來放置最後價格的字符串值。 咱們不在這裏使用它,但咱們將要註解的點指定爲圖上最後一個點。 接下來,咱們使用xytext
將咱們的文本放置到特定位置。 咱們將它的y
座標指定爲最後一個點的y
座標,x
座標指定爲最後一個點的x
座標,再加上幾個點。咱們這樣作是爲了將它移出圖表。 將文本放在圖形外面就足夠了,但如今它只是一些浮動文本。
咱們使用bbox
參數在文本週圍建立一個框。 咱們使用bbox_props
建立一個屬性字典,包含盒子樣式,而後是白色(w
)前景色,黑色(k
)邊框顏色而且線寬爲 1。 更多框樣式請參閱 matplotlib 註解文檔。
最後,這個註解向右移動,須要咱們使用subplots_adjust
來建立一些新空間:
plt.subplots_adjust(left=0.11, bottom=0.24, right=0.87, top=0.90, wspace=0.2, hspace=0)
這裏的完整代碼以下:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 17 def bytespdate2num(fmt, encoding='utf-8'): 18 strconverter = mdates.strpdate2num(fmt) 19 def bytesconverter(b): 20 s = b.decode(encoding) 21 return strconverter(s) 22 return bytesconverter 23 24 25 def graph_data(stock): 26 27 fig = plt.figure() 28 ax1 = plt.subplot2grid((1,1), (0,0)) 29 30 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 31 source_code = urllib.request.urlopen(stock_price_url).read().decode() 32 stock_data = [] 33 split_source = source_code.split('\n') 34 for line in split_source: 35 split_line = line.split(',') 36 if len(split_line) == 6: 37 if 'values' not in line and 'labels' not in line: 38 stock_data.append(line) 39 40 41 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 42 delimiter=',', 43 unpack=True, 44 converters={0: bytespdate2num('%Y%m%d')}) 45 46 x = 0 47 y = len(date) 48 ohlc = [] 49 50 while x < y: 51 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 52 ohlc.append(append_me) 53 x+=1 54 55 56 candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 57 58 for label in ax1.xaxis.get_ticklabels(): 59 label.set_rotation(45) 60 61 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 62 ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 63 ax1.grid(True) 64 65 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 66 67 ax1.annotate(str(closep[-1]), (date[-1], closep[-1]), 68 xytext = (date[-1]+3, closep[-1]), bbox=bbox_props) 69 70 71 ## # Annotation example with arrow 72 ## ax1.annotate('Bad News!',(date[11],highp[11]), 73 ## xytext=(0.8, 0.9), textcoords='axes fraction', 74 ## arrowprops = dict(facecolor='grey',color='grey')) 75 ## 76 ## 77 ## # Font dict example 78 ## font_dict = {'family':'serif', 79 ## 'color':'darkred', 80 ## 'size':15} 81 ## # Hard coded text 82 ## ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict) 83 84 plt.xlabel('Date') 85 plt.ylabel('Price') 86 plt.title(stock) 87 #plt.legend() 88 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.87, top=0.90, wspace=0.2, hspace=0) 89 plt.show() 90 91 92 graph_data('EBAY')
結果爲:
在這個 Matplotlib 教程中,咱們將討論子圖。 有兩種處理子圖的主要方法,用於在同一圖上建立多個圖表。 如今,咱們將從一個乾淨的代碼開始。 若是你一直關注這個教程,那麼請確保保留舊的代碼,或者你能夠隨時從新查看上一個教程的代碼。
首先,讓咱們使用樣式,建立咱們的圖表,而後建立一個隨機建立示例繪圖的函數:
1 import random 2 import matplotlib.pyplot as plt 3 from matplotlib import style 4 5 style.use('fivethirtyeight') 6 7 fig = plt.figure() 8 9 def create_plots(): 10 xs = [] 11 ys = [] 12 13 for i in range(10): 14 x = i 15 y = random.randrange(10) 16 17 xs.append(x) 18 ys.append(y) 19 return xs, ys
如今,咱們開始使用add_subplot
方法建立子圖:
ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(212)
它的工做原理是使用 3 個數字,即:行數(numRows
)、列數(numCols
)和繪圖編號(plotNum
)。
因此,221 表示兩行兩列的第一個位置。222 是兩行兩列的第二個位置。最後,212 是兩行一列的第二個位置。
2x2:
+-----+-----+ | 1 | 2 | +-----+-----+ | 3 | 4 | +-----+-----+ 2x1: +-----------+ | 1 | +-----------+ | 2 | +-----------+
譯者注:原文此處表述有誤,譯文已更改。
譯者注:
221
是縮寫形式,僅在行數乘列數小於 10 時有效,不然要寫成2,2,1
。
此代碼結果爲:
這就是add_subplot
。 嘗試一些你認爲可能頗有趣的配置,而後嘗試使用add_subplot
建立它們,直到你感到滿意。
接下來,讓咱們介紹另外一種方法,它是subplot2grid
。
刪除或註釋掉其餘軸域定義,而後添加:
ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1)
因此,add_subplot
不能讓咱們使一個繪圖覆蓋多個位置。 可是這個新的subplot2grid
能夠。 因此,subplot2grid
的工做方式是首先傳遞一個元組,它是網格形狀。 咱們傳遞了(6,1)
,這意味着整個圖表分爲六行一列。 下一個元組是左上角的起始點。 對於ax1
,這是0,0
,所以它起始於頂部。 接下來,咱們能夠選擇指定rowspan
和colspan
。 這是軸域所佔的行數和列數。
6x1: colspan=1 (0,0) +-----------+ | ax1 | rowspan=1 (1,0) +-----------+ | | | ax2 | rowspan=4 | | | | (5,0) +-----------+ | ax3 | rowspan=1 +-----------+
結果爲:
顯然,咱們在這裏有一些重疊的問題,咱們能夠調整子圖來處理它。
再次,嘗試構思各類配置的子圖,使用subplot2grid
製做出來,直到你感到滿意!
咱們將繼續使用subplot2grid
,將它應用到咱們已經逐步創建的代碼中,咱們將在下一個教程中繼續。
在這個 Matplotlib 教程中,咱們將處理咱們之前教程的代碼,並實現上一個教程中的子圖配置。 咱們的起始代碼是這樣:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 17 def bytespdate2num(fmt, encoding='utf-8'): 18 strconverter = mdates.strpdate2num(fmt) 19 def bytesconverter(b): 20 s = b.decode(encoding) 21 return strconverter(s) 22 return bytesconverter 23 24 25 def graph_data(stock): 26 27 fig = plt.figure() 28 ax1 = plt.subplot2grid((1,1), (0,0)) 29 30 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 31 source_code = urllib.request.urlopen(stock_price_url).read().decode() 32 stock_data = [] 33 split_source = source_code.split('\n') 34 for line in split_source: 35 split_line = line.split(',') 36 if len(split_line) == 6: 37 if 'values' not in line and 'labels' not in line: 38 stock_data.append(line) 39 40 41 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 42 delimiter=',', 43 unpack=True, 44 converters={0: bytespdate2num('%Y%m%d')}) 45 46 x = 0 47 y = len(date) 48 ohlc = [] 49 50 while x < y: 51 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 52 ohlc.append(append_me) 53 x+=1 54 55 56 candlestick_ohlc(ax1, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 57 58 for label in ax1.xaxis.get_ticklabels(): 59 label.set_rotation(45) 60 61 ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 62 ax1.xaxis.set_major_locator(mticker.MaxNLocator(10)) 63 ax1.grid(True) 64 65 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 66 67 ax1.annotate(str(closep[-1]), (date[-1], closep[-1]), 68 xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) 69 70 71 ## # Annotation example with arrow 72 ## ax1.annotate('Bad News!',(date[11],highp[11]), 73 ## xytext=(0.8, 0.9), textcoords='axes fraction', 74 ## arrowprops = dict(facecolor='grey',color='grey')) 75 ## 76 ## 77 ## # Font dict example 78 ## font_dict = {'family':'serif', 79 ## 'color':'darkred', 80 ## 'size':15} 81 ## # Hard coded text 82 ## ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict) 83 84 plt.xlabel('Date') 85 plt.ylabel('Price') 86 plt.title(stock) 87 #plt.legend() 88 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) 89 plt.show() 90 91 92 graph_data('EBAY')
一個主要的改動是修改軸域的定義:
ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) plt.xlabel('Date') plt.ylabel('Price') ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1)
如今,ax2
是咱們實際上在繪製的股票價格數據。 頂部和底部圖表將做爲指標信息。
在咱們繪製數據的代碼中,咱們須要將ax1
更改成ax2
:
candlestick_ohlc(ax2, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') for label in ax2.xaxis.get_ticklabels(): label.set_rotation(45) ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax2.xaxis.set_major_locator(mticker.MaxNLocator(10)) ax2.grid(True) bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+4, closep[-1]), bbox=bbox_props)
更改以後,代碼爲:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 17 def bytespdate2num(fmt, encoding='utf-8'): 18 strconverter = mdates.strpdate2num(fmt) 19 def bytesconverter(b): 20 s = b.decode(encoding) 21 return strconverter(s) 22 return bytesconverter 23 24 25 def graph_data(stock): 26 27 fig = plt.figure() 28 ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) 29 plt.title(stock) 30 ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) 31 plt.xlabel('Date') 32 plt.ylabel('Price') 33 ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1) 34 35 36 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1m/csv' 37 source_code = urllib.request.urlopen(stock_price_url).read().decode() 38 stock_data = [] 39 split_source = source_code.split('\n') 40 for line in split_source: 41 split_line = line.split(',') 42 if len(split_line) == 6: 43 if 'values' not in line and 'labels' not in line: 44 stock_data.append(line) 45 46 47 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 48 delimiter=',', 49 unpack=True, 50 converters={0: bytespdate2num('%Y%m%d')}) 51 52 x = 0 53 y = len(date) 54 ohlc = [] 55 56 while x < y: 57 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 58 ohlc.append(append_me) 59 x+=1 60 61 62 candlestick_ohlc(ax2, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 63 64 for label in ax2.xaxis.get_ticklabels(): 65 label.set_rotation(45) 66 67 ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 68 ax2.xaxis.set_major_locator(mticker.MaxNLocator(10)) 69 ax2.grid(True) 70 71 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 72 73 ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), 74 xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) 75 76 77 ## # Annotation example with arrow 78 ## ax1.annotate('Bad News!',(date[11],highp[11]), 79 ## xytext=(0.8, 0.9), textcoords='axes fraction', 80 ## arrowprops = dict(facecolor='grey',color='grey')) 81 ## 82 ## 83 ## # Font dict example 84 ## font_dict = {'family':'serif', 85 ## 'color':'darkred', 86 ## 'size':15} 87 ## # Hard coded text 88 ## ax1.text(date[10], closep[1],'Text Example', fontdict=font_dict) 89 90 91 # 92 #plt.legend() 93 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) 94 plt.show() 95 96 97 graph_data('EBAY')
結果爲:
在這篇 Matplotlib 教程中,咱們介紹了添加一些簡單的函數來計算數據,以便咱們填充咱們的軸域。 一個是簡單的移動均值,另外一個是簡單的價格 HML 計算。
這些新函數是:
def moving_average(values, window): weights = np.repeat(1.0, window)/window smas = np.convolve(values, weights, 'valid') return smas def high_minus_low(highs, lows): return highs-lows
你不須要太過專一於理解移動均值的工做原理,咱們只是對樣本數據來計算它,以即可以學習更多自定義 Matplotlib 的東西。
咱們還想在腳本頂部爲移動均值定義一些值:
MA1 = 10 MA2 = 30
下面,在咱們的graph_data
函數中:
ma1 = moving_average(closep,MA1) ma2 = moving_average(closep,MA2) start = len(date[MA2-1:]) h_l = list(map(high_minus_low, highp, lowp))
在這裏,咱們計算兩個移動均值和 HML。
咱們還定義了一個『起始』點。 咱們這樣作是由於咱們但願咱們的數據排成一行。 例如,20 天的移動均值須要 20 個數據點。 這意味着咱們不能在第 5 天真正計算 20 天的移動均值。 所以,當咱們計算移動均值時,咱們會失去一些數據。 爲了處理這種數據的減法,咱們使用起始變量來計算應該有多少數據。 這裏,咱們能夠安全地使用[-start:]
繪製移動均值,而且若是咱們但願的話,對全部繪圖進行上述步驟來排列數據。
接下來,咱們能夠在ax1
上繪製 HML,經過這樣:
ax1.plot_date(date,h_l,'-')
最後咱們能夠經過這樣向ax3
添加移動均值:
ax3.plot(date[-start:], ma1[-start:]) ax3.plot(date[-start:], ma2[-start:])
咱們的完整代碼,包括增長咱們所用的時間範圍:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 MA1 = 10 17 MA2 = 30 18 19 def moving_average(values, window): 20 weights = np.repeat(1.0, window)/window 21 smas = np.convolve(values, weights, 'valid') 22 return smas 23 24 def high_minus_low(highs, lows): 25 return highs-lows 26 27 28 def bytespdate2num(fmt, encoding='utf-8'): 29 strconverter = mdates.strpdate2num(fmt) 30 def bytesconverter(b): 31 s = b.decode(encoding) 32 return strconverter(s) 33 return bytesconverter 34 35 36 def graph_data(stock): 37 38 fig = plt.figure() 39 ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) 40 plt.title(stock) 41 ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) 42 plt.xlabel('Date') 43 plt.ylabel('Price') 44 ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1) 45 46 47 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv' 48 source_code = urllib.request.urlopen(stock_price_url).read().decode() 49 stock_data = [] 50 split_source = source_code.split('\n') 51 for line in split_source: 52 split_line = line.split(',') 53 if len(split_line) == 6: 54 if 'values' not in line and 'labels' not in line: 55 stock_data.append(line) 56 57 58 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 59 delimiter=',', 60 unpack=True, 61 converters={0: bytespdate2num('%Y%m%d')}) 62 63 x = 0 64 y = len(date) 65 ohlc = [] 66 67 while x < y: 68 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 69 ohlc.append(append_me) 70 x+=1 71 72 ma1 = moving_average(closep,MA1) 73 ma2 = moving_average(closep,MA2) 74 start = len(date[MA2-1:]) 75 76 h_l = list(map(high_minus_low, highp, lowp)) 77 78 ax1.plot_date(date,h_l,'-') 79 80 81 candlestick_ohlc(ax2, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 82 83 for label in ax2.xaxis.get_ticklabels(): 84 label.set_rotation(45) 85 86 ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 87 ax2.xaxis.set_major_locator(mticker.MaxNLocator(10)) 88 ax2.grid(True) 89 90 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 91 92 ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), 93 xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) 94 95 96 ## # Annotation example with arrow 97 ## ax2.annotate('Bad News!',(date[11],highp[11]), 98 ## xytext=(0.8, 0.9), textcoords='axes fraction', 99 ## arrowprops = dict(facecolor='grey',color='grey')) 100 ## 101 ## 102 ## # Font dict example 103 ## font_dict = {'family':'serif', 104 ## 'color':'darkred', 105 ## 'size':15} 106 ## # Hard coded text 107 ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) 108 109 110 111 ax3.plot(date[-start:], ma1[-start:]) 112 ax3.plot(date[-start:], ma2[-start:]) 113 114 115 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) 116 plt.show() 117 118 119 graph_data('EBAY')
代碼效果如圖:
歡迎閱讀另外一個 Matplotlib 教程! 在本教程中,咱們將清除圖表,而後再作一些自定義。
咱們當前的代碼是:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 MA1 = 10 17 MA2 = 30 18 19 def moving_average(values, window): 20 weights = np.repeat(1.0, window)/window 21 smas = np.convolve(values, weights, 'valid') 22 return smas 23 24 def high_minus_low(highs, lows): 25 return highs-lows 26 27 28 def bytespdate2num(fmt, encoding='utf-8'): 29 strconverter = mdates.strpdate2num(fmt) 30 def bytesconverter(b): 31 s = b.decode(encoding) 32 return strconverter(s) 33 return bytesconverter 34 35 36 def graph_data(stock): 37 38 fig = plt.figure() 39 ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) 40 plt.title(stock) 41 ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) 42 plt.xlabel('Date') 43 plt.ylabel('Price') 44 ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1) 45 46 47 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv' 48 source_code = urllib.request.urlopen(stock_price_url).read().decode() 49 stock_data = [] 50 split_source = source_code.split('\n') 51 for line in split_source: 52 split_line = line.split(',') 53 if len(split_line) == 6: 54 if 'values' not in line and 'labels' not in line: 55 stock_data.append(line) 56 57 58 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 59 delimiter=',', 60 unpack=True, 61 converters={0: bytespdate2num('%Y%m%d')}) 62 63 x = 0 64 y = len(date) 65 ohlc = [] 66 67 while x < y: 68 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 69 ohlc.append(append_me) 70 x+=1 71 72 ma1 = moving_average(closep,MA1) 73 ma2 = moving_average(closep,MA2) 74 start = len(date[MA2-1:]) 75 76 h_l = list(map(high_minus_low, highp, lowp)) 77 78 ax1.plot_date(date,h_l,'-') 79 80 81 candlestick_ohlc(ax2, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') 82 83 for label in ax2.xaxis.get_ticklabels(): 84 label.set_rotation(45) 85 86 ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 87 ax2.xaxis.set_major_locator(mticker.MaxNLocator(10)) 88 ax2.grid(True) 89 90 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 91 92 ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), 93 xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) 94 95 96 ## # Annotation example with arrow 97 ## ax2.annotate('Bad News!',(date[11],highp[11]), 98 ## xytext=(0.8, 0.9), textcoords='axes fraction', 99 ## arrowprops = dict(facecolor='grey',color='grey')) 100 ## 101 ## 102 ## # Font dict example 103 ## font_dict = {'family':'serif', 104 ## 'color':'darkred', 105 ## 'size':15} 106 ## # Hard coded text 107 ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) 108 109 110 111 ax3.plot(date[-start:], ma1[-start:]) 112 ax3.plot(date[-start:], ma2[-start:]) 113 114 115 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) 116 plt.show() 117 118 119 graph_data('EBAY')
如今我認爲向咱們的移動均值添加自定義填充是一個很好的主意。 移動均值一般用於說明價格趨勢。 這個想法是,你能夠計算一個快速和一個慢速的移動均值。 通常來講,移動均值用於使價格變得『平滑』。 他們老是『滯後』於價格,可是咱們的想法是計算不一樣的速度。 移動均值越大就越『慢』。 因此這個想法是,若是『較快』的移動均值超過『較慢』的均值,那麼價格就會上升,這是一件好事。 若是較快的 MA 從較慢的 MA 下方穿過,則這是降低趨勢而且一般被視爲壞事。 個人想法是在快速和慢速 MA 之間填充,『上升』趨勢爲綠色,而後降低趨勢爲紅色。 方法以下:
ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] < ma2[-start:]), facecolor='r', edgecolor='r', alpha=0.5) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] > ma2[-start:]), facecolor='g', edgecolor='g', alpha=0.5)
下面,咱們會碰到一些咱們可解決的問題:
ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) for label in ax3.xaxis.get_ticklabels(): label.set_rotation(45) plt.setp(ax1.get_xticklabels(), visible=False) plt.setp(ax2.get_xticklabels(), visible=False)
這裏,咱們剪切和粘貼ax2
日期格式,而後咱們將x
刻度標籤設置爲false
,去掉它們!
咱們還能夠經過在軸域定義中執行如下操做,爲每一個軸域提供自定義標籤:
fig = plt.figure() ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) plt.xlabel('Date') plt.ylabel('Price') ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1)
接下來,咱們能夠看到,咱們y
刻度有許多數字,常常互相覆蓋。 咱們也看到軸之間互相重疊。 咱們能夠這樣:
ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=5, prune='lower'))
因此,這裏發生的是,咱們經過首先將nbins
設置爲 5 來修改咱們的y
軸對象。這意味着咱們顯示的標籤最多爲 5 個。而後咱們還能夠『修剪』標籤,所以,在咱們這裏, 咱們修剪底部標籤,這會使它消失,因此如今不會有任何文本重疊。 咱們仍然可能打算修剪ax2
的頂部標籤,但這裏是咱們目前爲止的源代碼:
當前的源碼:
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__) MA1 = 10 MA2 = 30 def moving_average(values, window): weights = np.repeat(1.0, window)/window smas = np.convolve(values, weights, 'valid') return smas def high_minus_low(highs, lows): return highs-lows 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((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) plt.ylabel('H-L') ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1) plt.ylabel('Price') ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1) plt.ylabel('MAvgs') stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/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 ma1 = moving_average(closep,MA1) ma2 = moving_average(closep,MA2) start = len(date[MA2-1:]) h_l = list(map(high_minus_low, highp, lowp)) ax1.plot_date(date,h_l,'-') ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=5, prune='lower')) candlestick_ohlc(ax2, ohlc, width=0.4, colorup='#77d879', colordown='#db3f3f') ax2.grid(True) bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) ## # Annotation example with arrow ## ax2.annotate('Bad News!',(date[11],highp[11]), ## xytext=(0.8, 0.9), textcoords='axes fraction', ## arrowprops = dict(facecolor='grey',color='grey')) ## ## ## # Font dict example ## font_dict = {'family':'serif', ## 'color':'darkred', ## 'size':15} ## # Hard coded text ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) ax3.plot(date[-start:], ma1[-start:], linewidth=1) ax3.plot(date[-start:], ma2[-start:], linewidth=1) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] < ma2[-start:]), facecolor='r', edgecolor='r', alpha=0.5) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] > ma2[-start:]), facecolor='g', edgecolor='g', alpha=0.5) ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) for label in ax3.xaxis.get_ticklabels(): label.set_rotation(45) plt.setp(ax1.get_xticklabels(), visible=False) plt.setp(ax2.get_xticklabels(), visible=False) plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) plt.show() graph_data('EBAY')
看起來好了一些,可是仍然有一些東西須要清除。
在這個 Matplotlib 數據可視化教程中,咱們將討論sharex
選項,它容許咱們在圖表之間共享x
軸。將sharex
看作『複製 x』也許更好。
在咱們開始以前,首先咱們要作些修剪並在另外一個軸上設置最大刻度數,以下所示:
ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper'))
以及
ax3.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='upper'))
如今,讓咱們共享全部軸域之間的x
軸。 爲此,咱們須要將其添加到軸域定義中:
fig = plt.figure() ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) plt.ylabel('H-L') ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1, sharex=ax1) plt.ylabel('Price') ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1, sharex=ax1) plt.ylabel('MAvgs')
上面,對於ax2
和ax3
,咱們添加一個新的參數,稱爲sharex
,而後咱們說,咱們要與ax1
共享x
軸。
使用這種方式,咱們能夠加載圖表,而後咱們能夠放大到一個特定的點,結果將是這樣:
因此這意味着全部軸域沿着它們的x
軸一塊兒移動。 這很酷吧!
接下來,讓咱們將[-start:]
應用到全部數據,因此全部軸域都起始於相同地方。 咱們最終的代碼爲:
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__) MA1 = 10 MA2 = 30 def moving_average(values, window): weights = np.repeat(1.0, window)/window smas = np.convolve(values, weights, 'valid') return smas def high_minus_low(highs, lows): return highs-lows 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((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) plt.ylabel('H-L') ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1, sharex=ax1) plt.ylabel('Price') ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1, sharex=ax1) plt.ylabel('MAvgs') stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/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 ma1 = moving_average(closep,MA1) ma2 = moving_average(closep,MA2) start = len(date[MA2-1:]) h_l = list(map(high_minus_low, highp, lowp)) ax1.plot_date(date[-start:],h_l[-start:],'-') ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='lower')) candlestick_ohlc(ax2, ohlc[-start:], width=0.4, colorup='#77d879', colordown='#db3f3f') ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper')) ax2.grid(True) bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) ## # Annotation example with arrow ## ax2.annotate('Bad News!',(date[11],highp[11]), ## xytext=(0.8, 0.9), textcoords='axes fraction', ## arrowprops = dict(facecolor='grey',color='grey')) ## ## ## # Font dict example ## font_dict = {'family':'serif', ## 'color':'darkred', ## 'size':15} ## # Hard coded text ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) ax3.plot(date[-start:], ma1[-start:], linewidth=1) ax3.plot(date[-start:], ma2[-start:], linewidth=1) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] < ma2[-start:]), facecolor='r', edgecolor='r', alpha=0.5) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] > ma2[-start:]), facecolor='g', edgecolor='g', alpha=0.5) ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) ax3.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='upper')) for label in ax3.xaxis.get_ticklabels(): label.set_rotation(45) plt.setp(ax1.get_xticklabels(), visible=False) plt.setp(ax2.get_xticklabels(), visible=False) plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) plt.show() graph_data('EBAY')
下面咱們會討論如何建立多個y
軸。
在這篇 Matplotlib 教程中,咱們將介紹如何在同一子圖上使用多個 Y 軸。 在咱們的例子中,咱們有興趣在同一個圖表及同一個子圖上繪製股票價格和交易量。
爲此,首先咱們須要定義一個新的軸域,可是這個軸域是ax2
僅帶有x
軸的『雙生子』。
這足以建立軸域了。咱們叫它ax2v
,由於這個軸域是ax2
加交易量。
如今,咱們在軸域上定義繪圖,咱們將添加:
ax2v.fill_between(date[-start:],0, volume[-start:], facecolor='#0079a3', alpha=0.4)
咱們在 0 和當前交易量之間填充,給予它藍色的前景色,而後給予它一個透明度。 咱們想要應用幽冥毒,以防交易量最終覆蓋其它東西,因此咱們仍然能夠看到這兩個元素。
因此,到如今爲止,咱們的代碼爲:
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__) MA1 = 10 MA2 = 30 def moving_average(values, window): weights = np.repeat(1.0, window)/window smas = np.convolve(values, weights, 'valid') return smas def high_minus_low(highs, lows): return highs-lows 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((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) plt.ylabel('H-L') ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1, sharex=ax1) plt.ylabel('Price') ax2v = ax2.twinx() ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1, sharex=ax1) plt.ylabel('MAvgs') stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/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 ma1 = moving_average(closep,MA1) ma2 = moving_average(closep,MA2) start = len(date[MA2-1:]) h_l = list(map(high_minus_low, highp, lowp)) ax1.plot_date(date[-start:],h_l[-start:],'-') ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='lower')) candlestick_ohlc(ax2, ohlc[-start:], width=0.4, colorup='#77d879', colordown='#db3f3f') ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper')) ax2.grid(True) bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) ## # Annotation example with arrow ## ax2.annotate('Bad News!',(date[11],highp[11]), ## xytext=(0.8, 0.9), textcoords='axes fraction', ## arrowprops = dict(facecolor='grey',color='grey')) ## ## ## # Font dict example ## font_dict = {'family':'serif', ## 'color':'darkred', ## 'size':15} ## # Hard coded text ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) ax2v.fill_between(date[-start:],0, volume[-start:], facecolor='#0079a3', alpha=0.4) ax3.plot(date[-start:], ma1[-start:], linewidth=1) ax3.plot(date[-start:], ma2[-start:], linewidth=1) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] < ma2[-start:]), facecolor='r', edgecolor='r', alpha=0.5) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] > ma2[-start:]), facecolor='g', edgecolor='g', alpha=0.5) ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) ax3.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='upper')) for label in ax3.xaxis.get_ticklabels(): label.set_rotation(45) plt.setp(ax1.get_xticklabels(), visible=False) plt.setp(ax2.get_xticklabels(), visible=False) plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) plt.show() graph_data('GOOG')
會生成:
太棒了,到目前爲止還不錯。 接下來,咱們可能要刪除新y
軸上的標籤,而後咱們也可能不想讓交易量佔用太多空間。 沒問題:
首先:
ax2v.axes.yaxis.set_ticklabels([])
上面將y
刻度標籤設置爲一個空列表,因此不會有任何標籤了。
譯者注:因此將標籤刪除以後,添加新軸的意義是什麼?直接在原軸域上繪圖就能夠了。
接下來,咱們可能要將網格設置爲false
,使軸域上不會有雙網格:
ax2v.grid(False)
最後,爲了處理交易量佔用不少空間,咱們能夠作如下操做:
ax2v.set_ylim(0, 3*volume.max())
因此這設置y
軸顯示範圍從 0 到交易量的最大值的 3 倍。 這意味着,在最高點,交易量最多可佔據圖形的33%。 因此,增長volume.max
的倍數越多,空間就越小/越少。
如今,咱們的圖表爲:
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__) MA1 = 10 MA2 = 30 def moving_average(values, window): weights = np.repeat(1.0, window)/window smas = np.convolve(values, weights, 'valid') return smas def high_minus_low(highs, lows): return highs-lows 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((6,1), (0,0), rowspan=1, colspan=1) plt.title(stock) plt.ylabel('H-L') ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1, sharex=ax1) plt.ylabel('Price') ax2v = ax2.twinx() ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1, sharex=ax1) plt.ylabel('MAvgs') stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/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 ma1 = moving_average(closep,MA1) ma2 = moving_average(closep,MA2) start = len(date[MA2-1:]) h_l = list(map(high_minus_low, highp, lowp)) ax1.plot_date(date[-start:],h_l[-start:],'-') ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='lower')) candlestick_ohlc(ax2, ohlc[-start:], width=0.4, colorup='#77d879', colordown='#db3f3f') ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper')) ax2.grid(True) bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), xytext = (date[-1]+5, closep[-1]), bbox=bbox_props) ## # Annotation example with arrow ## ax2.annotate('Bad News!',(date[11],highp[11]), ## xytext=(0.8, 0.9), textcoords='axes fraction', ## arrowprops = dict(facecolor='grey',color='grey')) ## ## ## # Font dict example ## font_dict = {'family':'serif', ## 'color':'darkred', ## 'size':15} ## # Hard coded text ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) ax2v.fill_between(date[-start:],0, volume[-start:], facecolor='#0079a3', alpha=0.4) ax2v.axes.yaxis.set_ticklabels([]) ax2v.grid(False) ax2v.set_ylim(0, 3*volume.max()) ax3.plot(date[-start:], ma1[-start:], linewidth=1) ax3.plot(date[-start:], ma2[-start:], linewidth=1) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] < ma2[-start:]), facecolor='r', edgecolor='r', alpha=0.5) ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], where=(ma1[-start:] > ma2[-start:]), facecolor='g', edgecolor='g', alpha=0.5) ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) ax3.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='upper')) for label in ax3.xaxis.get_ticklabels(): label.set_rotation(45) plt.setp(ax1.get_xticklabels(), visible=False) plt.setp(ax2.get_xticklabels(), visible=False) plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) plt.show() graph_data('GOOG')
到這裏,咱們差很少完成了。 這裏惟一的缺陷是一個好的圖例。 一些線條是顯而易見的,但人們可能會好奇移動均值的參數是什麼,咱們這裏是 10 和 30。 添加自定義圖例是下一個教程中涉及的內容。
在這篇 Matplotlib 教程中,咱們將討論自定義圖例。 咱們已經介紹了添加圖例的基礎知識。
圖例的主要問題一般是圖例阻礙了數據的展現。 這裏有幾個選項。 一個選項是將圖例放在軸域外,可是咱們在這裏有多個子圖,這是很是困難的。 相反,咱們將使圖例稍微小一點,而後應用一個透明度。
首先,爲了建立一個圖例,咱們須要向咱們的數據添加咱們想要顯示在圖例上的標籤。
ax1.plot_date(date[-start:],h_l[-start:],'-', label='H-L') ... ax2v.plot([],[], color='#0079a3', alpha=0.4, label='Volume') ... ax3.plot(date[-start:], ma1[-start:], linewidth=1, label=(str(MA1)+'MA')) ax3.plot(date[-start:], ma2[-start:], linewidth=1, label=(str(MA2)+'MA'))
請注意,咱們經過建立空行爲交易量添加了標籤。 請記住,咱們不能對任何填充應用標籤,因此這就是咱們添加這個空行的緣由。
如今,咱們能夠在右下角添加圖例,經過在plt.show()
以前執行如下操做:
ax1.legend() ax2v.legend() ax3.legend()
會生成:
因此,咱們能夠看到,圖例仍是佔用了一些位置。 讓咱們更改位置,大小並添加透明度:
ax1.legend()
leg = ax1.legend(loc=9, ncol=2,prop={'size':11}) leg.get_frame().set_alpha(0.4) ax2v.legend() leg = ax2v.legend(loc=9, ncol=2,prop={'size':11}) leg.get_frame().set_alpha(0.4) ax3.legend() leg = ax3.legend(loc=9, ncol=2,prop={'size':11}) leg.get_frame().set_alpha(0.4)
1
全部的圖例位於位置 9(上中間)。 有不少地方可放置圖例,咱們能夠爲參數傳入不一樣的位置號碼,來看看它們都位於哪裏。 ncol
參數容許咱們指定圖例中的列數。 這裏只有一列,若是圖例中有 2 個項目,他們將堆疊在一列中。 最後,咱們將尺寸規定爲更小。 以後,咱們對整個圖例應用0.4
的透明度。
如今咱們的結果爲:
完整的代碼爲:
1 import matplotlib.pyplot as plt 2 import matplotlib.dates as mdates 3 import matplotlib.ticker as mticker 4 from matplotlib.finance import candlestick_ohlc 5 from matplotlib import style 6 7 import numpy as np 8 import urllib 9 import datetime as dt 10 11 style.use('fivethirtyeight') 12 print(plt.style.available) 13 14 print(plt.__file__) 15 16 MA1 = 10 17 MA2 = 30 18 19 def moving_average(values, window): 20 weights = np.repeat(1.0, window)/window 21 smas = np.convolve(values, weights, 'valid') 22 return smas 23 24 def high_minus_low(highs, lows): 25 return highs-lows 26 27 28 def bytespdate2num(fmt, encoding='utf-8'): 29 strconverter = mdates.strpdate2num(fmt) 30 def bytesconverter(b): 31 s = b.decode(encoding) 32 return strconverter(s) 33 return bytesconverter 34 35 36 def graph_data(stock): 37 38 fig = plt.figure(facecolor='#f0f0f0') 39 ax1 = plt.subplot2grid((6,1), (0,0), rowspan=1, colspan=1) 40 plt.title(stock) 41 plt.ylabel('H-L') 42 ax2 = plt.subplot2grid((6,1), (1,0), rowspan=4, colspan=1, sharex=ax1) 43 plt.ylabel('Price') 44 ax2v = ax2.twinx() 45 46 ax3 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1, sharex=ax1) 47 plt.ylabel('MAvgs') 48 49 50 stock_price_url = 'http://chartapi.finance.yahoo.com/instrument/1.0/'+stock+'/chartdata;type=quote;range=1y/csv' 51 source_code = urllib.request.urlopen(stock_price_url).read().decode() 52 stock_data = [] 53 split_source = source_code.split('\n') 54 for line in split_source: 55 split_line = line.split(',') 56 if len(split_line) == 6: 57 if 'values' not in line and 'labels' not in line: 58 stock_data.append(line) 59 60 61 date, closep, highp, lowp, openp, volume = np.loadtxt(stock_data, 62 delimiter=',', 63 unpack=True, 64 converters={0: bytespdate2num('%Y%m%d')}) 65 66 x = 0 67 y = len(date) 68 ohlc = [] 69 70 while x < y: 71 append_me = date[x], openp[x], highp[x], lowp[x], closep[x], volume[x] 72 ohlc.append(append_me) 73 x+=1 74 75 ma1 = moving_average(closep,MA1) 76 ma2 = moving_average(closep,MA2) 77 start = len(date[MA2-1:]) 78 79 h_l = list(map(high_minus_low, highp, lowp)) 80 81 82 ax1.plot_date(date[-start:],h_l[-start:],'-', label='H-L') 83 ax1.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='lower')) 84 85 86 candlestick_ohlc(ax2, ohlc[-start:], width=0.4, colorup='#77d879', colordown='#db3f3f') 87 88 89 90 ax2.yaxis.set_major_locator(mticker.MaxNLocator(nbins=7, prune='upper')) 91 ax2.grid(True) 92 93 bbox_props = dict(boxstyle='round',fc='w', ec='k',lw=1) 94 95 ax2.annotate(str(closep[-1]), (date[-1], closep[-1]), 96 xytext = (date[-1]+4, closep[-1]), bbox=bbox_props) 97 98 ## # Annotation example with arrow 99 ## ax2.annotate('Bad News!',(date[11],highp[11]), 100 ## xytext=(0.8, 0.9), textcoords='axes fraction', 101 ## arrowprops = dict(facecolor='grey',color='grey')) 102 ## 103 ## 104 ## # Font dict example 105 ## font_dict = {'family':'serif', 106 ## 'color':'darkred', 107 ## 'size':15} 108 ## # Hard coded text 109 ## ax2.text(date[10], closep[1],'Text Example', fontdict=font_dict) 110 111 ax2v.plot([],[], color='#0079a3', alpha=0.4, label='Volume') 112 ax2v.fill_between(date[-start:],0, volume[-start:], facecolor='#0079a3', alpha=0.4) 113 ax2v.axes.yaxis.set_ticklabels([]) 114 ax2v.grid(False) 115 ax2v.set_ylim(0, 3*volume.max()) 116 117 118 119 ax3.plot(date[-start:], ma1[-start:], linewidth=1, label=(str(MA1)+'MA')) 120 ax3.plot(date[-start:], ma2[-start:], linewidth=1, label=(str(MA2)+'MA')) 121 122 ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], 123 where=(ma1[-start:] < ma2[-start:]), 124 facecolor='r', edgecolor='r', alpha=0.5) 125 126 ax3.fill_between(date[-start:], ma2[-start:], ma1[-start:], 127 where=(ma1[-start:] > ma2[-start:]), 128 facecolor='g', edgecolor='g', alpha=0.5) 129 130 ax3.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 131 ax3.xaxis.set_major_locator(mticker.MaxNLocator(10)) 132 ax3.yaxis.set_major_locator(mticker.MaxNLocator(nbins=4, prune='upper')) 133 134 for label in ax3.xaxis.get_ticklabels(): 135 label.set_rotation(45) 136 137 138 139 plt.setp(ax1.get_xticklabels(), visible=False) 140 plt.setp(ax2.get_xticklabels(), visible=False) 141 plt.subplots_adjust(left=0.11, bottom=0.24, right=0.90, top=0.90, wspace=0.2, hspace=0) 142 143 ax1.legend() 144 leg = ax1.legend(loc=9, ncol=2,prop={'size':11}) 145 leg.get_frame().set_alpha(0.4) 146 147 ax2v.legend() 148 leg = ax2v.legend(loc=9, ncol=2,prop={'size':11}) 149 leg.get_frame().set_alpha(0.4) 150 151 ax3.legend() 152 leg = ax3.legend(loc=9, ncol=2,prop={'size':11}) 153 leg.get_frame().set_alpha(0.4) 154 155 plt.show() 156 fig.savefig('google.png', facecolor=fig.get_facecolor()) 157 158 159 graph_data('GOOG')
如今咱們能夠看到圖例,但也看到了圖例下的任何信息。 還要注意額外函數fig.savefig
。 這是自動保存圖形的圖像的方式。 咱們還能夠設置所保存的圖形的前景色,使背景不是白色的,如咱們的例子所示。
這就是目前爲止,我想要顯示的典型 Matplotlib 圖表。 接下來,咱們將涉及Basemap
,它是一個 Matplotlib 擴展,用於繪製地理位置,而後我打算講解 Matplotlib 中的 3D 圖形。
在這個 Matplotlib 教程中,咱們將涉及地理繪圖模塊Basemap
。 Basemap
是 Matplotlib 的擴展。
爲了使用Basemap
,咱們首先須要安裝它。 爲了得到Basemap
,你能夠從這裏獲取:http://matplotlib.org/basemap/users/download.html,或者你能夠訪問http://www.lfd.uci.edu/~gohlke/pythonlibs/。
若是你在安裝Basemap
時遇到問題,請查看pip
安裝教程。
一旦你安裝了Basemap
,你就能夠建立地圖了。 首先,讓咱們投影一個簡單的地圖。 爲此,咱們須要導入Basemap
,pyplot
,建立投影,至少繪製某種輪廓或數據,而後咱們能夠顯示圖形。
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt m = Basemap(projection='mill') m.drawcoastlines() plt.show()
上面的代碼結果以下:
這是使用 Miller 投影完成的,這只是許多Basemap
投影選項之一。
在這篇 Matplotlib 教程中,咱們繼續使用Basemap
地理繪圖擴展。 咱們將展現一些咱們可用的自定義選項。
首先,從上一個教程中獲取咱們的起始代碼:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt m = Basemap(projection='mill') m.drawcoastlines() plt.show()
咱們能夠從放大到特定區域來開始:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt m = Basemap(projection='mill', llcrnrlat = -40, llcrnrlon = -40, urcrnrlat = 50, urcrnrlon = 75) m.drawcoastlines() plt.show()
這裏的參數是:
llcrnrlat
- 左下角的緯度llcrnrlon
- 左下角的經度urcrnrlat
- 右上角的緯度urcrnrlon
- 右上角的經度此外,座標須要轉換,其中西經和南緯座標是負值,北緯和東經座標是正值。
使用這些座標,Basemap
會選擇它們之間的區域。
下面,咱們要使用一些東西,相似:
m.drawcountries(linewidth=2)
這會畫出國家,並使用線寬爲 2 的線條生成分界線。
另外一個選項是:
m.drawstates(color='b')
這會用藍色線條畫出州。
你也能夠執行:
m.drawcounties(color='darkred')
這會畫出國家。
因此,咱們的代碼是:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt m = Basemap(projection='mill', llcrnrlat = -90, llcrnrlon = -180, urcrnrlat = 90, urcrnrlon = 180) m.drawcoastlines() m.drawcountries(linewidth=2) m.drawstates(color='b') m.drawcounties(color='darkred') plt.title('Basemap Tutorial') plt.show()
很難說,但咱們定義了美國的區縣的線條。 咱們可使用放大鏡放大Basemap
圖形,就像其餘圖形那樣,會生成:
另外一個有用的選項是Basemap
調用中的『分辨率』選項。
m = Basemap(projection='mill', llcrnrlat = -90, llcrnrlon = -180, urcrnrlat = 90, urcrnrlon = 180, resolution='l')
分辨率的選項爲:
c
- 粗糙l
- 低h
- 高f
- 完整對於更高的分辨率,你應該放大到很大,不然這可能只是浪費。
另外一個選項是使用etopo()
繪製地形,如:
m.etopo()
使用drawcountries
方法繪製此圖形會生成:
最後,有一個藍色的大理石版本,你能夠調用:
m.bluemarble()
會生成:
目前爲止的代碼:
1 from mpl_toolkits.basemap import Basemap 2 import matplotlib.pyplot as plt 3 4 m = Basemap(projection='mill', 5 llcrnrlat = -90, 6 llcrnrlon = -180, 7 urcrnrlat = 90, 8 urcrnrlon = 180, 9 resolution='l') 10 11 m.drawcoastlines() 12 m.drawcountries(linewidth=2) 13 ##m.drawstates(color='b') 14 ##m.drawcounties(color='darkred') 15 #m.fillcontinents() 16 #m.etopo() 17 m.bluemarble() 18 19 plt.title('Basemap Tutorial') 20 plt.show() 21 ````
# 第二十八章 在 Basemap 中繪製座標 歡迎閱讀另外一個 Matplotlib Basemap 教程。 在本教程中,咱們將介紹如何繪製單個座標,以及如何在地理區域中鏈接這些座標。 首先,咱們將從一些基本的起始數據開始:
from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt m = Basemap(projection='mill', llcrnrlat = 25, llcrnrlon = -130, urcrnrlat = 50, urcrnrlon = -60, resolution='l') m.drawcoastlines() m.drawcountries(linewidth=2) m.drawstates(color='b')
接下來,咱們能夠繪製座標,從得到它們的實際座標開始。 記住,南緯和西經座標須要轉換爲負值。 例如,紐約市是北緯40.7127
西經74.0059
。 咱們能夠在咱們的程序中定義這些座標,如:
NYClat, NYClon = 40.7127, -74.0059
以後咱們將這些轉換爲要繪製的x
和y
座標。
xpt, ypt = m(NYClon, NYClat)
注意這裏,咱們如今已經將座標順序翻轉爲lon, lat
(緯度,經度)。 座標一般以lat, lon
順序給出。 然而,在圖形中,lat, long
轉換爲y, x
,咱們顯然不須要。 在某些時候,你必須翻轉它們。 不要忘記這部分!
最後,咱們能夠繪製以下的座標:
m.plot(xpt, ypt, 'c*', markersize=15)
這個圖表上有一個青色的星,大小爲 15。更多標記類型請參閱:Matplotlib 標記文檔。
接下來,讓咱們再畫一個位置,洛杉磯,加利福尼亞:
LAlat, LAlon = 34.05, -118.25 xpt, ypt = m(LAlon, LAlat) m.plot(xpt, ypt, 'g^', markersize=15)
此次咱們畫出一個綠色三角,執行代碼會生成:
若是咱們想鏈接這些圖塊怎麼辦?原來,咱們能夠像其它 Matplotlib 圖表那樣實現它。
首先,咱們將那些xpt
和ypt
座標保存到列表,相似這樣的東西:
1 xs = [] 2 ys = [] 3 4 NYClat, NYClon = 40.7127, -74.0059 5 xpt, ypt = m(NYClon, NYClat) 6 xs.append(xpt) 7 ys.append(ypt) 8 m.plot(xpt, ypt, 'c*', markersize=15) 9 10 LAlat, LAlon = 34.05, -118.25 11 xpt, ypt = m(LAlon, LAlat) 12 xs.append(xpt) 13 ys.append(ypt) 14 m.plot(xpt, ypt, 'g^', markersize=15) 15 16 m.plot(xs, ys, color='r', linewidth=3, label='Flight 98')
會生成:
太棒了。有時咱們須要以圓弧鏈接圖上的兩個座標。如何實現呢?
m.drawgreatcircle(NYClon, NYClat, LAlon, LAlat, color='c', linewidth=3, label='Arc')
咱們的完整代碼爲:
1 from mpl_toolkits.basemap import Basemap 2 import matplotlib.pyplot as plt 3 4 m = Basemap(projection='mill', 5 llcrnrlat = 25, 6 llcrnrlon = -130, 7 urcrnrlat = 50, 8 urcrnrlon = -60, 9 resolution='l') 10 11 m.drawcoastlines() 12 m.drawcountries(linewidth=2) 13 m.drawstates(color='b') 14 #m.drawcounties(color='darkred') 15 #m.fillcontinents() 16 #m.etopo() 17 #m.bluemarble() 18 19 xs = [] 20 ys = [] 21 22 NYClat, NYClon = 40.7127, -74.0059 23 xpt, ypt = m(NYClon, NYClat) 24 xs.append(xpt) 25 ys.append(ypt) 26 m.plot(xpt, ypt, 'c*', markersize=15) 27 28 LAlat, LAlon = 34.05, -118.25 29 xpt, ypt = m(LAlon, LAlat) 30 xs.append(xpt) 31 ys.append(ypt) 32 m.plot(xpt, ypt, 'g^', markersize=15) 33 34 m.plot(xs, ys, color='r', linewidth=3, label='Flight 98') 35 m.drawgreatcircle(NYClon, NYClat, LAlon, LAlat, color='c', linewidth=3, label='Arc') 36 37 38 plt.legend(loc=4) 39 plt.title('Basemap Tutorial') 40 plt.show()
結果爲:
這就是Basemap
的所有了,下一章關於 Matplotlib 的 3D 繪圖。
您好,歡迎閱讀 Matplotlib 教程中的 3D 繪圖。 Matplotlib 已經內置了三維圖形,因此咱們不須要再下載任何東西。 首先,咱們須要引入一些完整的模塊:
from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt
使用axes3d
是由於它須要不一樣種類的軸域,以便在三維中實際繪製一些東西。 下面:
fig = plt.figure() ax1 = fig.add_subplot(111, projection='3d')
在這裏,咱們像一般同樣定義圖形,而後咱們將ax1
定義爲一般的子圖,只是此次使用 3D 投影。 咱們須要這樣作,以便提醒 Matplotlib 咱們要提供三維數據。
如今讓咱們建立一些 3D 數據:
x = [1,2,3,4,5,6,7,8,9,10] y = [5,6,7,8,2,5,6,3,7,2] z = [1,2,6,3,2,7,3,3,7,2]
接下來,咱們繪製它。 首先,讓咱們展現一個簡單的線框示例:
ax1.plot_wireframe(x,y,z)
最後:
ax1.set_xlabel('x axis') ax1.set_ylabel('y axis') ax1.set_zlabel('z axis') plt.show()
咱們完整的代碼是:
1 from mpl_toolkits.mplot3d import axes3d 2 import matplotlib.pyplot as plt 3 from matplotlib import style 4 5 style.use('fivethirtyeight') 6 7 fig = plt.figure() 8 ax1 = fig.add_subplot(111, projection='3d') 9 10 x = [1,2,3,4,5,6,7,8,9,10] 11 y = [5,6,7,8,2,5,6,3,7,2] 12 z = [1,2,6,3,2,7,3,3,7,2] 13 14 ax1.plot_wireframe(x,y,z) 15 16 ax1.set_xlabel('x axis') 17 ax1.set_ylabel('y axis') 18 ax1.set_zlabel('z axis') 19 20 plt.show()
結果爲(包括所用的樣式):
這些 3D 圖形能夠進行交互。 首先,您可使用鼠標左鍵單擊並拖動來移動圖形。 您還可使用鼠標右鍵單擊並拖動來放大或縮小。
歡迎閱讀另外一個 3D Matplotlib 教程,會涉及如何繪製三維散點圖。
繪製 3D 散點圖很是相似於一般的散點圖以及 3D 線框圖。
一個簡單示例:
1 from mpl_toolkits.mplot3d import axes3d 2 import matplotlib.pyplot as plt 3 from matplotlib import style 4 5 style.use('ggplot') 6 7 fig = plt.figure() 8 ax1 = fig.add_subplot(111, projection='3d') 9 10 x = [1,2,3,4,5,6,7,8,9,10] 11 y = [5,6,7,8,2,5,6,3,7,2] 12 z = [1,2,6,3,2,7,3,3,7,2] 13 14 x2 = [-1,-2,-3,-4,-5,-6,-7,-8,-9,-10] 15 y2 = [-5,-6,-7,-8,-2,-5,-6,-3,-7,-2] 16 z2 = [1,2,6,3,2,7,3,3,7,2] 17 18 ax1.scatter(x, y, z, c='g', marker='o') 19 ax1.scatter(x2, y2, z2, c ='r', marker='o') 20 21 ax1.set_xlabel('x axis') 22 ax1.set_ylabel('y axis') 23 ax1.set_zlabel('z axis') 24 25 plt.show()
結果爲:
要記住你能夠修改這些繪圖的大小和標記,就像一般的散點圖那樣。
在這個 Matplotlib 教程中,咱們要介紹 3D 條形圖。 3D 條形圖是很是獨特的,由於它容許咱們繪製多於 3 個維度。 不,你不能超過第三個維度來繪製,但你能夠繪製多於 3 個維度。
對於條形圖,你須要擁有條形的起點,條形的高度和寬度。 但對於 3D 條形圖,你還有另外一個選項,就是條形的深度。 大多數狀況下,條形圖從軸上的條形平面開始,可是你也能夠經過打破此約束來添加另外一個維度。 然而,咱們會讓它很是簡單:
1 from mpl_toolkits.mplot3d import axes3d 2 import matplotlib.pyplot as plt 3 import numpy as np 4 from matplotlib import style 5 style.use('ggplot') 6 7 fig = plt.figure() 8 ax1 = fig.add_subplot(111, projection='3d') 9 10 x3 = [1,2,3,4,5,6,7,8,9,10] 11 y3 = [5,6,7,8,2,5,6,3,7,2] 12 z3 = np.zeros(10) 13 14 dx = np.ones(10) 15 dy = np.ones(10) 16 dz = [1,2,3,4,5,6,7,8,9,10] 17 18 ax1.bar3d(x3, y3, z3, dx, dy, dz) 19 20 21 ax1.set_xlabel('x axis') 22 ax1.set_ylabel('y axis') 23 ax1.set_zlabel('z axis') 24 25 plt.show()
注意這裏,咱們必須定義x
、y
和z
,而後是 3 個維度的寬度、高度和深度。 這會生成:
歡迎閱讀最後的 Matplotlib 教程。 在這裏咱們將整理整個系列,並顯示一個稍微更復雜的 3D 線框圖:
1 from mpl_toolkits.mplot3d import axes3d 2 import matplotlib.pyplot as plt 3 import numpy as np 4 from matplotlib import style 5 style.use('ggplot') 6 7 fig = plt.figure() 8 ax1 = fig.add_subplot(111, projection='3d') 9 10 x, y, z = axes3d.get_test_data() 11 12 print(axes3d.__file__) 13 ax1.plot_wireframe(x,y,z, rstride = 3, cstride = 3) 14 15 ax1.set_xlabel('x axis') 16 ax1.set_ylabel('y axis') 17 ax1.set_zlabel('z axis') 18 19 plt.show()
若是你從一開始就關注這個教程的話,那麼你已經學會了 Matplotlib 提供的大部份內容。 你可能不相信,但Matplotlib 仍然能夠作不少其餘的事情! 請繼續學習,你能夠隨時訪問 Matplotlib.org,並查看示例和圖庫頁面。
若是你發現本身大量使用 Matplotlib,請考慮捐助給 John Hunter Memorial 基金。
注:空間曲面的畫法
# 二次拋物面 z = x^2 + y^2 x = np.linspace(-10, 10, 101) y = x x, y = np.meshgrid(x, y) z = x ** 2 + y ** 2 ax = plot.subplot(111, projection='3d') ax.plot_wireframe(x, y, z) plot.show()# 半徑爲 1 的球 t = np.linspace(0, np.pi * 2, 100) s = np.linspace(0, np.pi, 100) t, s = np.meshgrid(t, s) x = np.cos(t) * np.sin(s) y = np.sin(t) * np.sin(s) z = np.cos(s) ax = plot.subplot(111, projection='3d') ax.plot_wireframe(x, y, z) plot.show()