目录
前言
本文是Web数据可视化案例系列文章的第三篇。文章介绍主题河流图的用法。首先介绍主题河流图与堆叠柱状图的区别,其次详细说明如何使用主题河流图展示数据。
当我们面对一组具有2个维度属性的数据时,如果不使用可视化手段,很难抓到正确的数据趋势。对于这种超过一个维度的数据,我们常常想到使用堆叠柱状图来显示数据。但是堆叠柱状图在使用时是有限制的,比如,一组数据统计了每天9点、10点、11点、12点设备上报告警的数量,使用堆叠柱状图显示这组数据就会割裂每天数据的连贯性趋势,所以最好使用主题河流图(在Excel中,这种类型的图表叫做面积图)显示数据。
正文
那么,主题河流图和堆叠柱状图有什么区别呢?他们的主要区别在于它们所展示的数据类型和目的。
主题河流图主要用于表示事件或主题在一段时间内的变化。它通过不同颜色的条带状河流分支来编码不同的事件或主题,河流分支的宽度编码了原数据集中的value值。此外,原数据集中的时间属性被映射到单个时间轴上,从而形象地展示了一个主题或事件随时间的变化情况。这种图表类型特别适合展示动态的数据变化和事件流程。举例如下图。
堆叠柱状图则主要用于展示一个大分类包含的每个小分类的数据,以及各个小分类的占比。它通过将每个柱子进行分割来显示相同类型下各个数据的大小情况,从而形象地展示了单个项目与整体之间的关系。堆叠柱状图可以清晰地展示各个小分类与大分类之间的数量关系,以及它们在整体中的占比。
简而言之,主题河流图更适合用来展示动态的事件或主题随时间的变化情况,而堆叠柱状图则更适合用来展示不同小分类与大分类之间的数量关系和占比情况。
下面我们依然使用轻量级、开源的bottle作为前台web框架,页面使用echarts图表的主题河流图展示数据。在后台,我们使用python编程查询数据,仍然使用sqlite轻量级数据库存储数据。
项目背景是这样的:一台监控主机负责监控网络通信问题导致的告警,告警数量增加时,表明有通信链路产生问题。同时,该类型告警信息可因为通信链路经过多次尝试后变为正常通信,最终导致相关联的告警自动解除,因此告警数量会因此减少。该类型告警数据每天都会重复统计,统计频率是每小时统计一次。当前需求就是,让数据大屏显示该类型告警每天9点、10点、11点、12点告警变化趋势。
首先,我们先看下数据库中存储告警的表结构,以及数据集合的情况。
从数据表名称看,表名是使用日期+时间命名的,数据表中包括很多告警的数量统计信息,我们只显示告警alm001的数据。
根据对现有数据分析,我们需要整理出所有告警alm001的数量,日期和时间。如何从众多数据表中查询出所有alm001的每天每个时刻的告警数量,有没有简单的办法呢?
下面是代码实现:
def getAlm001Data():
db = create_engine(r'sqlite+pysqlite:///D:\alarmdb.sqlite3')
sql_cmd = '''select 'select "'||name||'" as tn,alarm_count from '||name||' where alarm_name="alm001"' from sqlite_master where name like "d05%"'''
conn = db.connect()
res = conn.execute(text(sql_cmd))
obj = res.fetchall()
res.close()
sql_query= ' union '.join([str(row[0]) for row in obj])
df = pd.read_sql(sql=sql_query, con=conn)
df['d']=df['tn'].apply(lambda x:'2024/'+x[1:3]+'/'+x[3:-2])
df['h']=df['tn'].apply(lambda x:x[-2:])
df = df[['d','alarm_count','h']]
df = df.astype({'alarm_count':'int64'})
json_lst=df.to_json(orient='values',force_ascii=False).replace('"', "'")
return json_lst
如果看过本系列前面文章的小伙伴会发现,这里处理多数据表查询相同条件数据的方法,与《使用 svg 图表进行数据可视化》处理多数据表的方法一模一样。此处就略过不讲,如果有不明白的地方请参考上一篇文章。
因为我们还要统计告警的日期和时间信息,这些信息都包含在数据表中,所以我们需要通过数据表名称来获取告警日期和时间信息。
df['d']=df['tn'].apply(lambda x:'2024/'+x[1:3]+'/'+x[3:-2])
df['h']=df['tn'].apply(lambda x:x[-2:])
数据列’tn’就来自于数据查询时保留的数据表的名称。
这个方法最后将数据转成json数组对象,每个数组元素也是一个数组,这个数组中有日期,告警数量,时间。
现在有了数据,我们通过bottle框架来搭建前台页面。
在bottle的控制模块增加路由配置用于指定需要显示的可视化页面。我们先把这个模板命名为almview.tpl,我们随后再绘制这个页面。控制模块增加下面的配置:
@route('/almview', method='GET')
def almview():
data = getAlm001Data()
return template('view/almview',json_data=data)
到了绘制河流图的最关键的地方,请大家瞪大眼睛仔细听讲啦。
先把almview.tpl的实现代码放在这里,后面讲解。
var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var data={{!json_data}}
var option;
option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: 'rgba(0,0,0,0.2)',
width: 1,
type: 'solid'
}
}
},
legend: {
data: ['09', '10', '11', '12']
},
singleAxis: {
top: 50,
bottom: 50,
axisTick: {},
axisLabel: {},
type: 'time',
axisPointer: {
animation: true,
label: {
show: true
}
},
splitLine: {
show: true,
lineStyle: {
type: 'dashed',
opacity: 0.2
}
}
},
series: [
{
type: 'themeRiver',
emphasis: {
itemStyle: {
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.8)'
}
},
data: data
}
]
};
首先最关键的是要把series类型设置为'themeRiver',说明使用主题河流图。
接着需要设置legend,用来对应告警每个时间点的趋势情况。这个legend的目的是我们可以通过点击legend过滤时间点显示告警趋势。'09', '10', '11', '12'代表时间点,与从数据库查询出来的json数据中的时间点对应。
legend: {
data: ['09', '10', '11', '12']
},
最后,我们要把横坐标轴对应到告警发生的日期。
singleAxis: {
top: 50,
bottom: 50,
axisTick: {},
axisLabel: {},
type: 'time',
axisPointer: {
animation: true,
label: {
show: true
}
},
其中,type: 'time',用来告诉echarts横坐标使用时间类型数据。
大功告成,我们测试一下显示效果。打开浏览器输入http://127.0.0.1:8099/almview,我们就可以看到如下图像了。
如果我们只显示9点告警趋势情况,只需要关闭其他的时间点的legend就可以了。
看到这里,你是否了解了主题河流图与堆叠柱状图的区别,是否知道了怎样使用主题河流图显示数据呢?欢迎与我交流。
标签:df,data,主题,数据表,柱状图,可视化,河流,数据,告警 From: https://blog.csdn.net/hgoop/article/details/142629944