欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python之Matplotlib文字與注釋的使用方法

 更新時間:2020年06月18日 11:35:42   作者:ywsydwsbn  
這篇文章主要介紹了Python之Matplotlib文字與注釋的使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

可視化對于大家來說確實(shí)是有關(guān)的,因?yàn)榇_實(shí)是直觀的,每一組大數(shù)據(jù)如果可以用可視化進(jìn)行展示的話可以讓大家豁然開朗。但在另外一些場景中,輔之以少量的文字提示(textual cue)和標(biāo)簽是必不可少的。雖然最基本的注釋(annotation)類型可能只是坐標(biāo)軸標(biāo)題與圖標(biāo)題,但注釋可遠(yuǎn)遠(yuǎn)不止這些。讓我們可視化一些數(shù)據(jù),看看如何通過添加注釋來更恰當(dāng)?shù)乇磉_(dá)信息。

首先導(dǎo)入畫圖需要用到的一些函數(shù):

import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd

1 案例:節(jié)假日對美國出生率的影響

數(shù)據(jù)可以在 https://github.com/jakevdp/data-CDCbirths 下載,數(shù)據(jù)類型如下:

用清洗方法處理數(shù)據(jù),然后畫出結(jié)果。

日均出生人數(shù)統(tǒng)計(jì)圖

births = pd.read_csv('births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]
fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax);
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]
fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax);
plt.show()

為日均出生人數(shù)統(tǒng)計(jì)圖添加注釋

在用這樣的圖表達(dá)觀點(diǎn)時,如果可以在圖中增加一些注釋,就更能吸引讀者的注意了??梢酝ㄟ^ plt.text / ax.text 命令手動添加注釋,它們可以在具體的 x / y 坐標(biāo)點(diǎn)上放上文字

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)
# 在圖上增加文字標(biāo)簽
style = dict(size=10, color='gray')
ax.text('2012-1-1', 3950, "New Year's Day", **style)
ax.text('2012-7-4', 4250, "Independence Day", ha='center', **style)
ax.text('2012-9-4', 4850, "Labor Day", ha='center', **style)
ax.text('2012-10-31', 4600, "Halloween", ha='right', **style)
ax.text('2012-11-25', 4450, "Thanksgiving", ha='center', **style)
ax.text('2012-12-25', 3850, "Christmas ", ha='right', **style)
# 設(shè)置坐標(biāo)軸標(biāo)題
ax.set(title='USA births by day of year (1969-1988)',
ylabel='average daily births')
# 設(shè)置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]
fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)
# 在圖上增加文字標(biāo)簽
style = dict(size=10, color='gray')
ax.text('2012-1-1', 3950, "New Year's Day", **style)
ax.text('2012-7-4', 4250, "Independence Day", ha='center', **style)
ax.text('2012-9-4', 4850, "Labor Day", ha='center', **style)
ax.text('2012-10-31', 4600, "Halloween", ha='right', **style)
ax.text('2012-11-25', 4450, "Thanksgiving", ha='center', **style)
ax.text('2012-12-25', 3850, "Christmas ", ha='right', **style)
# 設(shè)置坐標(biāo)軸標(biāo)題
ax.set(title='USA births by day of year (1969-1988)',
ylabel='average daily births')
# 設(shè)置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));
plt.show()

ax.text 方法需要一個 x 軸坐標(biāo)、一個 y 軸坐標(biāo)、一個字符串和一些可選參數(shù),比如文字的顏色、字號、風(fēng)格、對齊方式以及其他文字屬性。這里用了 ha='right'ha='center'ha 是水平對齊方式(horizonal alignment)的縮寫。關(guān)于配置參數(shù)的更多信息,請參考plt.text()mpl.text.Text() 的程序文檔。

2 坐標(biāo)變換與文字位置

前面的示例將文字放在了目標(biāo)數(shù)據(jù)的位置上。但有時候可能需要將文字放在與數(shù)據(jù)無關(guān)的位置上,比如坐標(biāo)軸或者圖形中。在 Matplotlib 中,我們通過調(diào)整坐標(biāo)變換(transform)來實(shí)現(xiàn)。

