Seaborn相关项目讲解(附ipynb文件)

1、Seaborn

Seaborn 是一个用于在 Python 中制作统计图形的库。它建立在 matplotlib 之上,并与 pandas 数据结构紧密集成。
Seaborn 可以帮助您探索和理解数据。它的绘图函数在包含整个数据集的数据框和数组上运行,并在内部执行必要的语义映射和统计聚合以生成信息丰富的绘图。它面向数据集的声明式 API 使您能够专注于绘图的不同元素的含义,而不是如何绘制它们的细节。

官网链接:https://seaborn.org.cn/index.html

2、项目(核电站的数据分析)

核电站的数据加载

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv(r'C:\Users\33631\Desktop\nuclear.csv', delimiter=',')  #切记导入数据时要加r

#这行代码是使用Pandas库中的read_csv函数来读取位于指定路径的CSV文件,并将其内容加载到一个DataFrame对象df中。
#这里的delimiter=','参数实际上是默认的,因为CSV文件通常就是使用逗号(,)作为字段分隔符的,
#所以即使不写这个参数,Pandas也会默认使用逗号作为分隔符。

countries_shortNames = [['UNITED STATES OF AMERICA', 'USA'], \
                        ['RUSSIAN FEDERATION', 'RUSSIA'], \
                        ['IRAN, ISLAMIC REPUBLIC OF', 'IRAN'], \
                        ['KOREA, REPUBLIC OF', 'SOUTH KOREA'], \
                        ['TAIWAN, CHINA', 'CHINA']]

for shortName in countries_shortNames:
    df = df.replace(shortName[0], shortName[1])

#这行Python代码片段的目的是在一个名为df的Pandas DataFrame中,
#将countries_shortNames列表中定义的完整国家名(每个列表的第一个元素)替换为对应的短名称(每个列表的第二个元素)

核电站的世界分类

import folium    #现在anaconda里安装folium。用于创建和保存交互式地图。
import matplotlib.cm as cm # 导入matplotlib的颜色映射模块。
import matplotlib.colors as colors # 导入matplotlib的颜色处理模块。  

# 设置地图的中心点和初始缩放级别
latitude, longitude = 40, 10.0  # 设置地图的中心点经纬度。 
map_world_NPP = folium.Map(location=[latitude, longitude], zoom_start=2) # 创建一个folium地图对象,设置中心点和初始缩放级别为2。  

# 生成颜色映射  
viridis = cm.get_cmap('viridis', df['NumReactor'].max()) ## 使用matplotlib的'viridis'颜色映射,根据'NumReactor'的最大值来设置颜色映射的范围。
colors_array = viridis(np.arange(df['NumReactor'].min() - 1, df['NumReactor'].max())) ## 生成颜色数组,
rainbow = [colors.rgb2hex(i) for i in colors_array] ## 将颜色数组中的颜色转换为十六进制字符串,以便在folium中使用。

#在地图上添加标记
for nReactor, lat, lng, borough, neighborhood in zip(df['NumReactor'].astype(int), df['Latitude'].astype(float),
                                                     df['Longitude'].astype(float), df['Plant'], df['NumReactor']):
    # 这里zip函数将多个序列(列)打包成一个元组的迭代器,每个元组包含来自每个序列的对应元素。  
    label = '{}, {}'.format(neighborhood, borough)  # 创建标签,格式为“邻域, 区域”。
    label = folium.Popup(label, parse_html=True) # 将标签转换为folium的Popup对象
    folium.CircleMarker(
        [lat, lng], # 标记的经纬度。
        radius=3, # 标记的半径
        popup=label,  # 标记的弹出窗口。
        color=rainbow[nReactor - 1],  # 标记的边框颜色,根据'NumReactor'的值从颜色映射中选择。  
        fill=True, # 标记是否填充颜色。
        fill_color=rainbow[nReactor - 1], # 标记的填充颜色。
        fill_opacity=0.5).add_to(map_world_NPP) # 标记的填充透明度,并将标记添加到地图上。

# 在地图上显示
map_world_NPP.save('world_map.html')  # 保存为 HTML 文件

map

拥有核反应堆的20个国家对比

原版(画图重叠)
countries = df['Country'].unique()
df_count_reactor = [[i, df[df['Country'] == i]['NumReactor'].sum(), df[df['Country'] == i]['Region'].iloc[0]] for i in
                    countries]
