前几个绘制折线的例子其实绘制的都是含有突出点的折线,也就是提供点数据的点在图中都会有一个较大的圆点来表示,虽然点的大小可以控制,但还是有突出的点;而点之间都是有连线来连接的。本节将介绍直接绘制不含突出点的折线以及仅绘制离散的点而不带连接线段的图。
package main
import (
"image/color"
"math"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/vg"
)
func main() {
//设置所绘制的每个数据点的默认大小
plotter.DefaultGlyphStyle.Radius =vg.Points(2.0)
//新建一张图表
p, _ := plot.New()
//设置图表标题与X、Y轴说明文字
p.Title.Text = "Lines and Points"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"
// 设置Y轴的数值范围
p.Y.Max = 4.0
p.Y.Min = -2.0
//手动设置Y轴上显示的各个参考点数值及其显示字符串
p.Y.Tick.Marker =plot.ConstantTicks([]plot.Tick{{-2.0, "-2 (Min)"}, {-1.0,""}, {0, "0"}, {1.0, ""}, {2.0, "2"},{3.0, ""}, {4.0, "4 (Max)"}})
//手动建立第一条折线的数据,共包含3个点
points1 := plotter.XYs{
{X: -8.0, Y:2.0},
{X: 1.0, Y:2.5},
{X: 7.0, Y:4.0},
}
//设置画线(不包含突出的点)使用的颜色
plotter.DefaultLineStyle.Color= color.RGBA{R: 0x00, G: 0, B: 0xFF, A: 0xFF}
// 新建一条不含突出点的折线
line1, _ := plotter.NewLine(points1)
//为第二条(Sin函数)曲线分配1000点容量的空间
points2 := make(plotter.XYs, 0, 1000)
//循环获取每个x点的Sin函数值
for x := -10.0; x <= 10.0; x = x + 0.1 {
y := math.Sin(x)
points2 = append(points2, plotter.XY{X:x, Y: y})
}
//为第三条(Cos函数)曲线分配1000点容量的空间
points3 := make(plotter.XYs, 0, 1000)
//循环获取每个x点的Cos函数值
for x := -10.0; x <= 10.0; x = x + 0.1 {
y := math.Cos(x)
points3 = append(points3, plotter.XY{X:x, Y: y})
}
//设置画Sin函数散点图的颜色
plotter.DefaultGlyphStyle.Color =color.RGBA{R: 0xFF, G: 0, B: 0, A: 0xFF}
//新建Sin函数的散点图
scatter1, _ := plotter.NewScatter(points2)
//设置画Cos函数散点图的颜色
plotter.DefaultGlyphStyle.Color =color.RGBA{R: 0, G: 0xFF, B: 0, A: 0xFF}
//新建Cos函数的散点图
scatter2, _ := plotter.NewScatter(points3)
//在图表中加入一条折线与两个散点的线
p.Add(scatter1, scatter2, line1)
//增加图例说明
p.Legend.Add("line1", line1)
p.Legend.Add("points2", scatter1)
p.Legend.Add("points3", scatter2)
//保存图表到图片文件
p.Save(8*vg.Inch, 8*vg.Inch,"points.png")
}
代码 5‑49 绘制不含突出点的折线与不含连线的离散点图
代码5‑49执行后绘制的图表如下所示,
图 5.10 不含突出点的折线与不含连线的离散点图
* 注:本系列文章中的代码,一般可以在https://github.com/topxeq/goexamples中找到,本例可参考其中的plot3代码。
代码5‑49中也添加了很多注释,我们还是择其要点说明如下:
-> 本例中通过给p.Y.Max和p.Y.Min赋值,可以控制Y轴显示数据的范围;X轴的范围也可用类似的方法来控制;如果不进行手工控制,各个坐标轴的范围会自动控制在有效数据的范围区间内;如果希望显示更大的范围,则需要手动来设置;
-> 通过设置 p.Y.Tick.Marker可以控制坐标轴上显示多少个标记点(tick)以及各个标记点的数值和显示方式。注意赋值是用plot.ConstantTicks函数中传入[]plot.Tick类型(即plot.Tick类型的切片)的数据,其中的每个数据项(plot.Tick类型)有两个值,第一个浮点数代表该标记点的数值,第二个字符串表示显示方式,如果是空字符串则代表只显示一个小短横线;
-> 给plotter.DefaultLineStyle.Color赋值可以控制默认绘制折线的颜色;color.RGBA{R: 0x00, G: 0, B: 0xFF, A: 0xFF}则是用RGB色彩空间加上表示透明度的Alpha通道供4个数值来表示颜色,color.RGBA是在color包中定义的数据结构,因此需要引用color包;0xFF这样的数据是十进制数字255的16进制形式,在计算机编程中有不少开发者习惯用16进制形式表示颜色数据;其中各个值的范围都是0x00至0xFF(0-255),其中Alpha通道值越小透明度越高;
-> plotter.NewLine函数即用于新建一条不含突出点的折线的函数;
-> points2、points3分别代表Sin、Cos数学函数表示的点序列;
-> plotter.NewScatter函数用于新建一个仅含离散点而不包括连线的点序列(也可以看成一条虚拟的折线);
-> p.Add(scatter1, scatter2, line1) 这条语句将scatter1、scatter2两个离散点序列和line1这条折线先后加入图表p中,注意这种方式与使用plotutil.AddLinePoints的异同,这种方式不会加入图例(legend),需要手动加入图例;
-> 增加图例用的是plot.Legend.Add函数,其中第一个参数是显示的图例名称,第二个参数是图例表示的折线或离散点序列的变量。
* 注意我们在描述增加图例中使用成员函数的叙述方式,我们说“增加图例用的是plot.Legend.Add函数”,但实际上代码5‑49中的代码是 p.Legend.Add("line1", line1) 等。这是因为,变量p是plot类型的变量(用面向对象的思维来说p就是plot类的一个实例),p.Legend.Add这种调用方式表示在plot类型的变量实例上调用其Legend类型的Add成员函数,该函数也将在变量p上起作用,也就是会将图例加在变量p表示的图表上面。而叙述中为了统一,会使用变量所属的类型来表示,即类似“plot.Legend.Add函数”的说法。有时候为了简化,在一定上下文环境中还会省略包名,说成“Legend.Add函数”。这也是开发文档中常用的描述方式,请理解这种描述方式。
观察图5.10显示的执行结果可以看出,其中上方蓝色的折线即是line1所表示的不含突出点的折线;下方两条红色和绿色的离散点组成的曲线则分别是Sin和Cos的离散点序列;这也说明,在调用plotter.NewScatter和plotter.NewLine之前对plotter.DefaultGlyphStyle.Color和plotter.DefaultLineStyle.Color赋值,可以改变各条折线或离散点序列的颜色。