Python 和 SPL 对比 14——数据可视化

数据分析过程中,数据可视化可以帮我们更好的感知数据,从而采用更好的策略来处理数据,本文就来对比一下 Python SPL 在数据可视化方面的情况

Python

Python常用的两个画图库是MatplotlibseabornMatplotlib以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过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坐标

散点图

横坐标范围

纵坐标范围

展示

Pythonmatplotlib 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表示22列画布的第一个位置,剩下的只要在对应的位置画图即可。

画图结果如下:

..

动图

动态的画出一条由点组成的线。

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

初始化

更新

作图

展示

animationmatplotlib库中绘制动图的模块,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范围内的10Dataframe,并以此为依据画出热图。

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用如下公式计算:

..

其中xy分别是-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.mplot3dMatplotlib里面专门用来画三维图的工具包,Axes3Dmpl_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()函数用来作图,其中A5A6A7分别画出横轴、纵轴、和散点,它们的区别是plot()函数的内容不同,如:A5A6是画坐标轴NumericAxisA7画散点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格的参数中增加categoriesSPL就可以自动找到各类别在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)

/展示

A7A8定义了两个纵轴y1y2,与横轴x组成两个坐标系,A9A10分别在相应的坐标系上画线。

画图结果如下:

..

多图合并展示

将上述中的散点图、曲线图、直方图、饼图合并显示在一张图上。

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的两个画图库Matplotlibseaborn画图功能很强大,常用的数据可视化功能都能覆盖,一些复杂的图形如等高线图、3D图等也可以完美呈现。不过它在某些方面做起来不太人性化,有些麻烦:

1. 绘制直方图时,不能自动判断直方的位置,需要手动修改业务数据;

2. 呈现3D直方图效果比较困难,需要利用3D模块来做,比较麻烦;

3. 分组直方图、堆叠直方图、嵌套饼图时需要手动来分组,分别绘制相应的图形,坐标、属性也需要手动来计算或者设置,比较麻烦,尤其是嵌套饼图的标记线,参数设置复杂程度远超饼图的绘制。

Python的这些困难,SPL都可以完美解决,因此在简单图形(如直方图、饼图)绘制方面,SPL呈现出来的图形更加美观,准确。当然SPL也有其不完善的方面,比如:

1. 一些复杂的图形不容易呈现,比如热图;

2. 还有些图像不能呈现,比如3D图;

另外值得一提的是SPL提供了编辑界面来辅助完成plot()参数的设置,可以很容易的知道该选择哪些参数,如何设置这些参数,大大提高了作图效率。

总而言之,Python在数学作图方面更全面,SPL在常用作图方面更方便。