小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

matplotlib技巧集之一

 dinghj 2014-10-25

不連續(xù)點

當(dāng)一條曲線中存在跳變點時,如果直接用plot()繪圖會用一條直線將跳變前后的點連接起來。若不想繪制跳變處的連接線,可在數(shù)組的跳變處插入Nan值,下面的程序演示了這一方法。

import numpy as np
import pylab as pl

x = np.linspace(-1, 1, 1000)
y = np.select([x<-0.5, x<0, x<0.5, True], [x**2, x**3, 1-x, 1-x**2])

ax = pl.subplot(121)
pl.plot(x, y, lw=2)

pl.subplot(122, sharey=ax)
pos = np.where(np.abs(np.diff(y))>0.05)[0]+1 ?
x2 = np.insert(x, pos, np.nan) ?
y2 = np.insert(y, pos, np.nan)

pl.plot(x2, y2, lw=2)
pl.show()

找到曲線中所有前后兩個點的高度差大于0.05的下標(biāo),?調(diào)用np.insert()在不連續(xù)點處插入np.nan。

matplotlib_segments.png

參數(shù)曲線上繪制方向箭頭

在參數(shù)曲線中為了表示隨著參數(shù)的增大,曲線的變化情況,需要在曲線上繪制箭頭表示方向。

import numpy as np
import pylab as pl

t = np.linspace(0, 2*np.pi, 1000)

x = np.sin(3*t)
y = np.cos(5*t)

def split_positions(x, y, n):
    dx = np.diff(x)
    dy = np.diff(y)
    l = np.sqrt(dx*dx+dy*dy)  ?
    cl = np.cumsum(l)         ?
    pos = np.linspace(0, cl[-1], n) ?
    idx = np.searchsorted(cl, pos)  ?
    dx = x[idx+1] - x[idx]          ?
    dy = y[idx+1] - y[idx]
    s = np.sqrt(dx*dx+dy*dy)
    dx/=s
    dy/=s
    return x[idx], y[idx], dx, dy

for x0, y0, dx, dy in zip(*cal_arrow(x, y, 18)):
    pl.arrow(x0, y0, dx*0.01, dy*0.01, head_width=0.05) ?

pl.plot(x, y)
pl.axis("equal")
pl.show()

split_positions(x, y, n)計算曲線(x,y)上等距離的n個點,以及在這n個點上的曲線切線方向。?首先計算曲線上每個小段的長度l,?對l用np.cumsum()進(jìn)行累加,得到到達(dá)曲線上每點時所走過的曲線長度cl。?cl[-1]為曲線的總長度,將這個總長度等分為n-1等分,?然后通過np.searchsorted()搜索每個等分點所對應(yīng)的下標(biāo)。?最后通過等分處前后兩個點計算出曲線在此處的切線方向。

對split_positions()得到的每個點調(diào)用pl.arrow()繪制箭頭,將dx和dy乘以一個很小的數(shù)(此處為0.01)是為了只繪制箭頭,好讓箭頭能剛好位于曲線之上。

matplotlib_curve_arrows.png

修改缺省刻度數(shù)目

在matplotlib中,圖表的刻度的位置由Axis對象的major.locator屬性決定,而子圖對象Axes的xaxis和yaxis屬性分別表示X軸和Y軸。

>>> import pylab as pl
>>> pl.plot([1,2,3])
[]
>>> pl.gca().xaxis.major.locator

缺省使用AutoLocator計算刻度的位置,下面是其代碼:

class AutoLocator(MaxNLocator):
    def __init__(self):
        MaxNLocator.__init__(self, nbins=9, steps=[1, 2, 5, 10])

可以看出刻度數(shù)目由nbins決定,缺省值為9。nbins決定的是最大刻度線數(shù),根據(jù)當(dāng)前的顯示范圍和steps的設(shè)置,AutoLocator會自動調(diào)節(jié)刻度線數(shù)。

當(dāng)刻度文本較長時,過多的刻度數(shù)會導(dǎo)致刻度文本不易看清,因此我們希望能修改缺省的刻度數(shù)目。但由上面的代碼可知,我們無法通過修改matplotlib的參數(shù)配置修改缺省刻度數(shù)。這時可以通過重新定義AutoLocator.__init__()實現(xiàn)這一功能。

import numpy as np
import pylab as pl
from matplotlib import ticker

def AutoLocatorInit(self): ?
    ticker.MaxNLocator.__init__(self, nbins=4, steps=[1, 2, 5, 10])
ticker.AutoLocator.__init__ = AutoLocatorInit ?

pl.rcParams["xtick.labelsize"] = 20
pl.rcParams["ytick.labelsize"] = 20
pl.plot(pl.randn(150), lw=2)
pl.show()

定義了一個和AutoLocator.__init__()類似的函數(shù),只是將nbins參數(shù)改為4,?然后將AutoLocator.__init__改為使用此函數(shù)。

matplotlib_locator.png

Y軸不同區(qū)間使用不同顏色填充

要求實現(xiàn)的效果如下圖所示,根據(jù)Y軸的范圍,使用不同的顏色對區(qū)域進(jìn)行填充。

matplotlib_color_range.png

填充區(qū)域的最小值和最大值由mintemps和maxtemps給出,而每個范圍的顏色由colors給出:

maxtemps = [ 25, 24, 24, 25, 26, 27, 22, 21, 22, 19, 17, 14,
             13, 12, 11, 12, 11, 10, 9, 9, 9, 8, 9, 9, 8 ]
mintemps = [ 21, 22, 22, 22, 23, 24, 18, 17, 16, 14, 10, 8,
              8, 7, 7, 6, 5, 5, 5, 4, 4, 4, 3, 4, 3 ]
times = list(xrange(len(mintemps)))

colors = [
    (25, '#FF69B4'),
    (20, '#F08228'),
    (15, '#E6AF2D'),
    (10, '#E6DC32'),
    (5,  '#A0E632'),
    (0,  '#00DC00')
]

填充區(qū)域可使用fill_between()實現(xiàn),但是它只支持一種顏色,因此需要對每個顏色范圍調(diào)用一次fill_between()。本題的難點在于如何計算整個區(qū)域與某個范圍相交的部分。我們可以使用NumPy的線性插值函數(shù)interp()和裁剪函數(shù)clip()快速實現(xiàn)這一運算。下面是完整的源程序:

import pylab as pl
import numpy as np
x = np.linspace(times[0], times[-1], 500)
maxt = np.interp(x, times, maxtemps) ?
mint = np.interp(x, times, mintemps) ?

last_level = np.inf
for level, color in colors:
    tmp_min = np.clip(mint, level, last_level) ?
    tmp_max = np.clip(maxt, level, last_level) ?
    pl.fill_between(x, tmp_min, tmp_max, lw=0, color=color) ?
    last_level = level

pl.grid(True)
pl.show()

對mintemps和maxtemps用np.interp()進(jìn)行線性插值,得到更細(xì)分的數(shù)據(jù)。?對colors中的每個區(qū)域進(jìn)行循環(huán),并使用np.clip()對細(xì)分之后的最大值和最小值進(jìn)行剪裁。?調(diào)用pl.fill_between()使用指定的顏色對裁剪之后的區(qū)域進(jìn)行填充。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多