一、效果图
查询返回GitHub上近100天内,星数>1000的用Python写的项目,按最大星数降序排列,返回前30个项目。点击对应蓝柱可直接跳转至仓库链接。
二、完整代码+注释
"""
GitHub趋势仓库数据可视化脚本
功能:获取最近100天星标数超过1000的Python仓库,生成水平柱状图展示前30名
"""
import requests
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
def fetch_trending_repos():
"""
从GitHub API获取趋势仓库数据
返回:包含(仓库名称, 星标数)的元组列表,最多30条
"""
# 计算时间范围:当前时间向前推100天
since_date = (datetime.now() - timedelta(days=100)).strftime("%Y-%m-%d")
# 构建API请求URL
# q参数说明:
# - created:>指定日期:筛选创建时间在指定日期之后的仓库
# - language:python:指定编程语言为Python
# - stars:>1000:筛选星标数超过1000的仓库
# sort=stars:按星标数排序
# order=desc:降序排列(从高到低)
url = f'https://api.github.com/search/repositories?q=created:>{since_date}+language:python+stars:>1000&sort=stars&order=desc'
# 设置请求头:模拟浏览器访问避免被拒绝
headers = {'User-Agent': 'Mozilla/5.0'}
# 发送GET请求(verify=False关闭SSL验证,生产环境不建议使用)
response = requests.get(url,
headers=headers,
verify=False,
timeout=10)
# 如果响应状态码不是200,抛出HTTP错误异常
response.raise_for_status()
# 解析JSON响应数据中的items字段
repos = response.json().get('items', [])
# 返回前30个仓库的(名称, 星标数)元组列表
return [(repo['name'], repo['stargazers_count']) for repo in repos[:30]]
def plot_repos_data(repos_data):
"""
数据可视化函数
参数:repos_data - 包含(名称, 星标数)的元组列表
"""
# 数据解包:将元组列表拆分为名称列表和星标数列表
names = [x[0] for x in repos_data] # 获取所有仓库名称
stars = [x[1] for x in repos_data] # 获取对应的星标数
# 创建图形对象,设置画布尺寸为15x8英寸
plt.figure(figsize=(15, 8))
# 创建水平柱状图
# barh参数说明:
# - names: y轴标签(仓库名称)
# - stars: 对应的柱状图长度(星标数)
# - color: 柱状图颜色设置为天蓝色
bars = plt.barh(names, stars, color='skyblue')
# 设置坐标轴标签样式
plt.xlabel('Stars Count', fontsize=12) # x轴标签
plt.ylabel('Repository Name', fontsize=12) # y轴标签
# 设置图表标题,pad参数控制标题与图表的间距
plt.title('Top Trending Python Repositories (Last 100 Days)',
fontsize=14, pad=20)
# 反转y轴,使星标数最多的显示在最上方
plt.gca().invert_yaxis()
# 添加数据标签:在每个柱状图右侧显示具体星标数
max_stars = max(stars) # 获取最大值用于动态调整标签位置
for bar in bars:
width = bar.get_width() # 获取当前柱状图的宽度(星标数)
# 文字位置说明:
# x坐标:柱状图右侧 + 最大值的2%(保持间距)
# y坐标:柱状图垂直中心位置
plt.text(width + max_stars*0.02,
bar.get_y() + bar.get_height()/2, # 计算垂直居中位置
f'{width:,}', # 格式化数字添加千位分隔符
va='center') # 垂直对齐方式设为居中
# 自动调整子图参数,使整个图表适应画布
plt.tight_layout()
# 显示图表窗口
plt.show()
if __name__ == "__main__":
# 主程序入口
repos_data = fetch_trending_repos()
if repos_data:
plot_repos_data(repos_data)
else:
print("没有找到趋势仓库数据")