交互的作用:

  • 交互能让用户更好地理解和分析数据
  • 有效地缓解了可视化空间和数据过载之间的矛盾。
  • 更好的组织数据,展示数据的内涵

8.1交互原则

8.1.1交互延时

交互延时指的是从用户操作开始到结果返回经历的时间,延时的长短在很大程度上直接决定了用户体验的效果
选择合理的交互操作和视觉反馈的方法,并且要确保延时在可以接受的范围之内,才可以让用户正常、高效得与系统进行互动。

8.1.2交互场景

一般情况下,交互将引起可视化场景的变化。
应用中,用户通过切换场景来反复对比,达到准确发现变化的目的

8.1.3交互成本

交互本身带给用户便利的同时,额外的成本也会相应增加。
一般情况下,可视化系统会采用自动化处理的方式来解决。
用户分析和自动化分析是相辅相成的,权衡其作用和成本,达到一个平衡

8.2交互分类

按任务类型分类

  • 选择:将目标数据对象标记出来,例如通过高亮的方式标记数据;
  • 重新配置:重新设置可视化配置;
  • 重新编码:展现不同的视觉效果;
  • 导航:可以用来展现不同的数据,例如下一页提示按钮;
  • 关联:将有关联的数据一并展示;
  • 过滤:根据过滤条件选择显示一部分数据;
  • 概览:展现对象的总体概况;
  • 细节:展现更多细节内容;

 按操作符与操作空间分类

  • 操作符分为:导航、选择和变形
  • 操作空间分为:数据值空间、数据结构空间、对象空间、属性空间、屏幕空间和可视化结构空间
  • 交互的本质就是操作符与操作空间的组合。 

 按交互操作类型分类

  • 常见的交互操作归纳如下:缩放、过滤、关联、记录、提取、按需要提供细节以及概览。
  • 根据所操作的数据类型对交互操作进行分类,包括图形操作、数据操作和集合操作三类。
  • 图形操作指的是对可视化对象进行操作,例如图形等视觉表面层面的操作;
  • 数据操作指的是对数据对象进行增加、修改和删除;
  • 集合操作指的是对数据对象组成的集合进行创建和删除操作。

8.3交互技术

选择技术

单选与框选

导航技术

平移、缩放和   旋转(适用于数据量比较小的场景)

重配技术

目的是为用户提供观察数据的不同视角,

可用于解决由于空间距离拉大导致数据属性关联性降低的问题

铁屑与磁铁(Dust & Magnet)技术(性质取决于):

  1. Magnet的性质
  2. Magnet的强度
  3. Magnet所设置的相斥值
  4. Dust关于Magnet所规定的的性质的值

过滤技术

指的是通过设置过滤条件来进行信息查询的技术。

关联技术

不同产品的年产量曲线 用户选择折线数据,饼状图动态显示选择结果

交互式数据可视化是谁发明的 什么是交互可视化_数据

概览+细节技术

综合运用概览和细节的技术展示数据,让用户既可以从整体上把握当前状态,又可以从细节微观的角度观察数据。

8.4部分代码实现

图8-11

df=pd.read_csv("data/beijing_AQI_2018.csv")
attr=df['Date']
vl=df['AQI']
line = (
    Line()
    .add_xaxis(list(attr))
    .add_yaxis("AQI:",list(vl))
    .set_global_opts(title_opts=opts.TitleOpts(
            title="AQI全年走势图"
        ),

    )
    .set_series_opts(
        markpoint_opts=opts.MarkPointOpts(data=[
            opts.MarkPointItem(type_="max",),#显示最大值
            opts.MarkPointItem(type_="min",),#显示最小值
        ]),
        markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),#显示平均线
        areastyle_opts= opts.AreaStyleOpts(color="#000",opacity=0.3),
        label_opts=opts.LabelOpts(is_show=False)
    )
    .render("result/8_11.html")
)

图8-13

df=pd.read_csv("data/beijing_AQI_2018.csv")
dom=df[["Date","AQI"]]
list1=[]
for i in dom["Date"]:
    time=i.split('-')[1]
    list1.append(time)
df["month"]=list1
month_message=df.groupby(["month"])
monyh_com=month_message["AQI"].agg(["mean"])
monyh_com.reset_index(inplace=True)
monyh_com_last=monyh_com.sort_index()
attr=["{}".format(str( i )+"月") for i in range(1,13)]
vl=np.array(monyh_com_last["mean"])
vl=["{}".format(int(i)) for i in vl]
line = (
    Line()
    .add_xaxis(attr)
    .add_yaxis("AQI:",vl)
    .set_global_opts(title_opts=opts.TitleOpts(title="AQI月均全年走势图"),)
    .set_series_opts(
        markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max",),opts.MarkPointItem(type_="min",)]),)
    .render("result/8_13.html")
)

图8-15

df=pd.read_csv("data/beijing_AQI_2018.csv")
dom = df[['Date', 'AQI']]
data = [[], [], [], []]
dom1, dom2, dom3, dom4 = data
for i, j in zip(dom['Date'], dom['AQI']):
    time = i.split('-')[1]
    if time in ['01', '02', '03']:
        dom1.append(j)
    elif time in ['04', '05', '06']:
        dom2.append(j)
    elif time in ['07', '08', '09']:
        dom3.append(j)
    else:
        dom4.append(j)

boxplot = Boxplot()
boxplot = (
    boxplot.add_xaxis(['第一季度', '第二季度', '第三季度', '第四季度'])
    .add_yaxis("", boxplot.prepare_data([dom1, dom2, dom3, dom4]))
    .set_global_opts(title_opts=opts.TitleOpts(title='2018年北京季度AQI箱型图'),)
)
boxplot.render("result/8_15.html")

图8-17

df=pd.read_csv("data/beijing_AQI_2018.csv")
rank_message = df.groupby(['Quality_grade'])
rank_com = rank_message['Quality_grade'].agg(['count'])
rank_com.reset_index(inplace=True)
rank_com_last = rank_com.sort_values('count', ascending=False)

attr = rank_com_last['Quality_grade']
v1 = rank_com_last['count']

pie = (
    Pie()
    .add("空气质量", [list(z) for z in zip(attr, v1)], radius=[80, 180],
         tooltip_opts=opts.TooltipOpts(textstyle_opts=opts.TextStyleOpts(align='center'),
                                       formatter='{a}'+'<br/>'+'{b}: {c} ({d}%)'))
    .set_global_opts(title_opts=opts.TitleOpts(title='2018年北京全年空气质量情况', pos_left='center'),
                     legend_opts=opts.LegendOpts(orient='vertical', pos_top='5%', pos_left='2%'),
                    )
)
pie.render("result/8_17.html")