zoukankan      html  css  js  c++  java
  • MOOC课程信息D3.js动态可视化

    版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/83153693

    - 写在前面



      好久没更新博客了,主要还是最近太忙了。很久之前就看到B站上动态柱状图图表(用D3.js做的),详情见@Jannchie见齐的主页。感觉很不错,于是便自己也做一哈。正好前一阵子写了脚本对中国大学MOOC的课程信息进行了爬取,经过修改后弄成了定时爬虫。经过近一个月爬取,数据已经挺多的啦,可以开始类似动态展示了。

      如果需要查阅爬虫脚本的,可参见我的博客:

      中国大学MOOC课程信息爬取与数据存储

    - 环境配置



      运行环境:Python3.6、Spyder
      依赖的模块:pandas、mysql等

    - 开始工作


    1. 数据


      从9月20日至今,已有28张表格(以爬取日期命名),每张表格中都有一两千条课程数据,如下:

    2. 开源动态可视化项目


      下载开源项目

      Historical-ranking-data-visualization-based-on-d3.js

      解压打开后,可以看到示例的example文件




      步骤很简单,只需根据示例文件格式添加数据即可。对于比较复杂的设置,如添加顶部附加信息或自定义颜色等,打开config,js和visual.js进行相应修改。

      打开压缩包内的bargraph.html网页并添加待可视化的表格文件即可。

    3. 获取每天选课热度前10课程

    '''获取热度每天选课热度前15课程'''
    def get_top_hot(quire_condition):
        db = pymysql.connect(host='localhost',user='root',passwd='root',db='mooc_courses_infos',charset='utf8')    #连接数据库
        cur = db.cursor()
        sql = 'SHOW TABLES'
        cur.execute(sql)    #遍历所有表格
        tables= cur.fetchall()
        top_hot={}  #热度
        for table in tables:
            data=table[0][9:11]+'-'+table[0][12:14]  #日期标准化
            cur.execute("select course,id,stu_num from %s"% table+" where start_time like '%s'"% quire_condition+" ORDER BY stu_num desc limit 10")  
            result=cur.fetchall()
            top_hot[data]=result
        return top_hot
    
    '''热度top10课程写入CSV表格'''
    def save_csv(subject,top_hot):
        all_data=()   #所有数据初始化
        date=[]     #日期
        order=[]    #每日热度排名
        for data in top_hot:  
            _order=[i+1 for i in range(len(top_hot[data]))]  #每日排名编号
            order.extend(_order)
            all_data+=top_hot[data] #添加数据 
            date.extend([data for _ in top_hot[data]])  #日期
        dataframe = pd.DataFrame(list(all_data))  #数据字典化
        dataframe.columns = ['name','type','value']  #修改标签
        dataframe['type']=order  #将type列值改为每日热度的排名
        dataframe['date']=date   #添加日期列 
        path='C:\Users\Administrator\Desktop\Historical-ranking-data-visualization-based-on-d3.js-master\src\'
        '''将DataFrame存储为csv,index表示是否显示行名,default=True'''
        dataframe.to_csv(path+subject+'.csv',index=False,sep=',')  #写入csv
    

      需要说明的是因为课程进程不一致,为了相对公正一些,我这里将其分为三类:已结束的、正在进行的、即将开始的,分别获取每日热度top10。
    conditions={'已结束':'已结束%','即将开始':'%开课%','正在进行':'进行至%'}  #查询条件集
    condition='已结束'  #查询条件
    quire_condition=conditions[condition]  #SQL语句中的查询条件
    top_hot=get_top_hot(quire_condition)  #获取指定查询条件下所有课程热度前10
    save_csv(condition,top_hot)  #存入SCV表格
    

    4. 获取指定课程门类下每天选课热度前10课程

    '''获取指定门类课程名称和ID'''
    def get_kc_kind(subject): 
        subject_ids=[]
        db = pymysql.connect(host='localhost',user='root',passwd='root',db='mooc_courses_info2',charset='utf8')
        cur = db.cursor()
        cur.execute("select id from %s"% subject)    #获取表所有课程ID
        results=cur.fetchall()
        for result in results:
            subject_ids.append(result[0])
        return subject_ids
    
    '''获取指定门类课程的选课人数变化'''
    def get_hot_by_subject(subject_ids): 
        subject_ids=tuple(subject_ids)
        db = pymysql.connect(host='localhost',user='root',passwd='root',db='mooc_courses_infos',charset='utf8')
        cur = db.cursor()
        sql = 'SHOW TABLES'
        cur.execute(sql)   #遍历指定数据库所有表
        tables= cur.fetchall()
        top_hot={}  #热度
        for table in tables:  #特定日期
            data=table[0][9:11]+'-'+table[0][12:14]  #日期标准化
            '''查询条件:在指定门类下ID范围内;正在进行的课程;课程热度由高到低前10'''
            sql2 = "select course,id,stu_num from %s"% table+" where id in (%s)" % ','.join(['%d']*len(subject_ids)) % subject_ids 
                  +" and start_time like '进行至%' ORDER BY stu_num desc limit 10"
            cur.execute(sql2)
            result=cur.fetchall()
            top_hot[data]=result
        return top_hot
    


      这里值得说的是SQL查询语句where in下变量的表达,使用了format(花了不少功夫才得以解决)。

    subjects={'国家精品':'excellent_course','计算机':'computer','经济管理':'management','心理学':'psychology',
             '外语':'language','文学历史':'literary_history','艺术设计':'art','工学':'engineering',
             '理学':'science','生命科学':'biomedicine','哲学':'philosophy','法学':'law',
             '教育教学':'teaching_method'}
    _subjects=list(subjects.keys())  #课程门类中文名列表
    for subject in _subjects:
        subject_Eng=subjects[subject]  #课程门类英文名
        subject_ids=get_kc_kind(subject_Eng)  #获取该门类下所有ID
        subject_top_hot=get_hot_by_subject(subject_ids)  #该门类下每日课程热度前10
        save_csv(subject,subject_top_hot)  #写入CSV
    

    - 结果展示


    1. 正在进行的所有课程每日热度前10

    2. 即将开课的所有课程每日热度前10

    3. 已结束的所有课程每日热度前10

    4. 计算机门类下正在进行课程每日热度前10

    5. 国家精品门类下正在进行课程每日热度前10

    - 写在最后



      运行程序时发现挺快的,只有几秒钟,因此代码优化暂时不着急做。在绘制动态图表时,为了展示效果更好还需要学习下开源项目的代码,进行相应优化提升。另图表中有些Bug,比如有些值显示不出来,为NaN。

      最后还是非常感谢大佬的开源奉献!

  • 相关阅读:
    JSOI2010 满汉全席
    LNOI2014 LCA
    BZOJ3689 异或之
    Codeforces Round #553 div.2
    AHOI2013 差异
    SDOI2016 生成魔咒
    NOI2006 最大获利
    没有过的题QAQ
    NOI2014 动物园
    HDU4622 Reincarnation
  • 原文地址:https://www.cnblogs.com/sc340/p/11870811.html
Copyright © 2011-2022 走看看