在图表中绘制基本图形元素

本节介绍Excel提供的基本图形元素的创建,包括点、直线段、矩形、椭圆、多义线、多边形、贝塞尔曲线、标签、文本框、标注、自选图形、艺术字等。Excel对象模型中,用Shape对象表示图形,Shapes对象作为集合对所有图形进行保存和管理。通过编程创建图形的过程,就是创建Shape对象并利用它本身及与之相关的一系列对象的属性和方法进行编程的过程。[大谦Excel,dqexcel点com]

Excel图表中,点可以用点标记标示,1.2.1小节有介绍。除了点标记外,点还可以用自选图形表示。自选图形是Excel中预定义的很多不同形状的图形,如矩形、椭圆、圆、三角形、正多边形等都是一种自选图形。

Shapes对象没有提供专门用于绘制点的方法,但是它提供的自选图形里面有若干特殊的图形类型可以用来表示点,比如星形、矩形、圆形、菱形等,这些自选图形可以用Shapes对象的AddShape方法创建。该方法的语法格式为:

sht.api.Shapes.AddShape(Type, Left, Top, Width, Height)

采用的是xlwings包的API调用方式。sht表示一个工作表对象。该方法返回一个Shape对象,各参数的意义如表2-1所示。

表2-1 AddShape方法的参数说明

名 称 必需/可选 数据类型 说 明
Type 必需 MsoAutoShapeType 指定要创建的自选图形的类型
Left 必需 Single 自选图形边框左上角相对于文档左上角的位置 (以磅为单位)
Top 必需 Single 自选图形边框左上角相对于文档顶部的位置 (以磅为单位)
Width 必需 Single 自选图形边框的宽度(以磅为单位)
Height 必需 Single 自选图形边框的高度(以磅为单位)

其中,Type参数的值为msoAutoShapeType枚举类型,可以有很多的选择。表2-2中列出了一些星形点对应的常数和值。

表2-2 AddShape方法Type参数中星形点的取值

名 称 说 明
msoShape10pointStar 149 十角星
msoShape12pointStar 150 十二角星
msoShape16pointStar 94 十六角星
msoShape24pointStar 95 二十四角星
msoShape32pointStar 96 三十二角星
msoShape4pointStar 91 四角星
msoShape5pointStar 92 五角星
msoShape6pointStar 147 六角星

下面在坐标系中创建一个五角星、一个三十二角星和一个棱形表示的点。完整代码见:Samples->ch05 创建新图表->11 在图表中绘制点->py.py。

code.python
root=os.getcwd()    #获取当前工作路径
app=xw.App(visible=True,add_book=False)    #创建Excel应用
wb=app.books.open(root+r'/data.xlsx',read_only=False)    #打开数据文件返回工作簿对象
sht=wb.sheets('Sheet1')    #获取指定工作表对象
#sht.api.Range('A1:B7').Select()    #数据
shp=sht.api.Shapes.AddChart2()    #创建空白图表
shp.Left=20
cht=shp.Chart    #获取图表
cht.ChartType=xw.constants.ChartType.xlXYScatter    #图表类型为散点图
ax1=cht.Axes(1)    #获取横轴
ax2=cht.Axes(2)    #获取纵轴
ax1.MinimumScale=0    #横轴最小值
ax1.MaximumScale=7
ax2.MinimumScale=0    #纵轴最小值.05
ax2.MaximumScale=0.35
set_style(cht)    #设置样式
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,2)
y=shape_y(cht,0.15)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*0.2
h=w
cht.Shapes.AddShape(92,x,y,w,h)    #五角星
x=shape_x(cht,3.5)
y=shape_y(cht,0.25)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*0.2
h=w
cht.Shapes.AddShape(150,x,y,w,h)    #32角星
x=shape_x(cht,6)
y=shape_y(cht,0.2)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*0.2
h=w
cht.Shapes.AddShape(4,x,y,w,h)    #棱形

运行代码生成图2-13。

Document Image
\[\]

图2-13 创建点

直线段

用Excel和Python xlwings可以在图表中绘制直线段。

用Shapes对象的AddLine方法创建直线段。该方法的语法格式为:

sht.api.Shapes.AddLine(BeginX, BeginY, EndX, EndY)

其中,sht表示一个工作表对象。参数BeginX, BeginY表示起点的横坐标和纵坐标,EndX, EndY表示终点的横坐标和纵坐标。该方法返回一个表示直线段的Shape对象。

下面在坐标系中添加一组直线段,各直线段有不同的颜色、线型和线宽等属性。完整代码见:Samples->ch05 创建新图表->12 在图表中绘制直线段->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,1)
y=shape_y(cht,0.12)
x2=shape_x(cht,6)
y2=shape_y(cht,0.17)
shp2=cht.Shapes.AddLine(x,y,x2,y2)    #在图表上添加直线段
shp2.Line.DashStyle=1    #msoLineSolid 线型
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))    #颜色
shp2.Line.Weight=2    #线宽
x=shape_x(cht,1)
y=shape_y(cht,0.17)
x2=shape_x(cht,6)
y2=shape_y(cht,0.22)
shp2=cht.Shapes.AddLine(x,y,x2,y2)    #在图表上添加直线段
shp2.Line.DashStyle=3    #msoLineDash
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((0,255,0))
shp2.Line.Weight=2
x=shape_x(cht,1)
y=shape_y(cht,0.22)
x2=shape_x(cht,6)
y2=shape_y(cht,0.27)
shp2=cht.Shapes.AddLine(x,y,x2,y2)    #在图表上添加直线段
shp2.Line.DashStyle=4    #msoLineDashDotDot
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((255,0,0))
shp2.Line.Weight=3

运行代码生成图2-14。

Document Image
\[\]

图2-14 创建直线段

可以给直线段两端添加箭头。LineFormat对象跟箭头有关的属性包括:

• BeginArrowheadLength属性:设置或获取起点处箭头的长度。

• BeginArrowheadStyle属性:设置或获取起点处箭头的样式。

• BeginArrowheadWidth属性:设置或获取起点处箭头的宽度。

• EndArrowheadLength属性:设置或获取终点处箭头的长度。

• EndArrowheadStyle属性:设置或获取终点处箭头的样式。

• EndArrowheadWidth属性:设置或获取终点处箭头的宽度。

其中,箭头的长度有3个取值,用1, 2和3表示短、中和长。箭头的宽度也有3个取值,用1, 2和3表示窄、中和宽。箭头样式的设置可以从表2-3中取值。

表2-3 箭头的样式

名 称 说 明
msoArrowheadDiamond 5 菱形
msoArrowheadNone 1 无箭头
msoArrowheadOpen 3 打开
msoArrowheadOval 6 椭圆形
msoArrowheadStealth 4 隐匿形状
msoArrowheadStyleMixed -2 只返回值,表示其他状态的组合
msoArrowheadTriangle 2 三角形

下面假设shp是图表中添加的一条两端有箭头的直线段,给直线段两端添加箭头。

code.python
lf=shp.Line    #获取线形对象
lf.Weight=2    #线宽
lf.BeginArrowheadLength=1    #起点处箭头长度
lf.BeginArrowheadStyle=6    #起点处箭头样式
lf.BeginArrowheadWidth=1    #起点处箭头宽度
lf.EndArrowheadLength=3    #终点处箭头长度
lf.EndArrowheadStyle=2    #终点处箭头样式
lf.EndArrowheadWidth=3    #终点处箭头宽度

用LineFormat对象的Transparency属性设置或获取线条的透明性,取值范围为0.0(不透明)到1.0(清晰)之间。

矩形、圆角矩形、椭圆和圆

用Excel和Python xlwings可以在图表中绘制矩形、圆角矩形、椭圆、圆及其对应的区域。

用Shapes对象的AddShape方法创建矩形、圆角矩形、椭圆和圆。该方法在2.1.1小节进行了介绍,实际上是通过创建自选图形的方法来创建。该方法跟以上几种图形有关的Type参数取值如表2-4所示。其中,圆是特殊的椭圆,即横轴和纵轴相等的椭圆。

表2-4 AddShape方法相关的Type参数取值

