matplotlib 可視化的基本原理

在平時(shí)使用matploglib的時(shí)候式塌,將問題解決方法书在、使用心得甘穿、基本概念等等腮恩,都零零散散做了一些總結(jié),但是一直沒有系統(tǒng)的進(jìn)行過整理扒磁。為了能夠更好的鞏固matplotlib的使用庆揪,將之前的總結(jié)進(jìn)行一次系統(tǒng)化的梳理。

為什么需要數(shù)據(jù)可視化妨托?

無論是工作缸榛,學(xué)習(xí),生活中都會(huì)遇到各種數(shù)據(jù):年度預(yù)算數(shù)據(jù)兰伤,項(xiàng)目人力成本數(shù)據(jù)内颗,實(shí)驗(yàn)記錄數(shù)據(jù),投資收益等等敦腔。當(dāng)直接面對(duì)各種數(shù)據(jù)的時(shí)候均澳,無法直觀的反映出各種數(shù)據(jù)間的關(guān)系,因此就需要借助各種圖表來對(duì)數(shù)據(jù)進(jìn)行可視化的展示。選擇合理的數(shù)據(jù)圖表找前,比用數(shù)據(jù)和文字描述更明了糟袁、更容易理解,將數(shù)據(jù)轉(zhuǎn)換成圖表的形式呈現(xiàn)躺盛,可以幫助我們更好地了解數(shù)據(jù)之間的關(guān)聯(lián)關(guān)系及變化趨勢(shì)项戴,對(duì)問題的研究可以做出合理的推斷和預(yù)測(cè)。
使用不同的圖表從不同的方面來闡述問題槽惫,從不同的角度表現(xiàn)相對(duì)的關(guān)系周叮、數(shù)據(jù)與數(shù)據(jù)之間的聯(lián)系,從而尋找問題更好的解決方法界斜。
如下圖左表格中x,y的數(shù)據(jù)仿耽,單純從數(shù)據(jù)中看無法直觀的看出x,y之間的關(guān)系各薇。但是從右圖可以很直觀的看出x项贺,y之間為正相關(guān)。

matplotlib簡(jiǎn)介

matplotlib使用numpy進(jìn)行數(shù)組運(yùn)算得糜,并調(diào)用一系列其他的Python庫來實(shí)現(xiàn)硬件交互敬扛。matplotlib的核心是一套由對(duì)象構(gòu)成的繪圖API。它利用通用的圖形用戶界面工具包朝抖,如Tkinter, wxPython, Qt或GTK+,向應(yīng)用程序嵌入式繪圖提供了應(yīng)用程序接口(API)谍珊。matplotlib是基于Python語言的開源項(xiàng)目治宣,旨在為Python提供一個(gè)數(shù)據(jù)繪圖包。matplotlib的對(duì)象體系嚴(yán)謹(jǐn)而豐富砌滞,為使用者提供了巨大的發(fā)揮空間侮邀。在熟悉了核心對(duì)象之后,可以輕易的定制圖像贝润。matplotlib的對(duì)象體系也是計(jì)算機(jī)圖形學(xué)的一個(gè)優(yōu)秀范例绊茧。
matplotlib最初由John D. Hunter撰寫,它擁有一個(gè)活躍的開發(fā)社區(qū)打掘,并且根據(jù)BSD樣式許可證分發(fā)华畏。 在John D. Hunter2012年去世前不久,Michael Droettboom被提名為matplotlib的主要開發(fā)者尊蚁。

可以通過官網(wǎng)和源碼可以更加深入的了解matplotlib亡笑。
官網(wǎng):https://matplotlib.org
源碼:https://github.com/matplotlib/matplotlib

matplotlib 可視化的結(jié)構(gòu)

使用matplotlib繪圖,主要掌握figure(畫布)横朋、axes(坐標(biāo)系)仑乌、axis(坐標(biāo)軸)之間的關(guān)系。在matplotlib中,整個(gè)圖像為一個(gè)Figure對(duì)象晰甚。在Figure對(duì)象中可以包含一個(gè)衙传,或者多個(gè)axes對(duì)象。每個(gè)Axes對(duì)象都是一個(gè)擁有自己坐標(biāo)系統(tǒng)的繪圖區(qū)域厕九。
如下圖所示粪牲,在同一個(gè)figure畫布中,存在四個(gè)坐標(biāo)系止剖,對(duì)應(yīng)的每個(gè)坐標(biāo)系都有各自的坐標(biāo)軸腺阳。


AxesAxisFig.png

