柱状图常用来比较各组数据之间的差别。例如:每季度不同类别商品的销售金额对比图。本节我们就来实践一下。
问题
现有某市洁雅超市2021年第一季度的销售数据,如表所示(单位为万元):
商品类别 | 1 月销售金额 | 2月销售金额 | 3月销售金额 |
---|---|---|---|
文具类 | 5 | 12 | 7 |
食品类 | 45 | 48 | 42 |
日化类 | 18 | 24 | 28 |
其它类 | 10 | 6 | 15 |
现要求绘制柱状图用于分析3个月的销售数据,不同各类的商品用不同颜色表示。
分析
从上一节课我们已经学习了如何构造自己的坐标系,并把实际数据转换到我们自己构造的坐标系中,那么绘制柱状图要解决的问题就是怎么画出一个个不同高度的“柱子”(也就是矩形)来代表数据,毕竟它不像是折线图那样只要角色走过去留下轨迹这么简单。怎么办呢?Scratch并没有提供画实心图形的方法,那么我们就得变通一下,就许多条线来“堆积”成“柱子”。具体如下图所示:
假设我们已经画出了图上所示的坐标系,那么这个坐标左下角坐标是 (X1,Y1),柱子的“高度”可以用把对应数据转换成坐标 Y 后,用 Y – Y1 计算出来。然后我们从下面 Y1 高度开始,循环向上画横线,先从左向右,再将 Y 坐标加1后掉头转180度从右向左,如此反复画线,重复的次数正好等于计算出来的柱子“高度” Y-Y1。
那么每个柱子起点的X坐标如何计算呢?我们可以把三个月画成三列网格,每个月起始线的 X 坐标是可以通过上一节的内容计算出来的,每个月有四种类型的数据,我们就画四条柱子,每个柱子的起点从当前月份的起点 X 坐标加上留出来的空白偏移量(比如第一个柱子是 X+10 ,第二条是 X+10+柱子宽度+10,这样依次计算),利用循环绘图即可。
编程
一、听说“懒惰”是程序员的美德。我们不妨把上一节的程序复制过来,因为画网格线的代码大部分是可以重复利用的。我们把变量 ROW 和 COL修改一下,画出 X 轴方向三个格代表三个月份,Y 轴方向五行代表 0-50万。
二、把月份标签的代码也做相应的修改,这里只是把克隆体的 X 坐标向右移动了半个网格的距离,因为我们是要把标签对准格子中间,而不是对准竖线(比如1月份标签应该显示在第一条线和第二条线的中间位置):
三、金额标签是原来的气温标签修改而来,只是重新命名了角色,删除了不需要的造型,把负值去掉,只保留0-50,原来的私有变量“气温”重新命名为“金额”:
四、现在到了关键部分。把问题中的数据做成三个列表,分别命名为“一月数据”、“二月数据”、“三月数据”,再建立一个“序列”变量,开始编程。
自制积木“绘制柱状图”用序号变量代表月份,调用三次自制积木“画月度数据”。画每个月数据的时候,我们首先要计算出当前月份对应的 X 坐标,然后重复四次(每月有四个数据)画柱子也就是序列的操作,每个序列画的时候先在当前月份X坐标基础上算出自己的X坐标,调用“序列设置”设置把当前的数据转换成Y坐标,并设置当前序列的画笔颜色,然后开始按照分析环节中我们描述的方法,反复画线 y-Y1 次,画线是通过移动、增加 Y 坐标、转向180实现的。为了确保每个序列开始绘制时画笔的方向是从左向右的,必须在开始时把它设置成面向90度方向。
如果你不想看到柱状图的绘制过程,可以把自制积木的“运行时不刷新屏幕”选中。
五、现在,把背景修改下,加上图例和标题,作品就完成了:
绘制的过程还是很有意思的——
总结
有了上一节课的经验和写好的自制积木,我们这节课任务完成得要快多了。可见将程序模块化,以便进行重用是多么重要的一件事。