df_count_reactor = pd.DataFrame(df_count_reactor, columns=['Country', 'NumReactor', 'Region'])
df_count_reactor = df_count_reactor.set_index('Country').sort_values(by='NumReactor', ascending=False)[:20]
ax = df_count_reactor.plot(kind='bar', stacked=True, figsize=(10, 3),
                           title='The 20 Countries With The Most Nuclear Reactors in 2010')
ax.set_ylim((0, 150))
for p in ax.patches:
    ax.annotate(str(p.get_height()), xy=(p.get_x(), p.get_height() + 2))
df_count_reactor['Country'] = df_count_reactor.index
sns.set(rc={'figure.figsize': (11.7, 8.27)})
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
ax = sns.barplot(x="NumReactor", y="Country", hue="Region", data=df_count_reactor, dodge=False, orient='h')
ax.set_title('2010年拥有最多核反应堆的20个国家', fontsize=16)
ax.set_xlabel('Reactors', fontsize=16)
ax.set_ylabel('')
ax.legend(fontsize='14')

plt.show()

原版

修改后的版本
# 1、计算每个国家的核反应堆总数,并保留第一个区域(注意:这可能不是最佳实践)
df_count_reactor = df.groupby('Country').agg(NumReactor=('NumReactor', 'sum'), Region=('Region', 'first')).reset_index()  
# df.groupby('Country'):按照'Country'列对df DataFrame进行分组。
#.agg(...):对每个分组应用聚合函数。这里,我们计算了'NumReactor'列的总和(即每个国家的核反应堆总数),并选择了'Region'列的第一个值(注意:这可能不是最佳选择,因为如果有多个国家在多个区域有反应堆,则只会显示第一个区域)。
#.reset_index():将分组后的结果转换回DataFrame,并将分组键(在这个例子中是'Country')作为一列添加到DataFrame中。
# 最后生成三列:country sum regi

# 排序并限制为前20个国家  
df_count_reactor = df_count_reactor.nlargest(20, 'NumReactor').reset_index(drop=True)  
# .nlargest(20, 'NumReactor'):选择'NumReactor'列中值最大的前20行。
# .reset_index(drop=True):重置索引,drop=True参数表示不保留旧的索引作为一列。

# 2、可视化  
# 设置绘图样式  
sns.set(rc={'figure.figsize': (11.7, 8.27)}, style="whitegrid")  
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签  
# sns.set(...):设置Seaborn的全局绘图样式和默认参数,包括图表的大小(rc={'figure.figsize': (11.7, 8.27)})和样式(style="whitegrid")。
# plt.rcParams['font.sans-serif']=['SimHei']:设置Matplotlib的字体参数,以便能够正确显示中文字符。  
  
# 绘制水平条形图  
ax = sns.barplot(x="NumReactor", y="Country", hue="Region", data=df_count_reactor, dodge=False, orient='h')
# hue="Region":按'Region'列的值对数据进行分组,并在图表中使用不同的颜色表示。
# data=df_count_reactor:指定包含数据的DataFrame。
# orient='h':指定条形图的方向为水平。
ax.set_title('2010年拥有最多核反应堆的20个国家', fontsize=16)  
ax.set_xlabel('反应堆数量', fontsize=16)  
ax.set_ylabel('')  
ax.legend(fontsize='14', title='区域')  
  
# 显示数值  
for p in ax.patches:  
    ax.annotate(str(p.get_width()), xy=(p.get_width() + 2, p.get_y() + p.get_height() / 2), ha='left', va='center')  
#遍历所有条形:for p in ax.patches: 这行代码遍历了ax轴对象上所有的条形(即patches列表中的每个Rectangle对象)。
#获取条形的宽度:p.get_width() 方法返回当前条形(p)的宽度。这个宽度对应于条形图中所表示的数据值。
# 添加文本注释:ax.annotate(...) 方法用于在图表中添加文本注释。在这个例子中,它用于在条形上方显示条形的宽度。
#str(p.get_width()):将条形的宽度(一个浮点数)转换为字符串,以便可以将其作为文本添加到图表中。
# xy=(p.get_width() + 2, p.get_y() + p.get_height() / 2):设置文本注释的位置。
#x坐标是条形的宽度加上一个小偏移量(以避免文本与条形重叠),而y坐标是条形的y坐标加上条形高度的一半(以将文本放在条形的中央)。
# ha='left' 和 va='center':设置文本注释的水平对齐(ha)和垂直对齐(va)。
# ha='left':这表示文本注释的水平对齐方式是左对齐。va='center':这表示文本注释的垂直对齐方式是居中对齐。  
plt.show()