舉個(gè)比較形象的例子,一個(gè)畫家需要?jiǎng)?chuàng)作一幅油畫穿香。首先需要在畫框上固定一張畫布上亭引,有了畫布就可以創(chuàng)作任意的作品了,這個(gè)過程就是matplotlib中初始化畫布(figure)皮获;其次焙蚓,需要規(guī)劃在這個(gè)畫布上的布局,是一整幅還是多個(gè)子圖構(gòu)成洒宝?如果是多了子圖就需要為不同的的板塊分配區(qū)域了购公,這個(gè)區(qū)域就對(duì)應(yīng)了matplotlib中為不同的子圖指定的坐標(biāo)系(axes)。對(duì)應(yīng)的畫布中可能會(huì)存在1個(gè)或者多個(gè)坐標(biāo)系雁歌;然后宏浩,在不同的子圖創(chuàng)作完成之后,需要對(duì)邊界進(jìn)行勾勒靠瞎,這個(gè)邊界就對(duì)應(yīng)了matplotlib中的坐標(biāo)軸(axis).

matplotlib的構(gòu)成

matplotlib官網(wǎng)上提供描述其結(jié)構(gòu)的一張圖比庄,為了更方便的了解其內(nèi)容將其中涉及到的內(nèi)容增加了中文的說明。通過這張可以大致了解到通過繪制一張圖所涵蓋的部分乏盐。通過運(yùn)行后面的


AnatomyOfMatplotlib.png

相關(guān)代碼

  • matplotlib圖的構(gòu)成(圖AnatomyOfMatplotlib):

由于matplotlib對(duì)于中文顯示的支持不太好佳窑,會(huì)導(dǎo)致中文顯示為亂碼。對(duì)于中文字符顯示的解決方案會(huì)在后面進(jìn)行說明

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter

#支持中文
matplotlib.rcParams['font.family'] = ['Heiti TC']

np.random.seed(19680801)

X = np.linspace(0.5, 3.5, 100)
Y1 = 3+np.cos(X)
Y2 = 1+np.cos(1+X/0.75)/2
Y3 = np.random.uniform(Y1, Y2, len(X))

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 1, 1, aspect=1)


def minor_tick(x, pos):
    if not x % 1.0:
        return ""
    return "%.2f" % x

#設(shè)置x軸主刻度的位置父能,主刻度標(biāo)簽設(shè)置為1的倍數(shù)
ax.xaxis.set_major_locator(MultipleLocator(1.000))
#設(shè)置x軸次刻度的位置神凑,將每一個(gè)主刻度的區(qū)間等分為4格,如對(duì)應(yīng)圖中第一個(gè)主刻度區(qū)間中0.25何吝,0.50溉委,0.75
ax.xaxis.set_minor_locator(AutoMinorLocator(4))

#設(shè)置y軸主刻度的位置,主刻度標(biāo)簽設(shè)置為1的倍數(shù)
ax.yaxis.set_major_locator(MultipleLocator(1.000))
#設(shè)置y軸次刻度的位置岔霸,將每一個(gè)主刻度的區(qū)間等分為4格
ax.yaxis.set_minor_locator(AutoMinorLocator(4))

#設(shè)置x軸副刻度的文本顯示格式
ax.xaxis.set_minor_formatter(FuncFormatter(minor_tick))

#設(shè)置x軸和y軸的顯示區(qū)間
ax.set_xlim(0, 4)
ax.set_ylim(0, 4)


#設(shè)置主刻度中刻度的長(zhǎng)寬屬性
ax.tick_params(which='major', width=1.0)
ax.tick_params(which='major', length=10)

#設(shè)置次刻度的文本大小薛躬,顏色
ax.tick_params(which='minor', width=1.0, labelsize=10)
ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')

#顯示網(wǎng)格設(shè)置
ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)

#按照y1,y2,y3來繪制
ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
ax.plot(X, Y3, linewidth=0,
        marker='o', markerfacecolor='w', markeredgecolor='k')

#設(shè)置圖的標(biāo)題
ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
#設(shè)置x軸lable
ax.set_xlabel("X axis label")
#設(shè)置y軸lable
ax.set_ylabel("Y axis label")

#設(shè)置圖例
ax.legend()


#通過patches和patheffects中的函數(shù)來繪制對(duì)應(yīng)圖中圓圈標(biāo)注的地方
def circle(x, y, radius=0.15):
    from matplotlib.patches import Circle
    from matplotlib.patheffects import withStroke
    circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
                    edgecolor='black', facecolor=(0, 0, 0, .0125),
                    path_effects=[withStroke(linewidth=5, foreground='w')])
    ax.add_artist(circle)

#設(shè)置文本顯示的屬性
def text(x, y, text):
    ax.text(x, y, text, backgroundcolor="white",
            ha='center', va='top', weight='bold', color='blue')


#對(duì)各個(gè)標(biāo)注點(diǎn)的顯示
# Minor tick
circle(0.50, -0.10)
text(0.50, -0.32, "次刻度標(biāo)簽(Minor tick label)")