名 称 说 明
msoShapeRectangle 1 矩形
msoShapeRoundedRectangle 5 圆角矩形
msoShapeOval 9 椭圆形

默认时生成的矩形和圆都是实心的,是矩形面和圆形面。设置它们的Fill属性返回对象的Visible属性的值为False,可以生成线形的矩形和圆。

本例向坐标系中添加矩形、圆角矩形、椭圆和圆,皆为实心的面。完整代码见:Samples->ch05 创建新图表->13 在图表中绘制矩形和椭圆->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,50)
y=shape_y(cht,250)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
cht.Shapes.AddShape(1,x,y,w,h)     #矩形区域
x=shape_x(cht,100)
y=shape_y(cht,300)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
cht.Shapes.AddShape(5,x,y,w,h)     #圆角矩形区域
x=shape_x(cht,150)
y=shape_y(cht,350)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
cht.Shapes.AddShape(9,x,y,w,h)     #椭圆区域
x=shape_x(cht,200)
y=shape_y(cht,300)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
cht.Shapes.AddShape(9,x,y,w,h)     #圆区域

运行代码生成图2-15。

Document Image
\[\]

图2-15 创建矩形、圆角矩形、椭圆和圆形面

下面在坐标系中创建没有填充的线形的矩形、圆角矩形、椭圆和圆。完整代码见:Samples->ch05 创建新图表->14 在图表中绘制矩形和椭圆2->py.py。

code.python
#... 省略部分代码
x=shape_x(cht,50)
y=shape_y(cht,250)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
shp2=cht.Shapes.AddShape(1,x,y,w,h)     #矩形区域
x=shape_x(cht,100)
y=shape_y(cht,300)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
shp3=cht.Shapes.AddShape(5,x,y,w,h)     #圆角矩形区域
x=shape_x(cht,150)
y=shape_y(cht,350)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
shp4=cht.Shapes.AddShape(9,x,y,w,h)     #椭圆区域
x=shape_x(cht,200)
y=shape_y(cht,300)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
shp5=cht.Shapes.AddShape(9,x,y,w,h)     #圆区域
shp2.Fill.Visible=False    #隐藏区域
shp3.Fill.Visible=False
shp4.Fill.Visible=False
shp5.Fill.Visible=False

运行代码生成图2-16。

Document Image
\[\]

图2-16 矩形、圆角矩形、椭圆和圆形线

多义线和多边形

用Excel和Python xlwings可以在图表中绘制多义线和多边形。用计算机绘制曲线时,本质上是用多义线逼近曲线。多义线的起点和终点重合时构成多边形,可以对多边形进行填充,构成多边形面。

使用Shapes对象的AddPolyline方法创建多义线和多边形。该方法的语法格式为:

code.python
sht.api.Shapes.AddPolyline(SafeArrayOfPoints)

其中,sht表示一个工作表对象。参数SafeArrayOfPoints指定多义线或多边形的顶点坐标。该方法返回一个表示多义线或多边形的Shape对象。

各顶点用其横坐标和纵坐标对表示,全部顶点用一个二维列表表示,例如:

code.python
pts=[[10,10],[20,30],[30,50],[50,80],[10,10]]

然后用Shapes对象的AddPolyline方法创建多边形:

code.python
sht.api.Shapes.AddPolyline(pts)

结果返回下面的出错信息:

code.python
pywintypes.com_error: (-2147352567, '发生意外。', (0, None, '指定参数的数据类型不正确。', None, 0, -2146827284), None)

可见,使用xlwings绘制多义线和多边形存在问题。出现该问题的原因在于,VBA中要求顶点坐标的数据类型必须时Single型,即单精度浮点型,但Python中不区分单精度浮点型和双精度浮点型,无法与该数据类型精确对应,出错了。

经过反复试验后,使用另一个Python包comtypes来实现多边形的绘制。该包跟Win32COM和xlwings类似,都是基于COM机制。

首先,在DOS命令窗口,用pip命令安装comtypes包:

pip install comtypes

然后编写以下Python代码:

code.python
from comtypes.client import CreateObject    #导入ComTypes包
app2=CreateObject("Excel.Application")    #创建Excel应用
app2.Visible=True    #应用窗口可见
bk2=app2.Workbooks.Add()    #添加工作簿
sht2=bk2.Sheets(1)    #获取第1个工作表
pts=[[10,10], [50,150],[90,80], [70,30], [10,10]]    #多边形顶点
sht2.Shapes.AddPolyline(pts)    #添加多边形区域

运行代码可以在工作表中成功生成多边形面。

本例向坐标系中添加一个四边形。 由于起点和终点的坐标相同,因此,该四边形既是闭合的又是填充的。完整代码见:Samples->ch05 创建新图表->15 在图表中绘制多义线和多边形->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp=cht.Shapes.AddPolyline(pts)

运行代码生成图2-17所示的多边形区域。

Document Image
\[\]

图2-17 多边形面

如果只生成多边形线条,设置表示多边形区域的Shape对象的Fill属性返回对象的Visible属性的值为False。完整代码见:Samples->ch05 创建新图表->16 在图表中绘制多义线和多边形2->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp=cht.Shapes.AddPolyline(pts)
shp.Fill.Visible=False    #多边形面隐藏

运行代码生成图2-18。

Document Image
\[\]

图2-18 多边形线

多边形面的着色,主要有单色填充、渐变色填充、图案填充、图片填充和纹理填充等几种方式。前面已经介绍了单色填充,接下来介绍剩下的几种填充方式。

本例向坐标系中添加一个多边形,多边形的面用兰色和白色垂向渐变填充,多边形的边为黑色。完整代码见:Samples->ch05 创建新图表->17 渐变色填充多边形->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp2=cht.Shapes.AddPolyline(pts)    #在图表中添加多边形
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))    #单色渐变色填充
shp2.Fill.OneColorGradient(1,1,1)

运行代码生成图2-19所示。

Document Image
\[\]

图2-19 多边形的单色渐变填充

本例向坐标系中添加一个多边形,并对多边形进行多色渐变填充。完整代码见:Samples->ch05 创建新图表->18 渐变色填充多边形2->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
#多色渐变色填充多边形面
shp2=cht.Shapes.AddPolyline(pts)
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))
shp2.Fill.OneColorGradient(1,1,1)
shp2.Fill.GradientStops.Insert(xw.utils.rgb_to_int((0,255,0)),0.5)
shp2.Fill.GradientStops.Delete(2)
shp2.Fill.GradientStops.Insert(xw.utils.rgb_to_int((255,0,0)),1)

运行代码生成图2-20。

Document Image
\[\]

图2-20 多边形的多色渐变填充

本例向坐标系中添加多边形并对多边形进行图案填充。完整代码见:Samples->ch05 创建新图表->19 多边形的其他填充效果->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp2=cht.Shapes.AddPolyline(pts)    #在图表中添加多边形
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))
shp2.Fill.Patterned(20)    #图案填充

运行代码生成图2-21。

Document Image
\[\]

图2-21 多边形的图案填充

本例向坐标系中添加一个多边形并对多边形进行图片填充。完整代码见:Samples->ch05 创建新图表->20 多边形的其他填充效果2->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp2=cht.Shapes.AddPolyline(pts)    #在图表中添加多边形
shp2.Fill.UserPicture('d:/pic.jpg')    #图片填充

运行代码生成图2-22。

Document Image
\[\]

图2-22 多边形的图片填充

多边形边的着色

引用Shape对象的Line属性可以获取多边形的边线,设置其属性可以修改边线的颜色、线型和线宽等。

本例向坐标系中添加一个多边形,设置边线为红色虚线,线宽为2。完整代码见:Samples->ch05 创建新图表->21 多边形边的着色->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp2=cht.Shapes.AddPolyline(pts)    #在图表中添加多边形
#设置多边形面的属性
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))
shp2.Fill.Transparency=0.5
#设置多边形边线的属性
shp2.Line.Weight=2
shp2.Line.DashStyle=1
shp2.Line.ForeColor.RGB=xw.utils.rgb_to_int((255,0,0))

运行代码生成图2-23。

Document Image
\[\]

图2-23 设置边线属性