任何圖形顯示框架都需要一些變換坐標(biāo)系的機(jī)制。例如,當(dāng)一個位于 (x, y) = (1, 1) 位置的點(diǎn)需要以某種方式顯示在圖上特定的位置時,就需要用屏幕的像素來表示。用數(shù)學(xué)方法處理這種坐標(biāo)系變換很簡單,Matplotlib 有一組非常棒的工具可以實(shí)現(xiàn)類似功能(這些工具位于 matplotlib.transforms 子模塊中)。

雖然一般用戶并不需要關(guān)心這些變換的細(xì)節(jié),但是了解這些知識對在圖上放置文字大有幫助。一共有三種解決這類問題的預(yù)定義變換方式。

  • ax.transData 以數(shù)據(jù)為基準(zhǔn)的坐標(biāo)變換。
  • ax.transAxes 以坐標(biāo)軸為基準(zhǔn)的坐標(biāo)變換(以坐標(biāo)軸維度為單位)。
  • fig.transFigure 以圖形為基準(zhǔn)的坐標(biāo)變換(以圖形維度為單位)。

默認(rèn)情況下,上面的文字在各自的坐標(biāo)系中都是左對齊的。這三個字符串開頭的 . 字符基本就是對應(yīng)的坐標(biāo)位置。
transData 坐標(biāo)用 x 軸與 y 軸的標(biāo)簽作為數(shù)據(jù)坐標(biāo)。
transAxes 坐標(biāo)以坐標(biāo)軸(圖中白色矩形)左下角的位置為原點(diǎn),按坐標(biāo)軸尺寸的比例呈現(xiàn)坐標(biāo)。
transFigure 坐標(biāo)與之類似,不過是以圖形(圖中灰色矩形)左下角的位置為原點(diǎn),按圖形尺寸的比例呈現(xiàn)坐標(biāo)。

對比 Matplotlib 的三種坐標(biāo)系(1)

下面舉一個例子,用三種變換方式將文字畫在不同的位置:

fig, ax = plt.subplots(facecolor='lightgray')
ax.axis([0, 10, 0, 10])
# 雖然transform=ax.transData是默認(rèn)值,但還是設(shè)置一下
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.2, 0.2, ". Figure: (0.2, 0.2)", transform=fig.transFigure);
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]
fig, ax = plt.subplots(facecolor='lightgray')
ax.axis([0, 10, 0, 10])
# 雖然transform=ax.transData是默認(rèn)值,但還是設(shè)置一下
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.2, 0.2, ". Figure: (0.2, 0.2)", transform=fig.transFigure);
plt.show()

對比 Matplotlib 的三種坐標(biāo)系(2)

需要注意的是,假如你改變了坐標(biāo)軸上下限,那么只有 transData 坐標(biāo)會受影響,其他坐標(biāo)系都不變

ax.set_xlim(0, 2)
ax.set_ylim(-6, 6)
fig
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]
fig, ax = plt.subplots(facecolor='lightgray')
ax.axis([0, 10, 0, 10])
# 雖然transform=ax.transData是默認(rèn)值,但還是設(shè)置一下
ax.text(1, 5, ". Data: (1, 5)", transform=ax.transData)
ax.text(0.5, 0.1, ". Axes: (0.5, 0.1)", transform=ax.transAxes)
ax.text(0.2, 0.2, ". Figure: (0.2, 0.2)", transform=fig.transFigure);
ax.set_xlim(0, 2)
ax.set_ylim(-6, 6)
fig
plt.show()


如果你改變了坐標(biāo)軸上下限,那么就可以更清晰地看到剛剛所說的變化。

3 箭頭與注釋

除了刻度線和文字,簡單的箭頭也是一種有用的注釋標(biāo)簽。

