十月一号,央视新闻网发布了一篇报道:《“数”览近十年国庆黄金周!今年“十一”超长假期有这些变化》。
报道中,用两张动态图表,展现了近十年来的黄金周全国接待旅客数量与收入的变化情
从两张图中可以看出:
近十年来国内黄金周的旅游人数和收入的绝对值均不断上升; 其中,2012年不论是旅游人数还是旅游收入,相对于2011年均有大幅度上升。2015年旅游人数的上升幅度,看起来没有旅游收入的上升幅度大,或表示2015年,民众的旅行消费升级。显然,想要更确切的看出每年的增长情况,单看绝对数量,是不太明显的。
此时,需要计算一下每年的增长率指标:
增长率指标计算公式:
按照国际惯例,先上结果: 以下代码,以绘制十年内旅行人数增长率变化为例,最终输出上面这个gif图。
实际中,使用matplotlib和seaborn就已经足够绘制出很漂亮的静态图表。
想要让图片动起来,使用matplotlib中的ainmation对象,配合构建的动态函数,就可以让图表动起来。还可以保存成gif、mp4等多种格式。
数据比较少,所以直接敲成列表。
year是年份;revenue_list是旅游年收入(亿元);number_list是年旅行人数(亿/人次)
# 计算增长率,保存为numpy列格式 def cal_rate(cal_list): list_c = [0] # 临时列表的第一个元素,即2010年,定为0 for i in range(len(cal_list)-1): list_c.append((cal_list[i+1]-cal_list[i])/cal_list[i]) return np.array(list_c) num_growth_rate = cal_rate(number_list) #定义一个用于往原始列表中,增加元素的函数 # 没有这个函数,保存的gif图片变化就会比较大 def augment(xold, yold, numsteps): xnew = [] ynew = [] for i in range(len(xold)-1): difx = xold[i+1] - xold[i] stepsX = difx/numsteps dify = yold[i+1] - yold[i] stepsY = dify/numsteps for s in range(numsteps): xnew = np.append(xnew, xold[i]+s*stepsX) ynew = np.append(ynew, yold[i]+s*stepsY) return xnew, ynew # numsteps=10,表示在原本列表的每两个数字之间,增加9个数字 # 原本长度为10的列表,最后变成100 # 相应的,最后生成动态图表的时候,迭代次数,frames变量要设置为100帧。 year_new, num_growth_new = augment(year, num_growth_rate, 10) num_df = pd.DataFrame(num_growth_new, year_new) num_df.columns = {'num_growth'}这里似乎没有什么可说的,就正常的绘图参数。
第一行,定义画布大小,坐标轴名称为ax; 第二、三行,分别定义横纵坐标的标签范围。 第四、五行,定义横纵坐标的名称和字体大小 最后,title,定义图标的名称和字体大小。
接下来,按照每一行说什么来讲解一下:
animator = matplotlib.animation.FuncAnimation(fig, animate, frames=100, repeat=True)这一行代码,是将绘制动画的matplotlib对象实例化为animator。方便接下来进行保存等操作。
其中frames=100,表示迭代100次,也就是animate(i)中的i=100,函数会迭代100次。
repeat=True,意味着如果使用plt.show(),那么动图会自动循环播放。
接下来讲解animate函数中的代码:
def animate(i): data = num_df.iloc[:int(i+1)] sns.lineplot(x=data.index, y=data['num_growth'], data=data, color='r', ax=ax, linewidth=5) j = int(i) // 10 if isinstance(j, int): ax.text(year[j], num_growth_rate[j], str(round(num_growth_rate[j]*100, 2))+'%', color='black', fontsize=10, ha='center', va='bottom') 提取绘图数据——data,每次都提取num_df表中的前i+1行数据,用于绘图。 这样,看起来才有一点点画出来的感觉。使用seaborn绘制线型图。没有什么好说的。重点是数据标签的绘制。我希望达到的感觉是,数据走到了那个点上,正好,标签也打上去。 定义了一个变量j,要使用地板除法,只取整数的部分。如果地板除法的结果是整数,那就正好是原本的增长率,而不是我们之前为了平滑图片增加的其他数据。 animator.save('number_of_t.gif') # plt.show()最后,将animator对象保存为gif图片。
或者,注意是“或者”,只能二选一哦,如果用plt.show(),那么就要将save备注起来。
用同样的方法,将旅游人数的数据,改为旅游收入的数据,就可以得到十年来黄金周旅游收入增长率变化图。
将整个绘图过程封装成为line_plot函数,传入数据表、数据列,y轴标签和表名称,三个变量,生成相应的动态图表。
最终生成的结果如下:
为了更直观的看出变化,人数与增长率的数据贴出来: 结合上面绘制的动图进行分析:
2012年,相比2011年,不论是出行人数还是旅游收入,均有大幅度上升。人数增长和收入增长的幅度持平。约为40%多。2013年,相比于2012年,虽然出行人数增长率仅为0.70%, 但是旅游收入的增长率却增加了6.1%。重点在于2015年,相比于2014年,出行人数增长10.7%,而旅游收入却大幅度增长,增长了71.8%。前文提到,2015年旅行消费升级,此处验证了这一点。接下来,民众在黄金周的出行和消费均呈现同步增长。2016-2017年,增长幅度较大,2018年增长幅度大幅降低,2019年,稍微恢复增长。这里,还是要借鉴《精益数据分析》的指标判定方法。
什么才是好的数据指标:
1. 简单易懂 2. 最好是一个比率
原因如下:
**比率的可操控性强,显示的是一种行动状态。**比如,案例中40%的增长率,对比与其他,可以发现处在一个快速上升状态。比率是天生的比较指标。每一年的增长率进行比较,就知道下一次,要保持在一个什么样的增长才算合理。**比率,还适用于比较因素之间的正相关和负相关性。**比如,本例中,出行人数与收入的增长幅度并不匹配,这时候就可以猜测是发生了什么情况。 在本案例中,只看数量变化,有一种粉饰太平的感觉。计算增长率之后,发现2018年以来,不论是出行人数还是旅游收入,增长率都比如以往年份。
这可能是2015之后,旅行消费升级的弊端开始显现。十一黄金周的旅行消费升级,是不是仅仅价格上涨了,而服务各方面都没有配套上涨,因而开始导致游客对旅行质量感到不满呢?
对于这个问题,当前的数据就没有办法进行预测。还需要搜集其他数据来验证想法。
这就超出了这篇文章的范畴,暂时先不去套路了! 码字不易!!
如果您能看到这里,动动手
点赞、关注、转发一下吧!