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

使用matplotlib畫圖自定義marker

 更新時(shí)間:2023年06月25日 09:06:16   作者:qiu_xingye  
這篇文章主要介紹了使用matplotlib畫圖自定義marker問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

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)處理。

https://stackoverflow.com/questions/11487797/python-matplotlib-basemap-overlay-small-image-on-map-plot 

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論