在 Matplotlib 里面畫箭頭通常比你想象的要困難。雖然有一個 plt.arrow() 函數(shù)可以實(shí)現(xiàn)這個功能,但是我不推薦使用它,因?yàn)樗鼊?chuàng)建出的箭頭是 SVG 向量圖對象,會隨著圖形分辨率的變化而改變,最終的結(jié)果可能完全不是用戶想要的。我要推薦的是 plt.annotate()函數(shù)。這個函數(shù)既可以創(chuàng)建文字,也可以創(chuàng)建箭頭,而且它創(chuàng)建的箭頭能夠進(jìn)行非常靈活的配置。

圖形注釋

下面用 annotate 的一些配置選項(xiàng)來演示

fig, ax = plt.subplots()
x = np.linspace(0, 20, 1000)
ax.plot(x, np.cos(x))
ax.axis('equal')
ax.annotate('local maximum', xy=(6.28, 1), xytext=(10, 4),arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('local minimum', xy=(5 * np.pi, -1), xytext=(2, -6),arrowprops=dict(arrowstyle="->",
connectionstyle="angle3,angleA=0,angleB=-90"));
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]

fig, ax = plt.subplots()
x = np.linspace(0, 20, 1000)
ax.plot(x, np.cos(x))
ax.axis('equal')
ax.annotate('local maximum', xy=(6.28, 1), xytext=(10, 4),arrowprops=dict(facecolor='black', shrink=0.05))
ax.annotate('local minimum', xy=(5 * np.pi, -1), xytext=(2, -6),arrowprops=dict(arrowstyle="->",connectionstyle="angle3,angleA=0,angleB=-90"));

plt.show()


箭頭的風(fēng)格是通過 arrowprops 字典控制的,里面有許多可用的選項(xiàng)。由于這些選項(xiàng)在Matplotlib 的官方文檔中都有非常詳細(xì)的介紹,我就不再贅述,僅做一點(diǎn)兒功能演示。

帶注釋的日均出生人數(shù)

讓我們用前面的美國出生人數(shù)圖來演示一些箭頭注釋

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)
# 在圖上增加箭頭標(biāo)簽
ax.annotate("New Year's Day", xy=('2012-1-1', 4100), xycoords='data',xytext=(50, -30), textcoords='offset points',arrowprops=dict(arrowstyle="->",connectionstyle="arc3,rad=-0.2"))
ax.annotate("Independence Day", xy=('2012-7-4', 4250),xycoords='data',bbox=dict(boxstyle="round", fc="none", ec="gray"),xytext=(10, -40), textcoords='offset points', ha='center', arrowprops=dict(arrowstyle="->"))
ax.annotate('Labor Day', xy=('2012-9-4', 4850), xycoords='data', ha='center', xytext=(0, -20), textcoords='offset points')
ax.annotate('', xy=('2012-9-1', 4850), xytext=('2012-9-7', 4850), xycoords='data', textcoords='data', arrowprops={'arrowstyle': '|-|,widthA=0.2,widthB=0.2', })
ax.annotate('Halloween', xy=('2012-10-31', 4600), xycoords='data', xytext=(-80, -40), textcoords='offset points', arrowprops=dict(arrowstyle="fancy", fc="0.6", ec="none", connectionstyle="angle3,angleA=0,angleB=-90"))
ax.annotate('Thanksgiving', xy=('2012-11-25', 4500), xycoords='data', xytext=(-120, -60), textcoords='offset points', bbox=dict(boxstyle="round4,pad=.5", fc="0.9"), arrowprops=dict(arrowstyle="->", connectionstyle="angle,angleA=0,angleB=80,rad=20"))
ax.annotate('Christmas', xy=('2012-12-25', 3850), xycoords='data', xytext=(-30, 0), textcoords='offset points', size=13, ha='right', va="center", bbox=dict(boxstyle="round", alpha=0.1), arrowprops=dict(arrowstyle="wedge,tail_width=0.5", alpha=0.1));
# 設(shè)置坐標(biāo)軸標(biāo)題
ax.set(title='USA births by day of year (1969-1988)', ylabel='average daily births')
# 設(shè)置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));
ax.set_ylim(3600, 5400);
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.style.use('seaborn-whitegrid')
import numpy as np
import pandas as pd
births = pd.read_csv('C:\\Users\\Y\\Desktop\\data-CDCbirths-master\\births.csv')
quartiles = np.percentile(births['births'], [25, 50, 75])
mu, sig = quartiles[1], 0.74 * (quartiles[2] - quartiles[0])
births = births.query('(births > @mu - 5 * @sig) & (births < @mu + 5 * @sig)')
births['day'] = births['day'].astype(int)
births.index = pd.to_datetime(10000 * births.year + 100 * births.month + births.day, format='%Y%m%d')
births_by_date = births.pivot_table('births', [births.index.month, births.index.day])
births_by_date.index = [pd.datetime(2012, month, day) for (month, day) in births_by_date.index]