设置边线对象的Visible属性值为False,可以隐藏多边形的边线。本例向坐标系中添加一个多边形并隐藏多边形的边线。完整代码见:Samples->ch05 创建新图表->22 多边形边的着色2->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,10),shape_y(cht,10)],
     [shape_x(cht,50),shape_y(cht,150)],
     [shape_x(cht,90),shape_y(cht,80)],
     [shape_x(cht,70),shape_y(cht,30)],
     [shape_x(cht,10),shape_y(cht,10)]]    #多边形顶点
shp2=cht.Shapes.AddPolyline(pts)
shp2.Fill.ForeColor.RGB=xw.utils.rgb_to_int((0,0,255))
shp2.Fill.Transparency=0.5
#隐藏多边形的边线
shp2.Line.Visible=False

运行代码生成成图2-24。

Document Image
\[\]

图2-24 隐藏多边形的边线

曲线

用Excel和Python xlwings可以在图表中绘制贝塞尔曲线。

用Shapes对象的AddCurve方法创建曲线。该方法的语法格式为:

code.python
sht.api.Shapes.AddCurve(SafeArrayOfPoints)

其中,sht表示一个工作表对象。参数SafeArrayOfPoints指定贝塞尔曲线顶点和控制点的坐标。指定的点数始终为3n + 1,其中n为曲线的线段条数。该方法返回一个表示贝塞尔曲线的Shape对象。

各顶点用其横坐标和纵坐标对表示,全部顶点用一个二维列表表示,例如:

code.python
pts=[[0,0],[72,72],[100,40],[20,50],[90,120],[60,30],[150,90]]

下面的示例向坐标系中添加贝塞尔曲线。完整代码见:Samples->ch05 创建新图表->23 在图表中绘制曲线->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
pts=[[shape_x(cht,0),shape_y(cht,0)],
     [shape_x(cht,72),shape_y(cht,72)],
     [shape_x(cht,100),shape_y(cht,40)],
     [shape_x(cht,20),shape_y(cht,50)],
     [shape_x(cht,90),shape_y(cht,120)],
     [shape_x(cht,60),shape_y(cht,30)],
     [shape_x(cht,150),shape_y(cht,90)]]    #顶点
shp=cht.Shapes.AddCurve(pts)    #在图表中添加曲线

运行代码生成图2-25所示的贝塞尔曲线。

Document Image
\[\]

图2-25 贝塞尔曲线

标签

用Excel和Python xlwings可以在图表中绘制标签。

使用Shapes对象的AddLabel方法创建标签。该方法的语法格式为:

code.python
sht.api.Shapes.AddLabel(Orientation,Left,Top,Width,Height)

其中,sht表示一个工作表对象。各参数的说明如表2-5所示。该方法返回一个表示标签的Shape对象。

表2-5 AddLabel方法各参数的说明

名 称 必需/可选 数据类型 说 明
Orientation 必需 msoTextOrientation 标签中文本的方向
Left 必需 Single 标签左上角相对于文档左上角的位置 (以磅为单位)
Top 必需 Single 标签左上角相对于文档顶部的位置 (以磅为单位)
Width 必需 Single 标签的宽度(以磅为单位)
Height 必需 Single 标签的高度(以磅为单位)

Orientation参数表示标签中文本的方向,其取值如表2-6所示。

表2-6 Orientation参数的取值

名 称 说 明
msoTextOrientationDownward 3 朝下
msoTextOrientationHorizontal 1 水平
msoTextOrientationHorizontalRotatedFarEast 6 亚洲语言支持所需的水平和旋转
msoTextOrientationMixed -2 不支持
msoTextOrientationUpward 2 朝上
msoTextOrientationVertical 5 垂直
msoTextOrientationVerticalFarEast 4 亚洲语言支持所需的垂直

本示例向坐标系中添加一个标签。完整代码见:Samples->ch05 创建新图表->24 在图表中绘制标签->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,60)
y=shape_y(cht,120)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*150
shp2=cht.Shapes.AddLabel(1,x,y,w,h)   #添加标签
shp2.TextFrame.Characters().Text='Test Label'   #标签文本
shp2.TextFrame.Characters().Font.Color=xw.utils.rgb_to_int((255,0,0))
shp2.TextFrame.Characters().Font.Size=20

