作者出版频率条形竞赛图

为了演示《周报》作者出版频率的走势,我们利用了条形竞赛图。传统的棒形图会将数据在一个图表中固定地显示出来,让读者仔细阅读,而条形竞赛图则是动态棒形图,把连串的数据连续显示出来。

图一的条形竞赛图演示每年于《周报》中出版频率最高首二十位作者的出版走势(1967年除外),此视觉演示除了让读者了解当年笔者的产量和发展,更可了解横跨二十二年来多产作者的转变和走势。当代的作家会使用不同的笔名在不同的刊物和专栏投稿,条形竞赛图亦显示不同笔名在不同年代的出现。

《中国学生周报》的作者出版频率(首20位)

图一:《中国学生周报》的作者出版频率(首20位)条形竞赛图

由图一可见,《周报》在五十年代刊印初期,一些较多产的作家有昆南、黄思骋和麦菁。在五十年代后期,作家如小庆、但尼、蓝子和张爱伦开始冒起头来。多产作家小庆在六、七十年代继续投稿,在六十年代初期她使用了笔名小离,之后则主要使用为人熟识的笔名陆离。蓝子和张爱伦是作家西西的其中两个笔名,在六十年代后期,除了笔名西西,她亦用笔名南南来出版。作家小思在六十年代中期之后十分活跃,除笔名小思,她亦常用笔名明川来投稿。 《周报》出版的最后一年(即  1974年),本名梁秉钧和他的笔名也斯在图表中都位于很高的位置。

图一的条形竞赛图除了演示作家的不同笔名,亦让我们认识《周报》中一些重要的体裁。其中一种体裁是影评,但尼和陆离都是当代重要的影评家,他们的名字都在相关五、六十年代的图表中出现,在图表中亦可见到其他的影评家,包括罗卡、石琪和吴昊。除了中文的文章,《周报》亦有一些英语的文章,在六十年代初「花生漫画」开始在《周报》中刊印,作者舒尔茨在 1961 至 1964 年的图表中紧守着首位。

制作条形竞赛图的方法

制作条形竞赛图只需要把每一年的数据在如图二的图表表列出来,然后放进制作条形竞赛图的工具,条形竞赛图就会呈现于眼前。

图二:《中国学生周报》的作者出版频率统计图表(节录)

由于我们制作的是《周报》的作者出版频率条形竞赛图,我们需要作者出版频率的数据。我们首先收集了在香港文学资料库《周报》元数据内作者栏目的数据,资料库有 79,975 条《周报》的记录,其中 53,374 条的作者栏目是有资料的。这些资料记录了每一篇文章的责任者,很多都附有责任的类别,如访问、文、翻译、图等,在电脑程式语言中,由于这些词语不是被分析的数据用词,因而被称为停用词。我们在作者栏目的资料中删除这些停用词,并使用 OpenRefine 做数据清洁。

有些作者栏目包含了多于一个作者的名称,因此我们利用函式 def create_full_name_list ,抽出所有作者的名称,共 55,506 个,这包括了 18,804 个独立不重覆的名称,再作一次数据清洁。因为我们仍在试验性阶段,加上停用词和作者的名称比较多变,所以我们仍在改良名称采集的技巧和数据清洁的过程,而已采集的名称并未作严谨的权威管理。

在得到所有作者名称之后,我们利用函式 def search_year 和 def generate_data_for_year 把每一年作者出版的数量作统计,制作了如图二的数据图表。虽然有些作者以不同的笔名出版文章,但是图一的条形竞赛图是以每一个笔名作独立统计。由于作者名称包括一些广告持份者,而他们刊登广告量很高,我们利用这数据图表时若是演示高产量的作家,就需要先把一些不适合用作演示的名称及其相关数据取走,再把数据图表放进制作竞赛棒形图的工具(如 flourish.studio),图一的竞赛棒形图就会出现了。

我们亦利用了 Python 的 plotly library 制作了传统的棒形图来演示《周报》的作者出版频率,除了可以把同一作者不同笔名的统计数字独立地或加起来演示,并可供选择演示不同年份及排名范围,这互动的棒形图将会在图书馆的其他平台供大家使用。

电脑程式

以下的电脑程式(Python 3.7),可以用作准备作者频率统计图表。

# -*- coding: utf-8 -*-
import pandas as pd

# Get a list with all names
def create_full_name_list():
    author_data = pd.read_csv('weekly_metadata.csv')        
    full_name_list = list(author_data['column_name_author_name_after_removing_stopword'])
    full_name_list = list(set(full_name_list))
    return full_name_list

# Get the first and last year in the dataset
def search_year():
    data = pd.read_csv('weekly_metadata.csv')
    date_list = list(set((list(data['column_name_search_date']))))
    date_list = [str(x) for x in date_list if str(x) != 'nan']
    yearList = []
    # Get the year from the date
    for i in range(0,len(date_list)):
        yearList.append(date_list[i][(date_list[i].rfind('/')) + 1 :])    
    yearList = list(set(yearList))
    yearList.sort(reverse = False)
    first_year = yearList[0]
    last_year = yearList[-1]
    return first_year, last_year, yearList

# Count the frequency of each name in a year
def generate_data_for_year(year, name_list):
    data = pd.read_csv('weekly_metadata.csv')
    year_str = str(year)
    temp_data = data[data['column_name_search_date'].str.contains(year_str, na = False)]
    name_list_from_temp_df = list(temp_data['column_name_author_name_after_removing_stopword'])
    temp_dict = {}
    temp_count = []
    # Count the frequency of each element
    for i in range(0, len(name_list)):       
        count = 0
        for element in name_list_from_temp_df:
                if str(element) == name_list[i] and str(element) !='nan':
                    count = count + 1
        temp_count.append(count)
    return temp_count
# create full name list
data = {}
full_name_list = create_full_name_list()
cat_list = []
# Assign the name to different categories for differnet color
for i in range(0, len(full_name_list)):    
    cat_list.append(i % 50)
data['Name'] = full_name_list
data['cat'] = cat_list
# generate the data for each year
first_year, last_year, yearList = search_year()
# Get the count for each name in each year
for year in yearList:  
    current_year_count = generate_data_for_year(year, full_name_list)
    data[year] = current_year_count
# generate csv and xlsx files
df = pd.DataFrame.from_dict(data)
df.to_csv('data_for_bar_chart_race.csv', encoding = 'utf-8', index = False)
df.to_excel('data_for_bar_chart_race.xlsx', encoding = 'utf-8', index = False)