fig, ax = plt.subplots(figsize=(12, 4))
births_by_date.plot(ax=ax)
# 在圖上增加箭頭標(biāo)簽
ax.annotate("New Year's Day", xy=('2012-1-1', 4100), xycoords='data',
			xytext=(50, -30), textcoords='offset points',
			arrowprops=dict(arrowstyle="->",
			connectionstyle="arc3,rad=-0.2"))
ax.annotate("Independence Day", xy=('2012-7-4', 4250), 	xycoords='data',
			bbox=dict(boxstyle="round", fc="none", ec="gray"),
			xytext=(10, -40), textcoords='offset points', ha='center',
			arrowprops=dict(arrowstyle="->"))
ax.annotate('Labor Day', xy=('2012-9-4', 4850), xycoords='data', 		ha='center',
			xytext=(0, -20), textcoords='offset points')
			ax.annotate('', xy=('2012-9-1', 4850), xytext=('2012-9-7', 4850),
			xycoords='data', textcoords='data',
			arrowprops={'arrowstyle': '|-|,widthA=0.2,widthB=0.2', })
ax.annotate('Halloween', xy=('2012-10-31', 4600), xycoords='data',
			xytext=(-80, -40), textcoords='offset points',
			arrowprops=dict(arrowstyle="fancy",
			fc="0.6", ec="none",
			connectionstyle="angle3,angleA=0,angleB=-90"))
ax.annotate('Thanksgiving', xy=('2012-11-25', 4500), xycoords='data',
			xytext=(-120, -60), textcoords='offset points',
			bbox=dict(boxstyle="round4,pad=.5", fc="0.9"),
			arrowprops=dict(arrowstyle="->",
			connectionstyle="angle,angleA=0,angleB=80,rad=20"))
ax.annotate('Christmas', xy=('2012-12-25', 3850), xycoords='data',xytext=(-30, 0), textcoords='offset points',size=13, 		ha='right', va="center",bbox=dict(boxstyle="round", 		alpha=0.1),arrowprops=dict(arrowstyle="wedge,tail_width=0.5", 	alpha=0.1));
# 設(shè)置坐標(biāo)軸標(biāo)題
ax.set(title='USA births by day of year (1969-1988)',ylabel='average daily births')
# 設(shè)置x軸刻度值,讓月份居中顯示
ax.xaxis.set_major_locator(mpl.dates.MonthLocator())
ax.xaxis.set_minor_locator(mpl.dates.MonthLocator(bymonthday=15))
ax.xaxis.set_major_formatter(plt.NullFormatter())
ax.xaxis.set_minor_formatter(mpl.dates.DateFormatter('%h'));
ax.set_ylim(3600, 5400);

plt.show()


你可能已經(jīng)注意到了,箭頭和文本框的配置功能非常細(xì)致,這樣你就可以創(chuàng)建自己想要的箭頭風(fēng)格了。不過,功能太過細(xì)致往往也就意味著操作起來比較復(fù)雜,如果真要做一個產(chǎn)品級的圖形,可能得耗費(fèi)大量的時間。最后我想說一句,前面適用的混合風(fēng)格并不是數(shù)據(jù)可視化的最佳實(shí)踐,僅僅是為演示一些功能而已。

到此這篇關(guān)于Python之Matplotlib文字與注釋的使用方法的文章就介紹到這了,更多相關(guān)Matplotlib文字與注釋內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論