第一次接触数据可视化时,我被各种图表类型和参数搞得晕头转向。直到遇到Seaborn,这个基于matplotlib的Python可视化库,才真正体会到什么叫"优雅的数据分析"。让我们从一个真实的销售数据案例开始,看看如何用几行代码完成专业级的可视化。
假设你手上有份电商平台的交易记录,数据格式是这样的:
code复制支付时间,实际金额
2023/1/15,128.5
2023/2/3,89.9
2023/1/22,56.0
...
要分析月度销售趋势,传统方法可能需要写十几行代码来处理日期、分组汇总。但用Seaborn配合pandas,整个过程可以简化到令人发指:
python复制import seaborn as sns
import pandas as pd
# 读取数据并提取月份
df = pd.read_csv('sales.csv')
df['month'] = df['支付时间'].str.split('/').str[1].astype(int)
# 按月汇总金额并绘图
monthly_sales = df.groupby('month')['实际金额'].sum()
sns.lineplot(data=monthly_sales)
这里有几个实用技巧值得注意:
我在第一次使用时犯过的典型错误包括:
正确的完整代码应该这样写:
python复制plt.figure(figsize=(10,6)) # 黄金比例更美观
sns.set_style("whitegrid") # 白色背景+网格线
monthly_sales = monthly_sales.sort_index() # 确保月份顺序正确
ax = sns.lineplot(data=monthly_sales, marker='o') # 添加数据点标记
ax.set(xlabel='月份', ylabel='销售额(元)', title='年度销售趋势') # 完善标签
掌握了基础绘图后,我发现Seaborn真正的威力在于其丰富的统计图形。以经典的tips数据集为例,这个记录餐厅小费的数据集包含total_bill(总消费)、tip(小费)、sex(性别)等字段,是练习统计可视化的绝佳材料。
当我们需要对比不同群体的数据分布时,catplot是首选。比如分析吸烟与否对小费比例的影响:
python复制tips = sns.load_dataset('tips')
sns.catplot(x='day', y='tip', hue='smoker',
kind='box', data=tips)
这幅箱线图一眼就能看出:
jointplot可以同时展示两个变量的分布及其关系。分析消费金额与小费的关系:
python复制sns.jointplot(x='total_bill', y='tip',
data=tips, kind='reg',
marginal_kws={'bins':15})
图中清晰显示:
处理时间序列数据时,heatmap能直观展示模式。比如分析餐厅客流的热力图:
python复制flights = sns.load_dataset('flights')
flights = flights.pivot("month", "year", "passengers")
sns.heatmap(flights, annot=True, fmt="d", linewidths=.5)
从颜色深浅可以立即发现:
当数据包含地理位置信息时,将其映射到地图上能产生质的飞跃。Basemap作为传统地理绘图工具,虽然现在逐渐被Cartopy取代,但在简单场景下仍然实用。
先看如何绘制一张中国地图:
python复制from mpl_toolkits.basemap import Basemap
plt.figure(figsize=(12,8))
m = Basemap(llcrnrlon=73, llcrnrlat=18,
urcrnrlon=135, urcrnrlat=53,
projection='lcc', lat_1=33, lat_2=45, lon_0=100)
m.drawcoastlines() # 海岸线
m.drawcountries() # 国界线
m.drawparallels(range(0, 90, 10), labels=[1,0,0,0]) # 纬线
m.drawmeridians(range(70, 140, 10), labels=[0,0,0,1]) # 经线
关键参数说明:
假设我们有各城市销售额数据,可以在地图上用散点图展示:
python复制cities = {
'北京': [116.4, 39.9, 4200],
'上海': [121.47, 31.23, 3800],
# ...其他城市数据
}
for city, (lon, lat, sales) in cities.items():
x, y = m(lon, lat)
size = sales / 50 # 缩放比例
m.scatter(x, y, s=size, c='red', alpha=0.5)
plt.text(x, y, city, fontsize=10)
对于区域数据,choropleth地图更合适。以省级GDP为例:
python复制from matplotlib.colors import LinearSegmentedColormap
# 自定义颜色渐变
cmap = LinearSegmentedColormap.from_list(
'mycmap', ['#FFFFFF', '#FF0000'])
m.readshapefile('CHN_adm_shp/CHN_adm1',
'provinces', drawbounds=True)
for info, shape in zip(m.provinces_info, m.provinces):
gdp = get_gdp_by_province(info['NAME_1']) # 自定义函数
color = cmap(gdp/max_gdp) # 归一化
patches = [Polygon(np.array(shape), closed=True, fc=color)]
plt.gca().add_collection(PatchCollection(patches))
现在我们把Seaborn和Basemap结合起来,完成一个从时间趋势到空间分布的全方位分析。假设我们有全国各城市分月的销售数据,要完成:
原始数据通常需要预处理:
python复制# 读取并清洗数据
df = pd.read_csv('national_sales.csv')
df['month'] = pd.to_datetime(df['date']).dt.month
df['city'] = df['city'].str.strip() # 去除城市名空格
# 处理异常值
df = df[(df['amount'] > 0) &
(df['amount'] < df['amount'].quantile(0.99))]
使用plt.subplots创建多视图:
python复制fig = plt.figure(figsize=(18, 12))
# 趋势分析
ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2)
monthly = df.groupby('month')['amount'].sum()
sns.lineplot(data=monthly, ax=ax1)
# 城市排名
ax2 = plt.subplot2grid((3, 3), (0, 2))
top_cities = df.groupby('city')['amount'].sum().nlargest(10)
sns.barplot(x=top_cities.values, y=top_cities.index, ax=ax2)
# 地理分布
ax3 = plt.subplot2grid((3, 3), (1, 0), colspan=3, rowspan=2)
m = Basemap(ax=ax3,
llcrnrlon=73, llcrnrlat=18,
urcrnrlon=135, urcrnrlat=53)
m.drawcoastlines()
for city, row in df.groupby('city').mean().iterrows():
x, y = m(row['lon'], row['lat'])
m.scatter(x, y, s=row['amount']/100, c='red', alpha=0.7)
在Jupyter中,可以结合ipywidgets创建动态可视化:
python复制from ipywidgets import interact
@interact(month=(1, 12))
def plot_monthly_sales(month):
month_data = df[df['month'] == month]
plt.figure(figsize=(12,8))
m = Basemap(llcrnrlon=73, llcrnrlat=18,
urcrnrlon=135, urcrnrlat=53)
m.drawcoastlines()
for _, row in month_data.iterrows():
x, y = m(row['lon'], row['lat'])
size = np.log(row['amount']) * 10 # 对数缩放
m.scatter(x, y, s=size, c=size, cmap='Reds')
这种可视化可以清晰展示销售活动的季节性迁移规律,比如冬季南方城市销量增长,北方则下降。