【数据分析可视化】动态生成柱状图

本文介绍了一种使用Python的pandas和matplotlib库创建动态柱状图的方法,展示了从2000到2020年间全球城市的人口数据,通过matplotlib的FuncAnimation实现年份间数据的动画效果。
摘要由CSDN通过智能技术生成
import pandas as pd 
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker 
from matplotlib.animation import FuncAnimation  
import matplotlib.patches as mpatches 
from matplotlib.animation import FFMpegWriter

# 定义一个函数,用于生成颜色列表
def generate_colors(string_list):
    num_colors = len(string_list)
    # 使用tab10调色板,可以根据需要选择不同的调色板
    colormap = plt.cm.get_cmap('tab10', num_colors)

    colors = []
    for i in range(num_colors):
        color = colormap(i)
        colors.append(color)

    return colors

# 读取CSV文件,并选择所需的列
# 数据地址:https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210901121516/city_populations.csv
df = pd.read_csv(r'C:\Users\wangkejun\Desktop\city_populations.csv', usecols=[
                 'name', 'group', 'year', 'value'])

# 将年份列转换为整数型
df['year'] = df['year'].astype(int)
# 将人口数量列转换为浮点型
df['value'] = df['value'].astype(float)

# 获取城市分组列表
group = list(set(df.group))

# 生成城市分组对应的颜色字典
group_clolor = dict(zip(group, generate_colors(group)))

# 创建城市名称与分组的字典
group_name = df.set_index('name')['group'].to_dict()


# 定义绘制柱状图的函数
def draw_barchart(year):
    # 根据年份筛选数据,并按人口数量进行降序排序,取出最大范围的数据
    df_year = df[df['year'].eq(year)].sort_values(
        by='value', ascending=True).tail(max_range)
    ax.clear()
    # 绘制水平柱状图,并设置颜色
    ax.barh(df_year['name'], df_year['value'], color=[
            group_clolor[group_name[x]] for x in df_year['name']])
    
    # 在柱状图上方添加文字标签
    dx = df_year['value'].max() / 200
    for i, (value, name) in enumerate(zip(df_year['value'], df_year['name'])):
        # 城市名
        ax.text(value-dx, i, name,
                size=12, weight=600,
                ha='right', va='bottom')
        ax.text(value-dx, i-0.25, group_name[name],
                size=10, color='#333333',
                ha='right', va='baseline')
        # 地区名
        ax.text(value+dx, i, f'{value:,.0f}',
                size=12, ha='left',  va='center')

    # 设置其他样式
    ax.text(1, 0.2, year, transform=ax.transAxes,
            color='#777777', size=46, ha='right',
            weight=800)
    ax.text(0, 1.06, 'Population (thousands)',
            transform=ax.transAxes, size=12,
            color='#777777')
    # 添加图例
    handles = []
    for name, color in group_clolor.items():
        patch = mpatches.Patch(color=color, label=name)
        handles.append(patch)
    ax.legend(handles=handles, fontsize=12, loc='center', bbox_to_anchor=(
        0.5, -0.03), ncol=len(group_clolor), frameon=False)
    
    # x轴的主要刻度格式化,不保留小数
    ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
    # 将x轴的刻度位置设置在图的顶部
    ax.xaxis.set_ticks_position('top')
    # 设置x轴的刻度颜色为灰色(#777777),字体大小为16
    ax.tick_params(axis='x', colors='#777777', labelsize=16)
    # 清除y轴的刻度标签
    ax.set_yticks([])
    # 在x轴和y轴上设置0.01的边距
    ax.margins(0, 0.01)
    # 在x轴上绘制主要网格线,线条样式为实线
    ax.grid(which='major', axis='x', linestyle='-')
    # 设置网格线绘制在图像下方
    ax.set_axisbelow(True)

    # 添加绘图信息
    ax.text(0, 1.10, f'The {max_range} most populous cities in the world from {start_year} to {end_year}',
            transform=ax.transAxes, size=24, weight=600, ha='left')

    ax.text(1, 0, 'Produced by luohenyueji',
            transform=ax.transAxes, ha='right', color='#777777',
            bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))
    plt.box(False)


# 创建绘图所需的figure和axes
fig, ax = plt.subplots(figsize=(12, 8))
start_year = 2000
end_year = 2020
# 设置最多显示城市数量
max_range = 15

# 获取数据中的最小年份和最大年份,并进行校验
min_year, max_year = min(set(df.year)), max(set(df.year))
assert min_year <= start_year, f"end_year cannot be lower than {min_year}"
assert end_year <= max_year, f"end_year cannot be higher  than {max_year}"

# 创建动画对象,调用draw_barchart函数进行绘制
ani = FuncAnimation(fig, draw_barchart, frames=range(
    start_year, end_year+1), repeat_delay=1000, interval=200)
fig.subplots_adjust(left=0.04, right=0.94, bottom=0.05)


# 显示图形
plt.show()

  1. 库:pandas 用于数据处理,matplotlib 用于绘图,matplotlib.ticker 用于设置刻度格式,matplotlib.animation 中的 FuncAnimation 用于创建动画,matplotlib.patches 用于创建图例,FFMpegWriter 用于保存动画。

  2. 定义了一个函数 generate_colors(string_list),用于生成颜色列表。

  3. 使用 pandas 读取城市人口数据的 CSV 文件,并选择所需的列。

  4. 将年份列和人口数量列转换为整数型和浮点型。

  5. 获取城市分组列表,并生成城市分组对应的颜色字典。

  6. 创建城市名称与分组的字典。

  7. 定义了绘制柱状图的函数 draw_barchart(year),用于根据年份绘制相应的水平柱状图。

  8. 在 draw_barchart 函数中,根据年份筛选数据并按人口数量进行降序排序,绘制柱状图并添加标签、图例等。

  9. 设置了图形的样式,包括文字标签、图例、刻度格式化、网格线等。

  10. 创建绘图所需的 figure 和 axes,并设置起始年份、结束年份以及最多显示城市数量。

  11. 创建动画对象 FuncAnimation,并调用 draw_barchart 函数进行绘制。

  12. 调整图形的布局并显示图形。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值