运行代码生成图2-26所示的标签。

Document Image
\[\]

图2-26 生成标签

文本框

用Excel和Python xlwings可以在图表中绘制文本框。文本框与标签的区别在于文本框可以指定文本框内的文本在文本框内进行排版。

用Shapes对象的AddTextbox方法生成文本框。该方法的调用格式和各参数的意义跟AddLabel方法的相同。

本示例向坐标系中添加包含文本的文本框。完整代码见:Samples->ch05 创建新图表->25 在图表中绘制文本框->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,40)
y=shape_y(cht,40)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*40
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*10
shp2=cht.Shapes.AddTextbox(1,x,y,w,h)   #添加文本框
shp2.TextFrame2.TextRange.Text="Test Box"
shp2.TextFrame2.TextRange.Font.Size=16
shp2.TextFrame2.TextRange.Font.Italic=True

运行代码生成图2-27所示的文本框。

Document Image
\[\]

图2-27 文本框

标注

用Excel和Python xlwings可以在图表中添加一定样式的标注。

用Shapes对象的AddCallout方法添加标注。该方法的语法格式为:

code.python
sht.api.Shapes.AddCallout(Type,Left,Top,Width,Height)

其中,sht表示一个工作表对象。各参数的说明如表2-6所示。该方法返回一个表示标注的Shape对象。

表2-7 AddCallout方法的参数设置

名称 必需/可选 数据类型 说 明
Type 必需 MsoCalloutType 标注线的类型
Left 必需 Single 标注边界框左上角相对于文档左上角的位置 (以磅为单位)
Top 必需 Single 标注边界框左上角相对于文档顶部的位置 (以磅为单位)
Width 必需 Single 标注边框的宽度(以磅为单位)
Height 必需 Single 标注边框的高度(以磅为单位)

Type参数的取值为MsoCalloutType枚举类型的值,如表2-7中所示,指定标注线的类型。

表2-8 AddCallout方法Type参数的取值

名 称 说 明
msoCalloutFour 4 由两条线段组成的标注线。 标注线附加在文本边界框的右侧
msoCalloutMixed -2 只返回值,表示其他状态的组合
msoCalloutOne 1 单线段水平标注线
msoCalloutThree 3 由两条线段组成的标注线。 标注线连接在文本边界框的左侧
msoCalloutTwo 2 单线段倾斜标注线

本示例向坐标系中添加包含文本的标注。完整代码见:Samples->ch05 创建新图表->26 在图表中绘制标注->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,40)
y=shape_y(cht,40)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*40
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*10
shp2=cht.Shapes.AddCallout(2,x,y,w,h)    #在图表上添加标注
shp2.TextFrame2.TextRange.Text='Test Box'    #标注的内容

运行代码生成图2-28所示的标注框。

Document Image
\[\]

图2-28 标注

下面设置shp对象的Callout属性,创建不同的标注样式。完整代码见:Samples->ch05 创建新图表->27 在图表中绘制标注2->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,110)
y=shape_y(cht,100)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*50
shp2=cht.Shapes.AddCallout(2,x,y,w,h)    #在图表上添加标注2
shp2.TextFrame2.TextRange.Text='Test Box'    #标注2的文本
shp2.Callout.Accent=True
shp2.Callout.Border=True
shp2.Callout.Angle=2

运行代码生成图2-29。代码中Accent属性设置引线左侧的竖线,Border属性设置标注区域的外框,Angle属性设置引线的角度,这里设置为30度。

Document Image
\[\]

图2-29 设置标注对象的属性

自选图形

用Excel和Python xlwings可以在图表中绘制自选图形。实际上,前面介绍的矩形和圆等都是自选图形。

所谓自选图形,是Excel预定义好的很多图形对象。使用Shapes对象的AddShape方法创建自选图形。前面我们用该方法创建了点、矩形、椭圆等图形。实际上,还有很多其他的图形类型,如表2-9中所示。

表2-9 部分自选图形

