使用matplotlib畫圖自定義marker
matplotlib畫圖自定義marker
在matplotlib工具箱中可以畫marker的高級作圖函數(shù)一共有兩個(gè),分別為plot和scatter,可以畫出多種marker。
但如果需要繪制一些特殊的marker,則必須通過自的定義marker來實(shí)現(xiàn)。
一般有兩種方式可以實(shí)現(xiàn):
- 一是在繪圖中插入特殊marker的icon圖片
- 二是借助于matplotlib.path中的Path類,自定義marker的Path參數(shù)。
但無論何種方式,實(shí)現(xiàn)的marker都要具有一般marker的特點(diǎn)。
marker的特點(diǎn)
- 固定大小:marker的大小只依賴于markersize關(guān)鍵字定義的數(shù)值,不隨著繪制的圖形的放大或縮小而變化;
- 可改變方向: matplotlib默認(rèn)支持的某些marker可以通過傳入的參數(shù)調(diào)整marker的方向
基于marker的上述兩個(gè)特點(diǎn),因此不能簡單地通過plot繪制特殊marker的折線或者簡單地進(jìn)行圖片插入實(shí)現(xiàn)。
通過插入圖片實(shí)現(xiàn)自定義marker
from matplotlib import pyplot as pltimport numpy as np '圖片插入(普通)' N = 100 x = np.linspace(0, 10, N) y = np.sin(x) fig = plt.figure() ax = fig.add_subplot(111) ax.imshow(plt.imread('icon\\icon-test.png'), extent=(x[0],x[0]+1,y[0],y[0]+1)) ax.plot(x, y) plt.show()
如上圖所示,基本可以實(shí)現(xiàn)marker的插入,但大小會(huì)隨figure的大小變化,而且也不能改變方向。
進(jìn)一步完善代碼如下:
from matplotlib import pyplot as plt from matplotlib.offsetbox import OffsetImage, AnnotationBbox import numpy as np '圖片插入(大小不變)' N = 100 x = np.linspace(0, 10, N) y = np.sin(x) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, y) img = plt.imread('icon\\icon-test.png') im = OffsetImage(img, zoom=0.3) ab = AnnotationBbox(im, (x[0],y[0]), xycoords='data', frameon=False) ax.add_artist(ab) plt.show()
此時(shí)插入的marker不再隨figure大小的變化而變化,但還不能做到自定義旋轉(zhuǎn)角度,如果要實(shí)現(xiàn)該功能,則可以通過定義旋轉(zhuǎn)矩陣,將plt.imread讀取的圖片數(shù)據(jù)img進(jìn)行旋轉(zhuǎn)變換以實(shí)現(xiàn)對marker的角度旋轉(zhuǎn)。
但這種方法仍然不同靈活,不像真正的“marker”,而且效率也不高。
下面介紹如何通過Path實(shí)現(xiàn)自定義marker。
通過Path實(shí)現(xiàn)自定義marker
from matplotlib import pyplot as plt from matplotlib.path import Path import numpy as np '通過Path類自定義marker' #定義旋轉(zhuǎn)矩陣 def rot(verts, az): #順時(shí)針旋轉(zhuǎn) rad = az / 180 * np.pi verts = np.array(verts) rotMat = np.array([[np.cos(rad), -np.sin(rad)], [np.sin(rad), np.cos(rad)]]) transVerts = verts.dot(rotMat) return transVerts iconMat = np.array([[-1.414, 1.414], [0, 0], [2.828, 2.828], [0, 0], [-1.414, 1.414]]) class CustomMarker(Path): def __init__(self, icon, az): if icon == "icon": verts = iconMat vertices = rot(verts, az) super().__init__(vertices) N = 30 x = np.linspace(0, 10, N) y = np.sin(x) fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(x, y, marker=IconMarker("icon", 20), c="red", s=1000) plt.show()
實(shí)現(xiàn)效果如上圖所示,就像普通的marker一樣,大小固定,不隨figure大小變化,而且可以調(diào)節(jié)方向(旋轉(zhuǎn))。
實(shí)現(xiàn)的主要原理是
matplotlib中的plot和scatter繪圖函數(shù)中的marker關(guān)鍵字傳遞的值會(huì)被matplotlib.markers中的MarkerStyle類處理,而MarkerStyle類中的set_marker是可以處理path對象的。
因此,先生成自定義的marker的Path對象的路徑點(diǎn)參數(shù),然后定義旋轉(zhuǎn)矩陣,根據(jù)旋轉(zhuǎn)角度對路徑點(diǎn)參數(shù)進(jìn)行旋轉(zhuǎn),生成指定方向的marker的Path對象的路徑點(diǎn)參數(shù)。
剩下的marker的大小/顏色等可由MarkerStyle類或plot/scatter函數(shù)其他相關(guān)的關(guān)鍵字屬性自動(dòng)處理。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python numpy庫linspace相同間隔采樣的實(shí)現(xiàn)
這篇文章主要介紹了python numpy庫linspace相同間隔采樣的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02python實(shí)現(xiàn)mp3文件播放的具體實(shí)現(xiàn)代碼
前段時(shí)間在搞一個(gè)基于python的語音助手,其中需要用到python播放音頻的功能,下面這篇文章主要給大家介紹了關(guān)于python實(shí)現(xiàn)mp3文件播放的具體實(shí)現(xiàn)代碼,需要的朋友可以參考下2023-05-05Python面向?qū)ο笾涌?、抽象類與多態(tài)詳解
這篇文章主要介紹了Python面向?qū)ο笾涌凇⒊橄箢惻c多態(tài),結(jié)合實(shí)例形式詳細(xì)分析了Python面向?qū)ο笾薪涌?、抽象類及多態(tài)的概念、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-08-08Python Web開發(fā)模板引擎優(yōu)缺點(diǎn)總結(jié)
這篇文章主要介紹了Python Web開發(fā)模板引擎優(yōu)缺點(diǎn)總結(jié),需要的朋友可以參考下2014-05-05Python?pygame項(xiàng)目實(shí)戰(zhàn)監(jiān)聽退出事件
這篇文章主要介紹了Python?pygame項(xiàng)目實(shí)戰(zhàn)監(jiān)聽退出事件,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08python實(shí)現(xiàn)簡易名片管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡易名片管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04Seaborn數(shù)據(jù)分析NBA球員信息數(shù)據(jù)集
這篇文章主要為大家介紹了Seaborn數(shù)據(jù)分析處理NBA球員信息數(shù)據(jù)集案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09python實(shí)現(xiàn)TCPserver的使用示例
python實(shí)現(xiàn)TCPserver是一件簡單的事情,只要通過socket這個(gè)模塊就可以實(shí)現(xiàn),本文就來介紹一下python實(shí)現(xiàn)TCPserver的使用示例,感興趣的可以了解一下2023-10-10