改版

核电站暴露人口分析

# 绘制条形图
def getMostExposedNPP(Exposedradius):
    df_pop_sort = df.sort_values(by=str('p10_' + str(Exposedradius)), ascending=False)[:10]
    # 根据指定半径内的暴露人口数量对核电站进行排序,并取前10个
    df_pop_sort['Country'] = df_pop_sort['Plant'] + ',\n' + df_pop_sort['Country']
    # 合并'Plant'和'Country'列来创建新的'Country'列
    df_pop_sort = df_pop_sort.set_index('Country')
    # 将'Country'列设置为索引
    df_pop_sort = df_pop_sort.rename(
        columns={str('p90_' + str(Exposedradius)): '1990', str('p00_' + str(Exposedradius)): '2000',
                 str('p10_' + str(Exposedradius)): '2010'})
    df_pop_sort = df_pop_sort[['1990', '2000', '2010']] / 1E6
    # 重命名列以反映年份,并将数值除以1E6转换为百万人口  
    ax = df_pop_sort.plot(kind='bar', stacked=False, figsize=(10, 4))
    ax.set_ylabel('Population Exposure in millions', size=14)
    ax.set_title(
        'Location of nuclear power plants \n with the most exposed population \n within ' + Exposedradius + ' km radius',
        size=16)
    print(df_pop_sort['2010'])
    # 绘制条形图并设置标签  

getMostExposedNPP('30')
# 调用函数,指定暴露半径为30km  

#创建和修改地图
latitude, longitude = 40, 10.0
map_world_NPP = folium.Figure(width=100, height=100)
map_world_NPP = folium.Map(location=[latitude, longitude], zoom_start=2)
# 初始化地图

for nReactor, lat, lng, borough, neighborhood in zip(df['NumReactor'].astype(int), df['Latitude'].astype(float),
                                                     df['Longitude'].astype(float), df['Plant'], df['NumReactor']):
    label = '{}, {}'.format(neighborhood, borough)
    label = folium.Popup(label, parse_html=True)
    folium.Circle(
        [lat, lng],
        radius=30000,
        popup=label,
        color='grey',
        fill=True,
        fill_color='grey',
        fill_opacity=0.5).add_to(map_world_NPP)
# 遍历所有核电站,添加灰色圆圈

Exposedradius = '30'
df_sort = df.sort_values(by=str('p10_' + str(Exposedradius)), ascending=False)[:10]
# 对暴露人口最多的前10个核电站进行特殊处理

for nReactor, lat, lng, borough, neighborhood in zip(df_sort['NumReactor'].astype(int),
                                                     df_sort['Latitude'].astype(float),
                                                     df_sort['Longitude'].astype(float), df_sort['Plant'],
                                                     df_sort['NumReactor']):
    label = '{}, {}'.format(neighborhood, borough)
    label = folium.Popup(label, parse_html=True)
    folium.CircleMarker(
        [lat, lng],
        radius=5,
        popup=label,
        color='red',
        fill=True,
        fill_color='red',
        fill_opacity=0.25).add_to(map_world_NPP)
# 添加红色圆圈
for nReactor, lat, lng, borough, neighborhood in zip(df_sort['NumReactor'].astype(int),
                                                     df_sort['Latitude'].astype(float),
                                                     df_sort['Longitude'].astype(float), df_sort['Plant'],
                                                     df_sort['NumReactor']):
    label = '{}, {}'.format(neighborhood, borough)
    label = folium.Popup(label, parse_html=True)
    folium.Circle(
        [lat, lng],
        radius=30000,
        popup=label,
        color='red',
        fill=True,
        fill_color='red',
        fill_opacity=0.25).add_to(map_world_NPP)

# 在地图上显示
map_world_NPP.save('world_map2.html')  # 保存为 HTML 文件

条形图
map2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值