打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
matplotlib技巧集之一

不连续点

当一条曲线中存在跳变点时,如果直接用plot()绘图会用一条直线将跳变前后的点连接起来。若不想绘制跳变处的连接线,可在数组的跳变处插入Nan值,下面的程序演示了这一方法。

import numpy as npimport pylab as plx = 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的下标,?调用np.insert()在不连续点处插入np.nan。

参数曲线上绘制方向箭头

在参数曲线中为了表示随着参数的增大,曲线的变化情况,需要在曲线上绘制箭头表示方向。

import numpy as npimport pylab as plt = 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, dyfor 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()进行累加,得到到达曲线上每点时所走过的曲线长度cl。?cl[-1]为曲线的总长度,将这个总长度等分为n-1等分,?然后通过np.searchsorted()搜索每个等分点所对应的下标。?最后通过等分处前后两个点计算出曲线在此处的切线方向。

对split_positions()得到的每个点调用pl.arrow()绘制箭头,将dx和dy乘以一个很小的数(此处为0.01)是为了只绘制箭头,好让箭头能刚好位于曲线之上。

修改缺省刻度数目

在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])

可以看出刻度数目由nbins决定,缺省值为9。nbins决定的是最大刻度线数,根据当前的显示范围和steps的设置,AutoLocator会自动调节刻度线数。

当刻度文本较长时,过多的刻度数会导致刻度文本不易看清,因此我们希望能修改缺省的刻度数目。但由上面的代码可知,我们无法通过修改matplotlib的参数配置修改缺省刻度数。这时可以通过重新定义AutoLocator.__init__()实现这一功能。

import numpy as npimport pylab as plfrom matplotlib import tickerdef AutoLocatorInit(self): ?    ticker.MaxNLocator.__init__(self, nbins=4, steps=[1, 2, 5, 10])ticker.AutoLocator.__init__ = AutoLocatorInit ?pl.rcParams["xtick.labelsize"] = 20pl.rcParams["ytick.labelsize"] = 20pl.plot(pl.randn(150), lw=2)pl.show()

定义了一个和AutoLocator.__init__()类似的函数,只是将nbins参数改为4,?然后将AutoLocator.__init__改为使用此函数。

Y轴不同区间使用不同颜色填充

要求实现的效果如下图所示,根据Y轴的范围,使用不同的颜色对区域进行填充。

填充区域的最小值和最大值由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')]

填充区域可使用fill_between()实现,但是它只支持一种颜色,因此需要对每个颜色范围调用一次fill_between()。本题的难点在于如何计算整个区域与某个范围相交的部分。我们可以使用NumPy的线性插值函数interp()和裁剪函数clip()快速实现这一运算。下面是完整的源程序:

import pylab as plimport numpy as npx = np.linspace(times[0], times[-1], 500)maxt = np.interp(x, times, maxtemps) ?mint = np.interp(x, times, mintemps) ?last_level = np.inffor 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 = levelpl.grid(True)pl.show()

对mintemps和maxtemps用np.interp()进行线性插值,得到更细分的数据。?对colors中的每个区域进行循环,并使用np.clip()对细分之后的最大值和最小值进行剪裁。?调用pl.fill_between()使用指定的颜色对裁剪之后的区域进行填充。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
python matplotlib绘图设置坐标轴刻度、文本
Python数据可视化Matplotlib,坐标轴刻度线定位自动定位法
1.4Matplotlib:绘图
怎么用积分求一条(曲)线的长度 爱问知识人
Python 绘制分形图
matplotlib画图系列之设置坐标轴(精度、范围,标签,中文字符显示)python3
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服