名 称 说 明
msoShapeOval 9 椭圆形
msoShapeOvalCallout 107 椭圆形标注
msoShapeParallelogram 12 斜平行四边形
msoShapePie 142 圆形 ("饼图"), 缺少部分
msoShapeQuadArrow 39 指向向上、向下、向左和向右的箭头
msoShapeQuadArrowCallout 59 带向上、向下、向左和向右的箭头的标注
msoShapeRectangle 1 矩形
msoShapeRectangularCallout 105 矩形标注
msoShapeRightArrow 33 右箭头
msoShapeRightArrowCallout 53 带右箭头的标注
msoShapeRightBrace 32 右大括号
msoShapeRightBracket 30 右小括号
msoShapeRightTriangle utf-8 直角三角形
msoShapeRound1Rectangle 151 有一个圆角的矩形
msoShapeRound2DiagRectangle 157 有两个圆角的矩形, 对角相对
msoShapeRound2SameRectangle 152 具有两个圆角的矩形, 共一侧
msoShapeRoundedRectangle 5 圆角矩形
msoShapeRoundedRectangularCallout 106 圆角矩形-形状标注
……

下面的例子向坐标系中添加矩形、平行四边形和一个笑脸图形。完整代码见:Samples->ch05 创建新图表->28 在图表中绘制自选图形->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,50)
y=shape_y(cht,250)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*200
cht.Shapes.AddShape(1,x,y,w,h)    #在图表上添加自选图形
x=shape_x(cht,250)
y=shape_y(cht,150)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
cht.Shapes.AddShape(12,x,y,w,h)    #在图表上添加自选图形
x=shape_x(cht,450)
y=shape_y(cht,150)
w=cht.PlotArea.InsideWidth/(ax1.MaximumScale-ax1.MinimumScale)*100
h=cht.PlotArea.InsideHeight/(ax2.MaximumScale-ax2.MinimumScale)*100
cht.Shapes.AddShape(17,x,y,w,h)    #在图表上添加自选图形

运行代码生成图2-30。

Document Image
\[\]

图2-30 生成自选图形

艺术字

用Excel和Python xlwings可以在图表中绘制艺术字。

用Shapes对象的AddTextEffect方法创建艺术字。该方法的语法格式为:

code.python
sht.api.Shapes.AddTextEffect(PresetTextEffect,Text,FontName,FontSize,FontBold,FontItalic, Left, Top)

其中,sht为当前工作表,各参数的意义如表2-10中所示。

表2-10 AddTextEffect方法的参数

名 称 必需/可选 数据类型 说 明
PresetTextEffect 必需 MsoPresetTextEffect 预置文字效果
Text 必需 String 艺术字中的文字
FontName 必需 String 艺术字中所用字体的名称
FontSize 必需 Single 在艺术字中使用的字体的大小 (以磅为单位)
FontBold 必需 MsoTriState 在艺术字中要加粗的字体
FontItalic 必需 MsoTriState 在艺术字中要倾斜的字体
Left 必需 Single 左上角点的横坐标
Top 必需 Single 左上角点的纵坐标

PresetTextEffect参数表示艺术字的效果。Excel预置了约50种效果,表2-11中列出了少部分。设置时给PresetTextEffect参数赋对应的值即可。

表2-11 PresetTextEffect参数的取值

名 称 说 明
msoTextEffect1 0 第一个文本效果
msoTextEffect2 1 第二个文本效果
msoTextEffect3 2 第三个文本效果
……

下面向坐标系中添加两种不同效果的艺术字。完整代码见:Samples->ch05 创建新图表->29 在图表中绘制艺术字->py.py。

code.python
#... 省略部分代码
cht.SeriesCollection().NewSeries()    #新建序列
x=shape_x(cht,10)
y=shape_y(cht,55)
cht.Shapes.AddTextEffect(19,'科研绘图','Arial Black', 36,False,False,x,y)    #在图表上添加艺术字
x=shape_x(cht,20)
y=shape_y(cht,95)
cht.Shapes.AddTextEffect(25, '春眠不觉晓','黑体',40,False,False,x,y)

运行代码生成图2-31。

Document Image
\[\]

图2-31 艺术字