周末接了一个简单的文献信息统计任务,主要是从txt里提取关键、被引量、作者什么的,再简单画下图。有段时间没用过matplotlib了,所以花了点时间(捂脸
输入文件介绍
web of science 核心合集的字段标识
我接到的就是tab分隔的、包含这些字段的多条记录。
表头有:
PT AU BA BE GP AF BF CA TI SO SE BS LA DT CT CY CL SP HO DE ID AB C1 RP EM RI OI FU FX CR NR TC Z9 U1 U2 PU PI PA SN EI BN J9 JI PD PY VL IS PN SU SI MA BP EP AR DI D2 EA PG WC SC GA UT PM OA HC HP DA
任务中涉及到的包括:
缩写 | 解释 |
---|---|
PY | 发表年份 |
TC | Web of Science 核心合集的被引次数 |
Z9 | 被引频次合计 |
AU | 作者 |
DE | 关键词 |
对于前四个,主要用了条形图、折线图和饼图,对于关键词用了词云做展示(对于作者,我本来也想搞词云的,但是显示得不太好看,就放弃了)。
条形图
水平条形图
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
def read(file_name):
sheets = pd.read_excel(file_name, sheet_name=None)
sheet_names = list(sheets.keys())
for sheet in sheet_names:
df = sheets[sheet]
# 按年份聚合一下
group1 = df.groupby('PY') # 发表年份
years1 = []
cnt1 = []
for name, group in group1:
years1.append(name) # 比如2007, 2010这样
cnt1.append(group.shape[0]) # group.shape是r行c列的, c=df.shape[1]
# 年度发文量-水平条形图
plt.barh(range(len(years1)), cnt1, align='center', color='steelblue', alpha=0.8)
plt.xlabel('年度发文量')
plt.ylabel('年份')
plt.title('年度发文量分布情况')
plt.yticks(range(len(years1)), years1)
plt.xlim([min(cnt1)-1, max(cnt1)+50])
for x,y in enumerate(cnt1):
plt.text(y+0.1, x, '%s'%y, va='center')
plt.show()
效果:
普通条形图
还是用上面读到的df。这里大概想搞一个直方图,不过matplotlib的直方图函数跟我要的不太一样,所以我手动分组,计算每组的频数,然后画了条形图。这次方向是竖直的。
temp = df[df[col] <= i + 100].count()[‘PT’] 这里是筛选col列小于i+100的记录,计数。因为这个计数其实是每列都计数了,PT列是类型,只有一个,所以它的加和就是数目了
draw_tc(df, "TC", 5000, "Web of Science 核心合集的被引次数")
def draw_tc(df, col, up, title):
td = []
tn = []
# 以下是分组
t = 0
for i in range(0, 500, 100):
temp = df[df[col] <= i + 100].count()['PT']
name = str(i) + "-" + str(i + 100)
td.append(temp - t)
tn.append(name)
t = temp
for i in range(500, 2500, 500):
temp = df[df[col]<= i + 500].count()[c'PT']
name = str(i) + "-" + str(i + 500)
td.append(temp - t)
tn.append(name)
t = temp
temp2 = df[df[col] <= up].count()['PT']
name = "2500-" + str(up)
td.append(temp2 - temp)
tn.append(name)
print(td)
print(tn)
plt.xticks(range(len(tn)), tn) # 注意!x是list(数字)
plt.bar(range(len(tn)), td) # 这里的参数x与xticks的参数x,你品
for x, y in enumerate(td):
plt.text(x, y, '%s' % y)
plt.ylabel("文章数量")
plt.xlabel("被引数量范围")
plt.title(title + "分布情况")
plt.show()
效果如下:
折线图
折线图用的是水平条形图里的years1和cnt1的数据。
plt.plot(years1, cnt1, c='blue') # 画蓝色的线
plt.scatter(years1, cnt1, c="red") # 线上的每个点,红的
plt.xticks(years1, [i for i in years1]) # 这个之前我没设置,就有了1997.5这样离谱的年份
plt.ylabel('年度发文量')
plt.xlabel('年份')
plt.title('年度发文量分布情况')
plt.show()
饼图
def draw_pie_plot(dat, name, title):
y = np.array(dat) # dat是一个list,装的是数字
# name装的是dat中每个数字对应的名称
# autopct指计算出的每个百分比值,保留一位小数
# explode与name的长度相同,对应每一块的位置(按占比递减顺序)。越大的值表示这一角越靠外。也可以有负值的
plt.pie(y, labels=name, autopct='%.1f%%', explode=[0,0,0,0,0,0,0.3])
plt.title(title)
plt.show()
比如下图设置的就是explode=[0,-0.1,0.8]
词云图
词云用的是wordcloud包。pip装一下即可。
from wordcloud import WordCloud
# s是有固定分隔符的长字符串。词云图显示的词就是;内的一个一个词
s = "1;test;2004;2;test"
wordcloud = WordCloud(background_color='white', width=2000, height=1500,
margin=0).generate(s)
# 显示图片
plt.imshow(wordcloud)
plt.axis('off')
plt.show()