Python 和 SPL 对比 14——数据可视化
数据分析过程中,数据可视化可以帮我们更好的感知数据,从而采用更好的策略来处理数据,本文就来对比一下 Python 和 SPL 在数据可视化方面的情况。
Python
Python常用的两个画图库是Matplotlib和seaborn,Matplotlib以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。seaborn是基于matplotlib的数据集分布可视化库。它在matplotlib的基础上,进行了更高级的封装,从而使得绘图更加容易,不需要经过大量的调整,就能使图像变得精致。
下面以一些常见的图像来介绍Python的作图功能。
散点图
随机生成100个点,即横纵坐标都是0-1范围内的随机数。
Python代码
import matplotlib.pyplot as plt import numpy as np n = 100 X = np.random.random(size=n) Y = np.random.random(size=n) plt.scatter(X,Y,s = 5,c="b") plt.xlim((0,1)) plt.ylim((0,1)) plt.show() |
导入库 点数 X坐标 Y坐标 散点图 横坐标范围 纵坐标范围 展示 |
Python的matplotlib pyplot库提供了现成的散点图函数scatter(…),只要设置其中的参数就可以了,其中包括点的颜色、形状、大小、透明度等等。
画图结果如下:
曲线图
横坐标X是-10~10范围内间隔为0.1的序列,纵坐标Y=0.05*x2。
Python代码
import numpy as np import matplotlib.pyplot as plt x = np.arange(-10,10,0.1) y1 = 0.05 * x ** 2 plt.plot(x,y1,'g-') plt.show() |
导入库 X坐标 Y坐标 曲线图 展示 |
plot()函数可以绘制曲线图,和scatter(…)类似只要设置其中的参数就可以修改曲线的颜色、形状、粗细等,此外还可以设置线上点的颜色、形状等等。
画图结果如下:
直方图
假设有A~L个类别,他们对应的取值是0.5~1之间的随机数,请用直方图描述这12个类别的取值,并在图中标出各类别的取值。
Python代码
import matplotlib.pyplot as plt import numpy as np n = 12 X = [chr(i) for i in range(65,65+n)] Y = np.random.uniform(0.5,1.0,n) plt.bar(X,Y) for x,y in zip(X,Y): plt.text(x,y,'%.2f'%y,ha = 'center',va='bottom') plt.show() |
导入库 X坐标 Y坐标 直方图 标记取值 展示 |
bar()函数可以绘制直方图,设置其中的参数可以修改直方的颜色、位置等等。
画图结果如下:
现在图中显示的是A~L个类别的数量情况,如果有些类别比如Z(应该在第二个位置)因为数量是0没有显示在上图,如果想把它也表现在图上。
Python代码
import matplotlib.pyplot as plt import numpy as np n = 12 X = [chr(i) for i in range(65,65+n)] Y = np.random.uniform(0.5,1.0,n) X.insert(1,"Z") Y=np.insert(Y,1,0) plt.bar(X,Y) for x,y in zip(X,Y): plt.text(x,y,'%.2f'%y,ha = 'center',va='bottom') plt.show() |
导入库 X坐标 Y坐标 增加Z 增加Z的值 直方图 标记取值 展示 |
如果X,Y是业务数据,增加业务类别”Z”时必须要修改Y,使Y有类别”Z”的取值才可以在图上呈现。
画图结果如下:
分组直方图
已知某校男生和女生在5个科目上的得分,请绘制分组直方图将男女生放在一起对比他们各科目的得分情况。
import matplotlib.pyplot as plt import numpy as np import pandas as pd file="Hg_CData.csv" data=pd.read_csv(file) data_p=data.pivot(index="Subject",columns="Gender",values="Score") labels = data_p.index men_means = data_p.MenS women_means = data_p.WomenS x = np.arange(len(labels)) width = 0.35 fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, men_means, width, label='Men') rects2 = ax.bar(x + width/2, women_means, width, label='Women') ax.set_ylabel('Scores') ax.set_title('Scores by group and gender') ax.set_xticks(x) ax.set_xticklabels(labels) ax.legend() plt.show() |
导入库 读数据 转换数据 科目 男生得分 女生得分 直方图宽度 男生得分直方图 女生得分直方图 设置y轴名 设置图名 设置x轴 设置x轴的科目名 图例 展示 |
画分组直方图需要手动对数据分组,本例中分为男生和女生两组,然后用subplots()函数分别绘制男生和女生得分情况,相当于是画了两组直方图。legend()是图例设置函数,修改它参数可以修改图例的位置等属性。
画图结果如下:
堆叠直方图
将上例的数据画成堆叠直方图。
import matplotlib.pyplot as plt import numpy as np import pandas as pd file="Hg_CData.csv" data=pd.read_csv(file) data_p=data.pivot(index="Subject",columns="Gender",values="Score") labels = data_p.index men_means = data_p.MenS women_means = data_p.WomenS x = np.arange(len(labels)) width = 0.35 p1 = plt.bar(x, men_means, width) p2 = plt.bar(x, women_means, width, bottom=men_means) plt.ylabel('Scores') plt.title('Scores by group and gender') plt.xticks(x,labels) plt.legend((p1[0], p2[0]), ('Men', 'Women')) plt.show() |
导入库 读数据 转换数据 科目 男生得分 女生得分 直方图宽度 男生得分直方图 女生得分直方图 设置y轴名 设置图名 设置x轴 图例 展示 |
我们可以看到在堆叠直方图时,Python其实是画了两段直方,将两段拼接在一起变有了堆叠直方图,比较麻烦的一点是需要手动算出每段直方图的底。
画图结果如下:
饼图
假设有a,b,c,d四个类别,他们的占比分别是15%,30%,45%,10%,请画出饼图。
Python代码
importmatplotlib.pyplotasplt s=["a","b","c","d"] p=[15,30,45,10] plt.pie(p,autopct='%1.1f%%',labels=s) plt.show() |
导入库 类别 百分比 饼图 展示 |
pie()函数可以绘制饼图,设置其中的参数可以修改饼图的形态、角度等等。
画图结果如下:
嵌套饼图
假设已知连续3年内a,b,c,d四个类别的占比,请画饼图示意。
Python代码
importmatplotlib.pyplotasplt importnumpyasnp years=["2019","2020","2021"] s=["a","b","c","d"] p2019=[15,30,45,10] p2020=[23,28,32,17] p2021=[18,21,51,10] radius=[0.5,0.8,1] colors=["red","orange","yellow","gray"] angles=[30,150,270] fig,ax=plt.subplots() ax.pie(p2021,pctdistance=0.9,radius=radius[2],autopct='%3.1f%%',colors=colors, wedgeprops={"edgecolor":"black"}) ax.pie(p2020,pctdistance=0.75,radius=radius[1],autopct='%3.1f%%', colors=colors,wedgeprops={"edgecolor":"black"}) ax.pie(p2019,pctdistance=0.5,radius=radius[0],autopct='%3.1f%%', colors=colors,wedgeprops={"edgecolor":"black"}) bbox_props=dict(boxstyle="square,pad=0.3",fc="w",ec="k",lw=0.72) kw=dict(arrowprops=dict(arrowstyle="-"), bbox=bbox_props,va="center") foriinrange(len(years)): ang=angles[i] y=np.sin(np.deg2rad(ang))*radius[i] x=np.cos(np.deg2rad(ang))*radius[i] ha={-1:"right",1:"left"}[int(np.sign(x))] connectionstyle="angle,angleA=0,angleB={}".format(ang) kw["arrowprops"].update({"connectionstyle":connectionstyle}) plt.annotate(years[i],xy=(x,y),xytext=(1.35*np.sign(x),1.4*y), ha=ha,**kw,fontsize=18,weight='bold') plt.legend(s,bbox_to_anchor=(1.05,1),loc='best',borderaxespad=0.) plt.show() |
导入库 年份 类别 2019年类别占比 2020年类别占比 2021年类别占比 嵌套饼图半径 颜色 标记年份的角度 画布 画2021年饼图 画2020年饼图 画2019年饼图 标注线设置 标注年份 标注的纵坐标 标注的横坐标 ⽔平对⻬⽅式 箭头连接样式 更新箭头连接⽅式 标注年份 图例 |
pie()函数的参数labels可以标记类别,但对于嵌套饼图中每个饼图的注释则需要手动来画标记线,从代码中也可以看出,标注线的设置还是很麻烦的,甚至超过画饼图的工作量了。
画图结果如下:
双纵坐标画图
横坐标x相同,绘制两条不同的曲线,这两条曲线分别用自己的纵坐标。
Python代码
import matplotlib.pyplot as plt import numpy as np x = np.arange(0,10,0.1) y1 = 0.05 * x ** 2 y2 = -1 * y1 fig,ax1 = plt.subplots() ax2 = ax1.twinx() ax1.plot(x,y1,'g-') ax2.plot(x,y2,'b-') ax1.set_xlabel('X data') ax1.set_ylabel('Y1 data',color = 'g') ax2.set_ylabel('Y2 data',color = 'b') plt.show() |
导入库 x y1 y2 绘制子图 添加y2轴 绘制y1曲线 绘制y2曲线 添加x轴标签 添加y1轴标签 添加y2轴标签 展示 |
subplots ()函数用来绘制子图,twinx()增加y轴,然后用plot()函数画出曲线即可。
画图结果如下:
多图合并展示
将上述中的散点图、曲线图、直方图、饼图合并显示在一张图上。
Python代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from mpl_toolkits.mplot3d import Axes3D plt.figure(figsize = (12,10)) ax1 = plt.subplot(2,2,1) #绘制散点图 n = 1024 X = np.random.normal(0,1,n) Y = np.random.normal(0,1,n) plt.scatter(X,Y,s = 10,c="r",alpha = .2) plt.xlim((-4,4)) plt.ylim((-4,4)) #绘制曲线图 ax3 = plt.subplot(2,2,2) x = np.arange(-10,10,0.1) y1 = 0.05 * x ** 2 plt.plot(x,y1,'g-') #绘制直方图 ax3 = plt.subplot(2,2,3) n = 12 X = [chr(i) for i in range(65,65+n)] Y = np.random.uniform(0.5,1.0,n) plt.bar(X,Y) for x,y in zip(X,Y): plt.text(x,y,'%.2f'%y,ha = 'center',va='bottom') #绘制饼图 ax4 = plt.subplot(2,2,4) s = ["a","b","c","d"] p = [15, 30, 45, 10] plt.pie(p,autopct='%1.1f%%',labels=s) plt.show() |
subplots ()函数用来绘制子图,其中的参数表示子图的位置,如2,2,1表示2行2列画布的第一个位置,剩下的只要在对应的位置画图即可。
画图结果如下:
动图
动态的画出一条由点组成的线。
Python代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation fig, ax = plt.subplots() xdata, ydata = [], [] ln, = plt.plot([], [], 'ro',markersize=2) x=np.linspace(0, 2 * np.pi, 128) def init(): ax.set_xlim(0, 2 * np.pi) ax.set_ylim(-1, 1) return ln, def update(frame): xdata.append(frame) ydata.append(np.sin(frame)) ln.set_data(xdata, ydata) return ln, ani = FuncAnimation(fig, update, frames=x,interval=10, init_func=init, blit=True) plt.show() |
导入库 x 初始化 更新 作图 展示 |
animation是matplotlib库中绘制动图的模块,FuncAnimation()是绘制动图的函数,设置其中的参数可以修改动图的属性。
画图结果如下:
图中图
在图中增加两幅子图。
Python代码
import matplotlib.pyplot as plt fig = plt.figure() x = [1,2,3,4,5,6,7] y = [1,3,4,2,5,8,6] #主图位置 left, bottom, width, height = 0.1, 0.1, 0.8, 0.8 #绘制主图 ax1 = fig.add_axes([left, bottom, width, height])# main axes ax1.plot(x,y,'r') ax1.set_xlabel('x') ax1.set_ylabel('y') ax1.set_title('title') #绘制图中图1 ax2 = fig.add_axes([0.2, 0.6, 0.25, 0.25]) # inside axes ax2.plot(y, x, 'b') ax2.set_xlabel('x') ax2.set_ylabel('y') ax2.set_title('title inside 1') #另一种方法绘制图中图2 plt.axes([0.6, 0.2, 0.25, 0.25]) plt.plot(y[::-1], x, 'g') plt.xlabel('x') plt.ylabel('y') plt.title('title inside 2') plt.show() |
add_axes()函数是新增子图函数,相当于另开辟一张图,axes()也是创建图形的。
画图结果如下:
热图
随机生成1个以a~j为字段名,数值在0~1范围内的10行Dataframe,并以此为依据画出热图。
Python代码
import seaborn as sns import pandas as pd import numpy as np import matplotlib.pyplot as plt df = pd.DataFrame(np.random.random((10,10)), columns=["a","b","c","d","e","f","g","h","i","j"]) sns.heatmap(df, annot=True, annot_kws={"size": 7},cmap="coolwarm") plt.show() |
导入库 Dataframe 绘制热图 展示 |
heatmap()函数是seaborn库中的一个函数,用来绘制热图,设置其中的参数可以修改热图的属性。
画图结果如下:
等高线图
在横纵坐标都在-3~3范围内画出等高线图,其中高度h用如下公式计算:
其中x和y分别是-3~3范围内的值。
Python代码
import matplotlib.pyplot as plt import numpy as np def f(x,y): return (1-x/2 + x**5+y**3) * np.exp(-x **2 -y**2) n = 256 x = np.linspace(-3,3,n) y = np.linspace(-3,3,n) X,Y = np.meshgrid(x,y) Ct=f(X,Y) C = plt.contour(X,Y,Ct,2,colors = 'black') plt.clabel(C,inline = True,fontsize = 10) plt.contourf(X,Y,Ct,2,alpha = .75,cmap = plt.cm.hot) plt.show() |
导入库 计算高度值展示 X Y 等高线网格状数据 x,y坐标对应的高度值 等高线轮廓 等高线标记 等高线填充 展示 |
meshgrid()函数将数据网格化,contour()、clabel()和contourf()函数分别绘制等高线轮廓、标记和填充,设置它们的参数可以修改等高线的属性。
画图结果如下:
3D图
将上例的等高线图画为3D图。
Python代码
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def f(x,y): return (1-x/2 + x**5+y**3) * np.exp(-x **2 -y**2) fig = plt.figure() ax = Axes3D(fig) n=256 X = np.linspace(-3,3,n) Y = np.linspace(-3,3,n) X,Y = np.meshgrid(X,Y) Z=f(X,Y) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow')) plt.show() |
导入库 计算Z X Y 网格化 Z 绘制3D图 展示 |
mpl_toolkits.mplot3d是Matplotlib里面专门用来画三维图的工具包,Axes3D是mpl_toolkits.mplot3d中的一个绘图函数,plot_surface()函数是绘制3D图的函数,设置它的参数可以修改3D图像的各种属性。
画图结果如下:
在Pycharm设计器中,这幅3D图还可以拖动鼠标变换观察角度,如下图是另一个角度看到的图:
从不同的角度观察数据可以更好的了解3D图的情况,本例的3D图相当于上例等高线的3D地形图。
SPL
SPL也提供了绘图功能,常用的散点图、曲线图、直方图等也都可以呈现出来,SPL也可以呈现一些简单的动图,但是在某些复杂功能上还不够完善,如图中图、热图、等高线图、3D图等暂时还不能轻松呈现出来,这里只介绍常用的可视化功能。
散点图
随机生成100个点,即横纵坐标都是0-1范围内的随机数。
SPL代码
A |
B |
|
1 |
100 |
/点数 |
2 |
=canvas() |
/画布 |
3 |
=100.(rand()) |
/X |
4 |
=100.(rand()) |
/Y |
5 |
=A2.plot("NumericAxis","name":"x","autoCalcValueRange":false, "autoRangeFromZero":false,"maxValue":1.0) |
/横轴 |
6 |
=A2.plot("NumericAxis","name":"y","location":2,"autoCalcValueRange":false, "maxValue":1.0,"minValue":0) |
/纵轴 |
7 |
=A2.plot("Dot","lineColor":-16776961, "markerColor":["ChartColor",0,false,-16776961,-16776961,0], "markerWeight":1,"axis1":"x","data1":A3,"axis2":"y","data2":A4) |
/散点 |
8 |
=A2.draw@p(600,400) |
/展示 |
A2格的canvas()函数返回一个称为画布的对象, plot()函数用来作图,其中A5、A6、A7分别画出横轴、纵轴、和散点,它们的区别是plot()函数的内容不同,如:A5、A6是画坐标轴NumericAxis,A7画散点Dot,其他的参数是他们分别对应的颜色、形状等属性,对其修改即可画出想要的散点图。A8格中的draw()函数是画图函数,用来将图呈现出来,其中的参数则是呈现的图的大小。
plot()函数的参数那么多,怎么设置呢?
SPL提供了编辑界面辅助完成参数设置,右键点击要画图的单元格,选中“绘图编辑”选项,如下图:
点击蓝框中的选项,打开对话框:
左边第一列都是 plot()函数的参数!多到还要展开收缩的地步才方便看得清。右半部分是为了编辑序列型参数设置的,大家可以尝试修改这些属性,看看画图效果。
右上角的“图元”选项卡可以选择所需的图元,包括数值轴、时间轴等轴图元,也包括点、线、柱等图元,如下图:
SPL 中的图形就是由一批图元构成的,每种图元有各自的属性。选定了图元后,下面的属性列表就会跟着变化,然后再填入这个图元的属性,一句 plot()函数就编辑完了。每一句 plot()都会在画布上绘制一个或多个同种类型的图元。
画图结果如下:
曲线图
横坐标X是-10~10范围内间隔为0.1的序列,纵坐标Y=0.05*x2。
SPL代码
A |
B |
|
1 |
200 |
|
2 |
=canvas() |
/画布 |
3 |
=A1.(-10+0.1*(#-1)) |
/X |
4 |
=A3.(0.05*~*~) |
/Y |
5 |
=A2.plot("NumericAxis","name":"x","autoCalcValueRange":false, "autoRangeFromZero":false,"minValue":-10) |
/横轴 |
6 |
=A2.plot("NumericAxis","name":"y","location":2,"autoRangeFromZero":false) |
/纵轴 |
7 |
=A2.plot("Line","lineColor":-16776961, "markerColor":["ChartColor",0,false,-16776961,-16776961,0], "markerWeight":-1,"axis1":"x","data1":A3,"axis2":"y","data2":A4) |
/曲线 |
8 |
=A2.draw@p(600,400) |
/展示 |
A7格用线图元”Line”绘制曲线。
画图结果如下:
直方图
假设有A~L个类别,他们对应的取值是0.5~1之间的随机数,请用直方图描述这12个类别的取值,并在图中标出各类别的取值。
SPL代码
A |
B |
|
1 |
12 |
|
2 |
=canvas() |
/画布 |
3 |
=A1.(char(64+#)) |
/X |
4 |
=A3.(round(rand()*0.5+0.5,2)) |
/Y |
5 |
=A2.plot("EnumAxis","name":"x") |
/横轴 |
6 |
=A2.plot("NumericAxis","name":"y","location":2) |
/纵轴 |
7 |
=A2.plot("Column","text":A4,"axis1":"x","data1":A3,"axis2":"y","data2":A4) |
/直方图 |
8 |
=A2.draw@p(600,400) |
/展示 |
A7格用柱图元”Column”绘制直方图。
画图结果如下:
现在图中显示的是A~L个类别的数量情况,如果有些类别比如Z(应该在第二个位置)因为数量是0没有显示在上图,如果想把它也表现在图上。
SPL代码
A |
B |
|
1 |
12 |
|
2 |
=canvas() |
/画布 |
3 |
=A1.(char(64+#)) |
/X |
4 |
=A3.(round(rand()*0.5+0.5,2)) |
/Y |
5 |
=(A3*1).insert(2,"X") |
/类别 |
6 |
=A2.plot("EnumAxis","name":"x","categories":A5) |
/横轴 |
7 |
=A2.plot("NumericAxis","name":"y","location":2) |
/纵轴 |
8 |
=A2.plot("Column","text":A4,"axis1":"x","data1":A3,"axis2":"y","data2":A4) |
/散点 |
只要在A6格的参数中增加categories,SPL就可以自动找到各类别在X轴上的位置,不需要改变业务数据。
画图结果如下:
分组直方图
已知某校男生和女生在5个科目上的得分,请绘制分组直方图将男女生放在一起对比他们各科目的得分情况。
SPL代码
A |
B |
|
1 |
=file("Hg_CData.csv").import@tc() |
|
2 |
=A1.(Subject+","+Gender) |
/科目,性别 |
3 |
=A1.(Score) |
/得分 |
4 |
[Men,Women] |
/性别 |
5 |
=canvas() |
/画布 |
6 |
=A5.plot("EnumAxis","name":"x","is3D":true) |
/x轴 |
7 |
=A5.plot("NumericAxis","name":"y","location":2,"is3D":true) |
/y轴 |
8 |
=A5.plot("Column","columnShape":2,"axis1":"x","data1":A2, "axis2":"y","data2":A3) |
/分组直方图 |
9 |
=A5.plot("Legend","name":"manager","legendText":A4) |
/图例 |
10 |
=A5.draw@p(600,400) |
/展示 |
可以看到对于这类数据,SPL在画直方图时,不需要对数据重新分组来作图,只要用柱图元来作图,填入相应的数据即可,非常便捷。另外想呈现出3D效果的柱子也很容易,只要将轴设置为3D,同时柱图元选择3D柱图元即可。
画图结果如下:
堆叠直方图
将上例的数据画成堆叠直方图。
SPL代码
A |
B |
|
1 |
=file("Hg_CData.csv").import@tc() |
|
2 |
=A1.(Subject+","+Gender) |
/科目,性别 |
3 |
=A1.(Score) |
/得分 |
4 |
[Men,Women] |
/性别 |
5 |
=canvas() |
/画布 |
6 |
=A5.plot("EnumAxis","name":"x") |
/x轴 |
7 |
=A5.plot("NumericAxis","name":"y","location":2) |
/y轴 |
8 |
=A5.plot("Column","stackType":2,"axis1":"x","data1":A2, "axis2":"y","data2":A3) |
/分组直方图 |
9 |
=A5.plot("Legend","name":"manager","legendText":A4) |
/图例 |
10 |
=A5.draw@p(600,400) |
/展示 |
SPL提供了主图元堆积选项,只要增加这一设置会自动堆叠,本例中是在A8中增加了stackType选项,值为2表示按原值堆叠。
画图结果如下:
饼图
假设有a,b,c,d四个类别,他们的占比分别是15%,30%,45%,10%,请画出饼图。
SPL代码
A |
B |
|
1 |
=canvas() |
/画布 |
2 |
[a,b,c,d] |
/X |
3 |
[15, 30, 45, 10] |
/Y |
4 |
=A1.plot("EnumAxis","name":"x","location":3) |
/极轴 |
5 |
=A1.plot("NumericAxis","name":"y","location":4) |
/角轴 |
6 |
=A1.plot("Sector","text":A3.(~/"%"),"axis1":"x","data1":A2, "axis2":"y","data2":A3) |
/饼图 |
7 |
=A1.draw@p(600,600) |
/展示 |
“location”:3是极轴,“location”:4是角轴。
画图结果如下:
嵌套饼图
假设已知连续3年内a,b,c,d四个类别的占比,请画饼图示意。
SPL代码
A |
B |
|
1 |
=canvas() |
/画布 |
2 |
[2019,2020,2021] |
|
3 |
[a,b,c,d] |
/类别 |
4 |
[15, 30, 45, 10] |
/2019 |
5 |
[23, 28, 32, 17] |
/2020 |
6 |
[18, 21, 51, 10] |
/2021 |
7 |
=[A4:A6].conj() |
/得分数据 |
8 |
=A2.((c=~,A3.([c,~].concat@c()))).conj() |
/极轴数据 |
9 |
=A1.plot("EnumAxis","name":"x","location":3) |
/极轴 |
10 |
=A1.plot("NumericAxis","name":"y","location":4) |
/角轴 |
11 |
=A1.plot("Sector","text":A7.(~/"%"),"axis1":"x","data1":A8, "axis2":"y","data2":A7) |
/饼图 |
12 |
=A1.plot("Legend","legendText":A3,"columns":1,"x":0.8,"y":0.2) |
/图例 |
13 |
=A1.draw@p(600,600) |
/展示 |
和分组直方图类似,只要把极轴数据组织成”年份,类别”的形式(如”2019,a”),角轴数据就是得分,与极轴数据一一对应即可,然后用环图元绘制即可,简单便捷。值得说明的是嵌套饼图中,SPL会自动引出每个饼图的标记,这里就是年份标记。
画图结果如下:
双纵坐标画图
横坐标x相同,绘制两条不同的曲线,这两条曲线分别用自己的纵坐标。
SPL代码
A |
B |
|
1 |
100 |
|
2 |
=canvas() |
/画布 |
3 |
=A1.(0.1*(#-1)) |
/x |
4 |
=A3.(0.05*~*~) |
/y1 |
5 |
=A4.(-~) |
/y2 |
6 |
=A2.plot("NumericAxis","name":"x","autoCalcValueRange":false, "autoRangeFromZero":false,"minValue":0) |
/横轴x |
7 |
=A2.plot("NumericAxis","name":"y1","location":2,"autoRangeFromZero":false) |
/左纵轴y1 |
8 |
=A2.plot("NumericAxis","name":"y2","location":2,"yPosition":0.8) |
/右纵轴y2 |
9 |
=A2.plot("Line","lineColor":-16776961, "markerColor":["ChartColor",0,false,-16776961,-16776961,0], "markerWeight":-1,"axis1":"x","data1":A3,"axis2":"y1","data2":A4) |
/y1曲线 |
10 |
=A2.plot("Line","lineColor":-16711936, "markerColor":["ChartColor",0,false,-16711936,-16776961,0], "markerWeight":-1,"axis1":"x","data1":A3,"axis2":"y2","data2":A5) |
/y2曲线 |
11 |
=A2.draw@p(600,400) |
/展示 |
A7、A8定义了两个纵轴y1、y2,与横轴x组成两个坐标系,A9,A10分别在相应的坐标系上画线。
画图结果如下:
多图合并展示
将上述中的散点图、曲线图、直方图、饼图合并显示在一张图上。
SPL代码
A |
B |
|
1 |
/区域1 |
|
2 |
=canvas() |
/画布 |
3 |
=100.(rand()) |
/X |
4 |
=100.(rand()) |
/Y |
5 |
=A2.plot("NumericAxis","name":"x1","autoCalcValueRange":false, "autoRangeFromZero":false,"maxValue":1.0, "xStart":0.1,"xEnd":0.45,"xPosition":0.45) |
/横轴 |
6 |
=A2.plot("NumericAxis","name":"y1","location":2, "autoCalcValueRange":false,"maxValue":1.0,"minValue":0, "yStart":0.45,"yEnd":0.1,"yPosition":0.1) |
/纵轴 |
7 |
=A2.plot("Dot","lineColor":-16776961, "markerColor":["ChartColor",0,false,-16776961,-16776961,0], "markerWeight":1,"axis1":"x1","data1":A3,"axis2":"y1","data2":A4) |
/散点 |
8 |
/区域2 |
|
9 |
200 |
|
10 |
=A9.(-10+0.1*(#-1)) |
/X |
11 |
=A10.(0.05*~*~) |
/Y |
12 |
=A2.plot("NumericAxis","name":"x2","autoCalcValueRange":false, "autoRangeFromZero":false,"minValue":-10, "xStart":0.55,"xEnd":0.9,"xPosition":0.45) |
/横轴 |
13 |
=A2.plot("NumericAxis","name":"y2","location":2, "autoRangeFromZero":false, "yStart":0.45,"yEnd":0.1,"yPosition":0.55) |
/纵轴 |
14 |
=A2.plot("Line","lineColor":-16776961, "markerColor":["ChartColor",0,false,-16776961,-16776961,0], "markerWeight":-1,"axis1":"x2","data1":A10,"axis2":"y2","data2":A11) |
/曲线 |
15 |
/区域3 |
|
16 |
12 |
|
17 |
=A16.(char(64+#)) |
/X |
18 |
=A17.(round(rand()*0.5+0.5,2)) |
/Y |
19 |
=A2.plot("EnumAxis","name":"x3","xStart":0.1,"xEnd":0.45,"xPosition":0.9) |
/横轴 |
20 |
=A2.plot("NumericAxis","name":"y3","location":2, "yStart":0.9,"yEnd":0.55,"yPosition":0.1) |
/纵轴 |
21 |
=A2.plot("Column","text":A18,"axis1":"x3","data1":A17,"axis2":"y3","data2":A18) |
/散点 |
22 |
=A2.draw@p(800,600) |
|
23 |
/区域4 |
|
24 |
=canvas() |
/画布 |
25 |
[a,b,c,d] |
/X |
26 |
[15, 30, 45, 10] |
/Y |
27 |
=A2.plot("EnumAxis","name":"x4","location":3, "polarX":0.69,"polarY":0.725,"polarLength":0.105) |
/极轴 |
28 |
=A2.plot("NumericAxis","name":"y4","location":4, "yStart":0.9,"yEnd":0.55,"yPosition":0.55) |
/角轴 |
29 |
=A2.plot("Sector","text":A26.(~/"%"),"axis1":"x4","data1":A25, "axis2":"y4","data2":A26) |
/饼图 |
30 |
=A2.draw@p(800,600) |
/展示 |
在一张画布A2上画不同图,只需要指定各图的轴的位置,包括横纵两个方向的起始和结束位置,然后再利用相应的轴画出需要的图。
画图结果如下:
SPL画图中图、热图、等高线图、3D图、动图时会很困难,有些在理论上是可以画出来的,比如热图、等高线图,但3D图和动图暂时是画不了的,所以这里就不再介绍这些图的画法了。
动图
动态的画出一条由点组成的线。
SPL代码
A |
B |
|
1 |
157 |
|
2 |
=to(A1) |
|
3 |
=canvas() |
/画布 |
4 |
=A1.(0.04*(#-1)) |
/X |
5 |
=A4.(sin(~)) |
/Y |
6 |
=A3.plot("NumericAxis","name":"x","autoCalcValueRange":false, "autoRangeFromZero":false,"maxValue":6.28) |
/横轴 |
7 |
=A3.plot("NumericAxis","name":"y","location":2,"autoRangeFromZero":false) |
/纵轴 |
8 |
=A3.plot("TimeAxis","name":"t","autoCalcValueRange":false, "beginTime":1,"endTime":A1) |
/时间轴 |
9 |
=A3.plot("dot","lineColor":-65536, "markerColor":["ChartColor",0,false,-65536,-16776961,0], "markerWeight":2,"axis1":"x","data1":A4, "axis2":"y","data2":A5,"axisTime":"t","dataTime":A2) |
/动点 |
10 |
=A3.draw@p(600,400) |
/展示 |
A8轴是时间轴,又来画动图
A9中需要设置时间轴axisTime和时间数据dataTime,其中时间数据既可以是数字也可以是时间。
查看动图时点击画布所在格,然后点击“图形浏览”按钮,就可以看到图像,如果要看动态过程,设置好帧数和帧数延时后,点击“播放”按钮即可。
画图结果如下:
小结
Python的两个画图库Matplotlib和seaborn画图功能很强大,常用的数据可视化功能都能覆盖,一些复杂的图形如等高线图、3D图等也可以完美呈现。不过它在某些方面做起来不太人性化,有些麻烦:
1. 绘制直方图时,不能自动判断直方的位置,需要手动修改业务数据;
2. 呈现3D直方图效果比较困难,需要利用3D模块来做,比较麻烦;
3. 分组直方图、堆叠直方图、嵌套饼图时需要手动来分组,分别绘制相应的图形,坐标、属性也需要手动来计算或者设置,比较麻烦,尤其是嵌套饼图的标记线,参数设置复杂程度远超饼图的绘制。
Python的这些困难,SPL都可以完美解决,因此在简单图形(如直方图、饼图)绘制方面,SPL呈现出来的图形更加美观,准确。当然SPL也有其不完善的方面,比如:
1. 一些复杂的图形不容易呈现,比如热图;
2. 还有些图像不能呈现,比如3D图;
另外值得一提的是SPL提供了编辑界面来辅助完成plot()参数的设置,可以很容易的知道该选择哪些参数,如何设置这些参数,大大提高了作图效率。
总而言之,Python在数学作图方面更全面,SPL在常用作图方面更方便。