# Major tick
circle(-0.03, 4.00)
text(0.03, 3.80, "主刻度(Major tick)")

# Minor tick
circle(0.00, 3.50)
text(0.00, 3.30, "次刻度(Minor tick)")

# Major tick label
circle(-0.15, 3.00)
text(-0.15, 2.80, "主刻度標(biāo)簽(Major tick label)")

# X Label
circle(1.80, -0.27)
text(1.80, -0.45, "x軸標(biāo)簽(X axis label)")

# Y Label
circle(-0.27, 1.80)
text(-0.27, 1.6, "y軸標(biāo)簽(Y axis label)")

# Title
circle(1.60, 4.13)
text(1.60, 3.93, "名稱(Title)")

# Blue plot
circle(1.75, 2.80)
text(1.75, 2.60, "線條(Line)\n(line plot)")

# Red plot
circle(1.20, 0.60)
text(1.20, 0.40, "線條(Line)\n(line plot)")

# Scatter plot
circle(3.20, 1.75)
text(3.20, 1.55, "節(jié)點(diǎn)樣式(Markers)\n(scatter plot)")

# Grid
circle(3.00, 3.00)
text(3.00, 2.80, "網(wǎng)格(Grid)")

# Legend
circle(3.70, 3.80)
text(3.70, 3.60, "圖例(Legend)")

# Axes
circle(0.5, 0.5)
text(0.5, 0.3, "坐標(biāo)系(Axes)")

# Figure
circle(-0.3, 0.65)
text(-0.3, 0.45, "畫布(Figure)")

color = 'blue'

#注解的顯示,圖中右下角spines
ax.annotate('坐標(biāo)軸(Spines)', xy=(4.0, 0.35), xytext=(3.3, 0.5),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

#文本的顯示
ax.text(4.0, -0.4, "參考自官網(wǎng)的簡(jiǎn)介(\nMade with http://matplotlib.org)",
        fontsize=10, ha="right", color='.5')


#fig.savefig('./img/AnatomyOfMatplotlib.png')
plt.show()
  • 多子圖顯示(圖AxesAxisFig):
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,6.0)

figure,ax=plt.subplots(2,2,figsize=(16,9))

ax[0][0].plot(x,np.sin(np.pi*x));
ax[0][0].set_title("正弦")
ax[0][0].set_xlabel("時(shí)間")
ax[0][0].set_ylabel("幅度")
ax[0][0].set_ylabel("幅度")

ax[0][1].plot(x,np.cos(np.pi*x));
ax[0][1].set_title("余弦")
ax[0][1].set_xlabel("時(shí)間")
ax[0][1].set_ylabel("幅度")

ax[1][0].plot(x,np.log((x+1)*10));
ax[1][0].set_title("指數(shù)")
ax[1][0].set_xlabel("時(shí)間")
ax[1][0].set_ylabel("距離")


ax[1][1].plot(x,x*4);
ax[1][1].set_title("投資")
ax[1][1].set_xlabel("資金")
ax[1][1].set_ylabel("收益")

figure.tight_layout(pad=1.5)
#figure.savefig('./img/Subplots.png')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呆细,一起剝皮案震驚了整個(gè)濱河市型宝,隨后出現(xiàn)的幾起案子八匠,更是在濱河造成了極大的恐慌,老刑警劉巖趴酣,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梨树,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡岖寞,警方通過查閱死者的電腦和手機(jī)抡四,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仗谆,“玉大人指巡,你說我怎么就攤上這事×タ澹” “怎么了藻雪?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)狸吞。 經(jīng)常有香客問我勉耀,道長(zhǎng),這世上最難降的妖魔是什么蹋偏? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任便斥,我火速辦了婚禮,結(jié)果婚禮上威始,老公的妹妹穿的比我還像新娘枢纠。我一直安慰自己,他們只是感情好字逗,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布京郑。 她就那樣靜靜地躺著,像睡著了一般葫掉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跟狱,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天俭厚,我揣著相機(jī)與錄音,去河邊找鬼驶臊。 笑死挪挤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的关翎。 我是一名探鬼主播扛门,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纵寝!你這毒婦竟也來了论寨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葬凳,沒想到半個(gè)月后绰垂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡火焰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年劲装,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昌简。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡占业,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纯赎,到底是詐尸還是另有隱情谦疾,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布址否,位于F島的核電站餐蔬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏佑附。R本人自食惡果不足惜樊诺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望音同。 院中可真熱鬧词爬,春花似錦、人聲如沸权均。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叽赊。三九已至恋沃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間必指,已是汗流浹背囊咏。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塔橡,地道東北人梅割。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像葛家,于是被迫代替她去往敵國(guó)和親户辞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361