《第十二章科学计算与可视化.docx》由会员分享,可在线阅读,更多相关《第十二章科学计算与可视化.docx(26页珍藏版)》请在三一办公上搜索。
1、第十二章科学计算与可视化12.1 Python科学计算模块Python主要包含了负责处理数据的NUmPy,数值计算的SCiPy以及图形绘制的MalPIOHib等扩展模块。12.1.1 NumpyNUmPy是PythOn科学计算的基础模块,它专门针对的是严格的数字处理。NUmPy的主要处理对象是同种元素的多维数组,能实现对常用的数学函数进行数组化,从而使这些函数能对数组进行直接运算,这使得原本要在PythOn中进行的循环运算转变成高效率的库函数计算,从而提高了程序的运行效率。目前多为一些大型金融公司在使用,以及核心的科学计算组织如:劳伦斯弗尔(LaWrenCeLivermore)国家实验室,NA
2、SA用其处理一些本来使用C+,Fortran或Matlab等所做的任务。12.1.2 ScipyScipy函数库在NumPy库的基础上增加了许多的数学、科学以及工程计算中常用的函数库,如线性代数、常微分方程数值求解、信号处理、图像处理、稀疏矩阵等等,其中一些函数是在本来使用的Fortran数值计算库进行进一步封装实现的。另外,Scipy中的Weave模块能实现在PythOn中直接嵌入C+程序,进一步提高程序的运算效率。12.1.3 Matplotlib通过数据绘图,可以将枯燥的数字转换成容易被人们接受的图表,从而让人留下更加深刻的印象。而Python中的Matplotlib是基于numpy的一
3、套丰富的数据绘图模块,主要用于绘制一些统计图形,如带标签曲线、散点图、饼图等等,并以多种格式进行图形图像输出。另外,Matplotlib还带有简单的三维绘图功能。12.2 Numpy数据处理标准安装的PythOn中用列表(IiSt)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的123,需要有3个指针和3个整数对象。对于数值运算来说,这种结构显然比较浪费内存和CPU计算时间。此外PythOn还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,也没有各种运
4、算函数,因此也不适合做数值运算。NumPy是Python的一个科学计算的库,NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensionalarrayobject)和UfUnC(universalfunctionobject)。ndarray(下文统一称之为数组)是存储单一数据类型的多维数组,而UfUnC则是能够对数组进行处理的函数。在介绍使用NUmPy之前,我们可访问/files/NUmPy/1.8.1/下载对应操作系统版本的NumPy后安装。12.2.1 IIdalTay对象按前面安装好NumPy之后,就可以使用NumPy扩展模块:Python3.
5、7.3(default,May232015,09:40:32)MSCv.150032bit(Intel)onwin64importnumpyasnp我们可以通过如下语句查看当前所用的NumPy版本号:print(np._version_)1.16.4NUmPy的数组类被称作ndarray,通常被称作数组1,要运算和操作NUmPy的数组首先是需要对其进行创建。创建数组可以通过array。函数传递Python的序列对象:np.array(l,2,3)如果传递的序列是多层嵌套的序列,那么此时将创建多维数组:np.array(H1,2,3.4,5,6J)ndarray对象的常见属性具体如表12-1o套
6、12-1ndarrayXiI象常用属性属性描述ndim数组轴的个数,在PyIhOn的世界中,轴的个数被称作秩shape数组的维度,这是一个指示数组在每个维度上大小的整数元组。例如一个n排m列的矩阵,它的ShaPe属性将是(n,m)size数组元素的总个数,等Fsh叩e属性中元组元素的乘积dtype个用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准Python类型itemsize数组中每个元素的字节大小。例如,元素类型为float64的数组itemsiz属性值为8(=64/8),又如,元素类型为COmPlex32的数组item属性为4(=3278)data包含实际数组元素的缓冲
7、区,通常我们不需要使用这个属性,因为我们总是通过索引来使用数组中的元素NumPy中的数据类型都有几种字符串表示方式,字符串与类型之间的对应关系都存储在IyPeDiel字典中,例如d,double、TloaI64,都表示双精度浮点类型。np.typeDictdnp.(ypeDic(,float,np.typeDictdouble完整的类型列表可以将IyPeDiCt字典中所有的值转换为一个集合,从而去掉重复项。例如,np.lypeDic(,?:,0:,byte,:,,limedelia64:,Timetlelta64:,m8:,int32:,Int32:,i4,:,uint32:,UInt32:,
8、.,intj:,Iongfloaf:,clongfloat:,IongcompIex:,*bool-:class,bytesj:,.,float1:,complex:,bool,:class,object:,str,:,bytes:classa:前面数组的创建是通过先创建一个Python的序列对象,然后通过array。将其转换为数组,这样做效率方面显然不高。因此,NUmPy还提供了许多专门用于创建数组的函数。常见的函数具体见下面的表12-2o式12-2ndarray对象常见函数函数名功能arange()指定开始值、终值和步长创建表示等差数列的一维数组,注意得到的结果数组不包含终值Iinspac
9、eO指定开始值、终值和元素个数创建表示等差数列的维数组,可以通过endpoini参数指定是否包含终值,默认值为TrUe,包含终值IogspaceO与IinSPaCeo类似,但其表示创建等比数列。如IOgSPaCe(0,2,5)&示开始值10的0次幕,终值为10的2次塞的5个数。同时,还可以通过第三个参数base来指定基数,默认是10,并设置endpoii2empty()不对数组元素初始化,而直接分配数组所使用的内存zeros()将数组元素初始化为0fromstring()从字符串创建数组,如omsiring(abcd,dtype=np.ini8)表示从字符串创建一个8bit的整数数组fromf
10、unction()通过预先定义的函数来创建数组实例12-1创建一个表示九九乘法表的二维数组。使用前面学习的fromfunction()函数来实现,输出数组a中的每个元素ai,j都等于func(ij)。代码如下:importnunpyasnpdeffunc(ij):return(i+l)*(j+l)a=np.fromfunction(func,(9,9)print(三)运行结果:H1.2.3.4.5.6.7.8.9.2.4.6.8.10.12.14.16.18.3.6.9.12.15.18.21.24.27.4.8.12.16.20.24.28.32.36.5.10.15.20.25.30.35
11、.40.45.6.12.18.24.30.36.42.48.54.|7.14.21.28.35.42.49.56.63.8.16.24.32.40.48.56.64.72.9.18.27.36.45.54.63.72.81.在创建好数组之后,接下来就是对数组中元素的存取。首先,我们以下面的方式创建一个数组。a=np.arange(10)将对数组a的存取操作归结为如下的表12-3o表12-3数据操作操作功能a5用整数5作为下标,获取数组中的某个元素a3:5用切片(35)作为下标可以获取数组的一部分,包括a3但不包括a5a:5切片中省略下标,表示从a0开始a:-l下标使用负数,表示从数组最后往前数
12、a3:5=l,2下标可以用来修改元素值al:-l:2切片中的第三个参数衣示步长,2表示隔个元素获取个元素a,12获取数组a中下标为1,1,2,2的4个元素,组成一个数组,下标也可以是负数,表示从后往前数b=al:5如果切片产生一个新的数组b,b和a共享一块数组存储空间4提示:当使用布尔数组5作为下标存取数组X中的元素时;将收集数组X中所有的在对应数组中下标为TnIe的元素,使用布尔数组作为下标获得的数组不和原始数组共享数据内存。12.2.2 ufunc运算UfUnC是UniVerSalfUnCtiOn的缩写,它是一种能对数组的每个元素进行操作的函数。它们的计算速度非常快,因为NumPy内置的许
13、多ufunc函数都是在C语言级别实现的。下面是一个使用ufunc函数的简单例子。x=np.linspace(O.np.pi,10)x0.0.0.1.1.12.2.3.y=np.cos(x)y1.0.0.0.50.-0.-0.5-0.-0.-1.函数IinSPaCe()是用来产生一个从0到2的等差数组,接着,将其传递给函数np.cos()计算每个元素的余弦值。需要说明的是,这里的np.cos()就是一个UfImC函数,在其内部对数组X的每个元素会进行循环计算,分别计算余弦值,并返回一个保存各计算结果的数组。有时候也需要通过OUt参数指定计算结果的保存位置。例如:y=np.cos(x,out=x)
14、此时,上面的计算结果会保存在数组X中。提示:np.cos()同样也支持计算单个数值的正弦值。对单个数值的计算,()要比np.sin()速度快。其根本原因是叩.coSo为了同时支持数组和单个数值的计算,其C语言的内部实现要比()复杂得多。因此,在实际计算过程中,导入时不建议使用“import”全部导入,而是应该使用“importnumpyasnp”载入,这就可以根据需要选择合适的函数。另外,NUmPy还提供了丰富的四则运算函数、比较运算和逻辑运算。具体见下表12-4。表124数组运算符及其对应的UfUnC函数运算符对应的IIfUnC函数y=xl+x2add(xl,x2,y)y=x1-x2subt
15、ract(xl,x2,y)y=xl*x2mul(iply(xl,x2,y)y=xlx2divide(xl,x2,y)y=xlx2floor-divide(x1.x2,y)y=-xnegative(x,y)y=xl*x2Power(Xl,x2,y)y=xl%x2remainder(x1,x2,y)或mod(x1.x2,y)y=xI=x2equal(xl,x2,y)y=xl!=x2not-equal(xl,x2,y)y=xlx2lessl(xl,x2,y)y=xlx2greater(xl,x2,y)y=xl=x2greater_equal(x1,x2,y)逻辑与logical_and()逻辑或lo
16、gical-or()逻辑非logical_not()除了NUmPy中内置的ufunc函数,我们有时候考虑到具体实际情况还需要自定义相关ufunc函数。自定义UfUnC函数,一般采用frompyfunc()将一个计算单个元素的函数转换成UfUnC函数。实例12-2通过自定义UfUnC函数来计算分段函数在一个区间段集合上的取值。自定义一个以阈值为0.5的0-1函数,通过frompyfunc()将其转换成ufunc函数,来实现对区间段集合值的计算。代码如下:deftwoparts(x,c):#定义函数.ifx=c:r=l.elifxtwoparts_cal=np.frompyfunc(twopart
17、s,2,1)#转换为UfUnC函数x=np.linspace(0,2,20)y=twoparts_cal(x,0.5)yarray(0,0,0,0,0,1,1,1,1,1,1,1.1,1,1,1,1,1,1,1,dtype=object)12.2.3 多维数组在实例12-1中,我们已经涉及到了一个多维数组的情形,在这一节中将进一步对多维数组进行详细介绍。多维数组的存取和一维数组类似,由于多维数组有多个轴,所以其下标需要多个值来表示。本节讨论的主要是以二维数组为例,更多维情况,就如同我们可以将二维数组看作是元素为一维数组的一维数组类似,我们可以将三维数组看作是元素为二维数组的一维数组,等等。在这
18、里我们介绍创建二维数组的三种方法。1、array(listortuple)函数方法data=l,2,3,4,5,6ndarray=np.array(da(a)ndarrayarray(ll,2,引,4,5,6)2、array。函数和ShaPe属性方法data=np.array(1,2,3,4,5,6)=2,3dataarray(11l,2,3,4,5,6)同样地,也可以通过=2,-1来实现,当设置某个轴的元素个数为-1时,将自动计算此轴的长度。3、array。函数和reshape。函数方法data=np.array(1,2,3,4,5.61)=2,3data=p(3,2)dataarray(l
19、,2,E4.5,6)4、random。随机函数方法data=np.m(2,4)dataarray(0.,0.,0.,0.,0.,0.,0.,0.11)5、内置函数方法(1) ZerOS():创建给定形状的多维数组,并将数组中所有元素填充为1data=np.zeros(2,3)dataarray(0.0.,0.,0.,0.,0.)(2) ones():类似Ones,但用0进行填充data=np.ones(2,3)dataarray(1.,1,1.,I1.,1.,I.)(3) empty。:类似OneS,但不进行初始化,得到的多维数组中的元素值是不确定的data=np.empty(2,3)data
20、array(2.e-316,0.e+000,0.e+000,0.e+000,0.e+000.0.e+000)(4) full。:类似OneS,但需要自己手动指定需为多维数组填充的值data=np.ftll(2,3),05)dataarray0.5,0.5,0.5,0.5,0.5,0.5)(5) eye():创建一个对角矩阵,且所指定的对角线上的元素值为1data=np.eye(2,3)dataarray(111.,0.,0.,0.,1.,0.)(6) identity():创建单位矩阵np.identity(3)array(1.,0.,0.,0.,1.,0.,(0.,0.,I.)(7) dia
21、g():创建对角矩阵。与eye的不同之处在于:对角线上的元素值不是都为1,而是手动指定;不需要指定矩阵的形状,而是靠指定对角线上元素值来确定矩阵的形状。np.diag(3,2,l)array(3,0,0,0,2,0,0,0,1)np.diag(3,2,1,2)array(0,0,3,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,(0,0,0,0,0)存取数组使用元组作为下标,如果下标元组只包含整数的切片,那么得到的数组和原始数组共享数据,改变得到的数组就会改变原始数组的数据。实例12-3平行班成绩计算。现在有三个班,每个班级有15名学生,计算每个班的Pyhm课程平均成绩。
22、成绩采用随机数产生的方式进行模拟生成。首先,我们采用具有三个元素的二维数组,即其ShaPe为3,15来模拟构造三个班同学及其对应的成绩。其次通过NUmPy的mean()函数计算对应班级(即每个一维数组)的平均成绩。代码如下:grade=(100-1)*np.m(3,15)+1grade三个班同学成绩:(78.17.46.21.45.38.4.53.52.88.18.10.66.10.50.21.11.70.33.79.94.81.86.44.82.54.3.12. 36.88.I86.51743532.80.31.97.30.13. 61.28.52.97.92.25. 36.72.三个平行班
23、平均成绩:n.mean(grade0)47.284n.mean(grade(1)39.0924np.mean(grade(2)68.5212.2.4函数调用除了前面部分所涉及的ndarray数组对象和UfUnC函数之外,NumPy还提供了大量对数组进行处理的函数。合理利用和调用这些函数,能够简化程序的逻辑,提高运算速度。常用的统计函数具体见表12-5O表125NumPy中的常用统计函数函数名功能argmax()计算数组最大值的下标argmin()计算数组最小值的下标average()对数组进行平均计算bincount()对整数数组中各个元素出现的次数进行统计,要求数组中素有元素都是非负的max
24、()计算数组的最大值median()获得数组的中值,即对数组进行排序后,位于数组中间位置的值。当长度是偶数时,得到正中间两个数的平均值min()计算数组的最小值histogram()对一维数组进行直方图统计histogram2d()对两组数据的二维直方图进行统计分析polyld()将系数转换为POIykI对象std()计算数组的标准差sum()计算数组元素之和,也可以对列表、元组等与数组类似的序列进行求和unique()找到数组中所有的整数,并按照顺序进行排列var()计算数组的方差实际应用时我们可以直接调用上表中函数,例如以hisiogram()为例,hisiogram()函数格式为:his
25、togram(data,bins=10.range=None.normed=None.Weights=None.density=None)其中,参数data表示保存待统计数据的数组;bins表示指定统计的区间个数,即对统计范围的等分数;range是一个长度为2的数组,表示统计的最小值和最大值,默认值是None,表示由数据的范围决定,即为(),();当normed的参数为False时,函数返回数组data中的数据在每个区间的个数,否则对个数进行正则化处理,使得等于每个区间的概率密度;WeightS参数则和表中的bincounl()函数类似。例如:data=np.(10)np.histogram(
26、data,bins=5,range=None)(array(2,3,2,0,3.dtype=int64),array(I0.,0.0.0,0.,0.)np.histogram(daia,bins=5.range=None,normed=True)(array(l.,2.,1.,0.,2.),array(0.,0.,0.,0.,0.,0.)上述代码主要对数组data中的数据进行统计分析,fay(232Q3)分别表示了对应后一个数组2值加0.,0.,0.,0.,0.,0.),在区间(0.,0)中出现的元素有2个,在区间(0.,0.)中出现的元素有3a,在区间(0.,0.)中出现的元素有2个,在区间
27、(0.,0.)中出现的元素有。个,在区间(0.,0.)中出现的元素有3个。当normed参数值置为Tnle时,则由原来的元素出现个数就转成了元素在每个区间出现的概率密度。另外,如果要统计的区间长度不相等,可以将区间分割位置的数组传递给bins参数,例如:np.histogram(daa,bins=0,0.2,0.6,0.8,1,range=None)(array(2,5,3,0,dtype=int64),array(O.,0.2,0.6,0.8,1.)实例124成绩分析。分析计算某个班级40名同学的Python课程考试成绩。grade=100*np.(40)#模拟产生40名同学的PyIhon课
28、程成绩np.histogram(grade,bins=0,60,80,90,100)#计算班级40名同学每个分数段的人次情况运行结果:(array(24,8,5,3,dtype=int64),array(0,60,80,90,100J)根据结果知,060分之间为24人,6080之间为8人,8090之间为5人,90100之间为3人。12.3Scipy数值计算SCiPy库建立在NUmPy库之上,提供了大量科学算法模块,不同的模块对应于不同的实际应用,主委包括特殊函数(al)、积分(rate)、最优化(ize)、插值(PoIate)、傅立叶变换(ck)、信号处理、线性代数(g)、稀疏特征值(e)、统
29、计0、多维图像处理(ge)、文件10()等等。Scipy是Python中科学计算程序的核心,可以将其与其他标准科学计算程序库进行比较,如,GSL(GNUC或C+科学计算库),Mauab工具箱,等等。在本节中,将主要分三方面来介绍:常数与特殊函数、图像处理和统计应用。Scipy模块可从。12.3.1常数与特殊函数按前面安装好SCiPy之后,就可以使用SCiPy扩展模块。我们可以通过如下的代码语句查看当前所用的SCiPy版本号:importscipyasSpprint(sp._version_)1.3.0下面我们介绍在Scipy中两个比较常用的模块:ConStantS和SPeCia1。1、cons
30、tants模块在该模块中包含了众多数学、物理等方面常用的常量信息。可以通过help命令查看该模块下所包含的所有常量信息。fromscipyimportconstantsaschelp(c)Helponpackageantsinscipy:NAMEantsPyDESCRIPTIONConstants(:mod:ants).currentmodule:antsPhysicalandmathematicalconstantsandunits.MathematicalconstantspiPigoldenGoldenratioPhysicalconstantscspeedoflightinvacuun
31、GNewtonianconstantOfgravitationgstandardaccelerationo(gravityRmolargasconstantkBoltzmannconstantRydbergRydbergconstantFILEd:pylhon37libsile-packagesscipyconstanis_init_.None2、SPeCiaI模块除了常数模块ConStantS,special模块也会经常用到。它包含了基本数学函数、特殊数学函数以及NUmPy中出现的函数的完整函数库。同样可以通过代码:fromscipyimportspecialasshelp(s)查看SPeC
32、ial模块中的特殊函数。这里,我们仅介绍三个比较常见的函数。(1)伽玛函数:al.gamma()伽玛函数定义为:=JorTCT由我们可以用SPeeial模块中的gamma。函数进行计算。fromscipyimportspecialasss.gamma(2)1.0s.gamma(2.5)1.137s.gammaln(3)0.69353其中,al.gammaln()这个函数为对数坐标的伽玛函数,具有更高的数值精度和更大的范围。(2)贝塞尔函数,al.jn()(整数n阶贝塞尔函数)贝塞尔函数定义为:我们可以用SPeCial模块中的jn()函数进行计算。J(=y、但)n+2mm=0fromScipyi
33、mportspecialasss.jn(3,4.5)0.45566(3)椭圆函数:al.ellipj()(雅可比椭圆函数)第一类椭圆积分定义为:Z=F(,k)=/僚.雅可比椭圆函数的形式记为:-8n=F(z,k可以用SPeCiaI模块中的ellipj()进行计算。fromScipyimportspecialasss.ellipj(3,0.5)(0.03296,-0.776576,0.62057,2.6027)实例125根据COnStantS模块中定义的常数pi,计算半径r=l圆面积和球面积。fromscipyimportpir=larea=pi*r*r3.9793volume=4.03*pi*
34、r*r*r4.6390512.3.2Scipy应用于图像处理SCiPy的ndimage子模块是专用于n维图像处理的函数库,包含了用于图像滤波(filters)、傅里叶变换(fourier)、图像信息测量(measurements)形态学图像处理(morphology)、图像插值、旋转及仿如变换(interpolation)等子模块。这里,我们主要以图像滤波模块为例介绍Scipy对于图像处理的应用。(1)图像滤波(filters)rs具有图像滤波功能。rs.gaussianJilter对频度图进行高斯模糊处理,其主要的两个参数意思为,第一个参数表示要处理的滤波array:第二个参数为高斯终的热点
35、图也越分散。核酸麟居余曜藕翻髓需翳缸Iimportge.filtersasfhelp(f)Helponmodulege.fiItersinge:NAMEge.filtersFILEd:python37libsite-packagesScipyndimageFUNCTIONSconvolve(input,weights,output=None,mode=reflect,cval=O.O,origin=0)a=np.array(l,2,0,0.5,3,0,4,.0,0,0,7J,.9,3,0,0)k=np.array(1,1,1,1,1,0,1,0,0)fromScipyimportndimage
36、lve(a.k,mode=constant,.cval=0.0)array(1111,10,7,4,10,3,11,11,15,12,14.7,12,3,7,OJJ)correlate(input,weights,output=None,mode=reflect,cval=0.0,origin=0)gaussian_filter(inpu(,sigma,order=0,Output=None,mode=reflect,cval=0.0,runcate=4.0)truncate=4.0)gaussian_gradient_magnitude(inpul.Sigma,Outpul=None,mod
37、e=reflect,cval=0.0,*kwargs)gaussian_laplace(input,sigma,output=None,mode=reflect,cval=0.0,*kwargs)generic_fi1ter(input,function,size=None,fotprint=None,Output=None,node=reflect,cval=0.0,origin=0,extra_arguments=(),exlra_keywords=None)generic_gradient_magnitude(input.derivative,output=None.mode=refle
38、ct,eval=0.0,extra_arguments=(),extra_keywords=None)generic_laplace(input,derivative2,output=None,mode=reflect,eval=0.0,extra-arguments=(),ex(ra_keywords=None)laplace(input,output=None,mode=reflect.cval=0.0)maximum-filter(input,size=None,footprint=None,output=None,mode=refleet,cval=0.0,origin=0)mcdia
39、n_filter(input,size=None,fbotprint=None,output=None,mode=refleet,eval=0.0,origin=0)minimum_filier(inpul,size=None,fbotprint=None,Oulpul=None,mxle=reect,cval=0.0,origin=0)percentile-filter(input,percentile,size=None,fbotprint=None,output=None.mode=,reflect,cval=0.0,origin=0)prewit(inut,axis=-1,Outpul
40、=None.mode=,refleet,cval=0.0)rank-filter(input,rank,size=None,footprint=None,output=None.mode=,reflectcval=0.0,origin=0)sobel(input,axis=-1,output=None,mode=reflect,cvaI=0.0)unifbn-filter(input,size=3,Output=None,mode=reflect,cval=0.0,origin=0)Mul(i-dimensionaluniformfiller.Parametersinput:aay-likeI
41、nputarraytofilter.size:intorsequenceofints,optionalThesizesoftheuniformfilteraregivenforeachaxisasasequence,orasasinglenumber,inwhichcasethesizeisequalforallaxes.output:array,optionalTheoutputparameterpassesanarrayinwhichtostorethefilteroutput.mode:reflect,constant,nearest,.,mirror,wrap),optionalThe
42、modeparameterdetermineshowthearraybordersarehandled,wherecvaisthevaluewhenmodeisequaltoconstant.Defaultis,reflecteval:scalar,optionalValuetofillpastedgesofinputifmodeisconstant.Defaultis0.0origin:scalar,optionalTheoriginparametercontrolstheplacementofthefilter.Default0.0.实例12-6绘制上海浦东新区张江地区Ofo共享单车分布热
43、点信息图。首先,载入浦东新区张江地区地图图片,创建一些Ofo共享单车分布随机分布的散列点,这些散列点以某些坐标为中心正态分布构成一些热点。使用gram2d()可以在地图图片的网格中统计二维散列点的频度,由于散列点数量较少,histogram2d()的结果并不能形成足够的热点信息。taspitimportasmpimgimportnunpyasnpimg=d(c:/image/l.png)h,w,_=xs,ys=,foriinrange(100):mean=w*np.(),h*np.()a=50+np.nt(50.200)b=50+np.nt(50,200)c=(a+b)*np.l()*0.2cov=a,c,c,bcount=200x,y=np.variate_normal(mean.cov,size=count).Txs.append(x)ys.append(y)X=np.concatenate(xs)y=np.concatenate(ys)hist,_=np.his