seaborn绘图(下)

多图网格

核心函数

sns.FaceGrid():分面网格,按字段生成子图矩阵

sns.PairGrid():成对网格,展示变量间的两两关系

sns.jointplot():联合图,展示双变量分布+单变量分布

关键参数

data:输入DataFrame

row/col:按字段分行/列生成子图

hue:分组字段

kind:子图类型('scatter'、'reg'、'kde'等)

实例

分面网格

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd


np.random.seed(123)

#POI日均曝光量
exposure = np.random.uniform(200, 800, size=800)
#POI线上推广投入
promotion = np.random.uniform(500, 3000, size=800)
#POI日均点击量
click = 0.7 * exposure + np.random.normal(0, 60, size=800)
#POI日均营业额
revenue = 120 * click + 0.5 * promotion + np.random.normal(0, 1000, size=800)

#
data = pd.DataFrame({
    #城市
    '城市': np.random.choice(['北京', '上海', '广州', '深圳'], size=800),
    #商圈类型
    '商圈类型': np.random.choice(['核心商圈', '区域商圈', '社区商圈'], size=800),
    # 时段
    '时段': np.random.choice(['工作日', '周末'], size=800, p=[0.6, 0.4]),
    # POI日均曝光量
    'poi日均曝光量': exposure,
    # POI线上推广投入
    'poi推广投入': promotion,
    #POI日均点击量
    'poi日均点击量': click,
    # POI日均营业额
    'poi日均营业额': revenue
})
numeric_cols = ['poi日均点击量', 'poi日均营业额']
data[numeric_cols] = data[numeric_cols].clip(lower=0)

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

sns.set_theme(style='whitegrid',font='SimHei',font_scale=1.0)
#单分面,按城市拆分,填充散点图,展示曝光量VS点击量
#创建分面网格
g1=sns.FacetGrid(
    data=data,
    col='城市',#按城市分列,每个城市一子图
    col_wrap=2,#每行显示2个子图
    hue='商圈类型',
    palette='coolwarm',
    height=4,#单个子图高度
    aspect=1.1#单个子图宽高比
    )
#为每个子图填充散点图
g1.map(sns.scatterplot,
       'poi日均曝光量', 'poi日均点击量',
       alpha=0.7,
       s=30#散点大小
       )

g1.add_legend(title='商圈类型',fontsize=5,loc='upper left')#将图例放在左上角
g1.set_titles('{col_name}')
g1.set_xlabels('POI日均曝光量')
g1.set_ylabels('POI日均点击量')
g1.figure.suptitle('各城市POI曝光量vs点击量', y=1.0)

#双分面,按时段、城市拆分,填充核密度图
#创建双分面网格
g2=sns.FacetGrid(
    data=data,
    row='时段',
    col='城市',
    hue='商圈类型',
    height=4,
    aspect=1.1
)
#为每个子图填充核密度图
g2.map(
    sns.kdeplot,
    'poi日均营业额',
    fill=True,
    alpha=0.4
)

g2.add_legend(title='商圈类型',fontsize=5,loc='upper left')
g2.set_titles('{row_name}-{col_name}')
g2.set_xlabels('POI日均营业额')
g2.set_ylabels('概率密度')
g2.figure.suptitle('各时段&城市POI营业额分布', y=1.0)

plt.tight_layout()
plt.show()

g1.map(plot_func, x, y, ..., **kwargs)

plot_func:必选参数,指定要填充到子图中的图表类型,这个参数只写函数名,不加括号

x, y:必选参数,指定传给plot_func的数据列名

成对网格

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd


np.random.seed(123)

#POI日均曝光量
exposure = np.random.uniform(200, 800, size=800)
#POI线上推广投入
promotion = np.random.uniform(500, 3000, size=800)
#POI日均点击量
click = 0.7 * exposure + np.random.normal(0, 60, size=800)
#POI日均营业额
revenue = 120 * click + 0.5 * promotion + np.random.normal(0, 1000, size=800)

#
data = pd.DataFrame({
    #城市
    '城市': np.random.choice(['北京', '上海', '广州', '深圳'], size=800),
    #商圈类型
    '商圈类型': np.random.choice(['核心商圈', '区域商圈', '社区商圈'], size=800),
    # 时段
    '时段': np.random.choice(['工作日', '周末'], size=800, p=[0.6, 0.4]),
    # POI日均曝光量
    'poi日均曝光量': exposure,
    # POI线上推广投入
    'poi推广投入': promotion,
    #POI日均点击量
    'poi日均点击量': click,
    # POI日均营业额
    'poi日均营业额': revenue
})
numeric_cols = ['poi日均点击量', 'poi日均营业额']
data[numeric_cols] = data[numeric_cols].clip(lower=0)

plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False

sns.set_theme(style='whitegrid',font='SimHei',font_scale=1.0)
#自定义数值字段,hue分组
#创建成对网格,指定要分析的字段
vars = ['poi日均曝光量', 'poi推广投入', 'poi日均点击量', 'poi日均营业额']
g1=sns.PairGrid(
    data=data,
    vars=vars,#指定要展示两两关系的数值字段
    hue='商圈类型',
    palette='coolwarm',
    height=2.8,#单个子图高度
    aspect=1.0,#单个子图宽高比
    diag_sharey=False#对角线子图不共享Y轴,避免分布图形变形
    )
#为每个子图填充图
g1.map_diag(sns.kdeplot,#对角线:单变量核密度图
       fill=True,
       alpha=0.7
       )
g1.map_offdiag(sns.scatterplot,alpha=0.6,s=20)#非对角线:双变量散点图
g1.add_legend(title='商圈类型',fontsize=6,loc='upper right')#将图例放在左上角
g1.figure.suptitle('POI运营指标两两关系', y=1.0)
plt.tight_layout()
plt.show()

#非对角线改为回归图
g2=sns.PairGrid(
    data=data,
    vars=['poi日均曝光量', 'poi日均点击量', 'poi日均营业额'],
    hue='商圈类型',
    height=2.8,
    aspect=1.0,
    diag_sharey=False
)
g2.map_diag(sns.histplot, kde=True, alpha=0.6)  # 对角线:直方图+核密度曲线
g2.map_offdiag(sns.regplot, scatter_kws={'alpha': 0.4, 's': 15}, line_kws={'linewidth': 1})  # 非对角线:回归图

g2.add_legend(title='商圈类型',fontsize=6,loc='upper right')
g2.figure.suptitle('POI核心指标两两回归关系', y=1.0)

plt.tight_layout()
plt.show()

样式与调色板

样式管理

sns.set_style():预设风格('white' 'dark' 'whitegrid' 'darkgrid' 'ticks')

sns.despine():移除图表的上/右边框

sns.set_context():设置绘图上下文('paper' 'notebook' 'talk' 'poster'),核心作用就是规范预设的尺寸,实现「一键缩放」整个图表的元素大小,而不改变图表的样式、配色和逻辑结构。

调色板

sns.color_palette():创建获取调色板

分类调色板:'husl' 'tab10' 'Set2'

连续调色板:'viridis' 'coolwarm' 'rocket'

发散调色板:'vlag' 'icefire'

在seaborn绘图(上)一章中第一个代码的基础上,进行美化

python 复制代码
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
 
data=pd.DataFrame(
    {
        '城市':['北京','上海','广州','深圳','杭州']*4,
        '季度':['Q1','Q2','Q3','Q4']*5,
        'poi新增量':np.random.randint(500,2000,20)
    }
)
 

#设置自定义风格
sns.set_style('darkgrid',{'axes.facecolor':'#f5f5f5'})
sns.set_context('notebook',font_scale=1.0)
palette=sns.set_palette(['#2ecc71','#3498db','#f1c40f','#e74c3c'])
 
#创建画布
fig,ax=plt.subplots(figsize=(10,6))
#绘制基础柱状图
sns.barplot(
    data=data,
    x='城市',
    y='poi新增量',
    hue='季度', #按季度分组
    palette=palette,
    alpha=0.6,
    ax=ax#指定将柱状图绘制在前面创建的坐标系ax上,如不指定,会自动创建一个新的坐标系
)

plt.rcParams['font.sans-serif']=['Microsoft YaHei']
plt.rcParams['axes.unicode_minus']=False
#添加元素
ax.set_title('各城市季度poi新增量对比')
ax.set_xlabel('城市')
ax.set_ylabel('poi新增量')
#美化
sns.despine(top=True,right=True)#移除上/右边框
plt.tight_layout()#自动调整图表中各元素的位置和间距
plt.show()

运行中遇到的问题:即使设置了中文配置问题的解决,但仍显示为方块。

原因:将plt.rcParams['font.sans-serif']=['SimHei']写在了sns.set_style()sns.set_context()前面;这两个函数会重新初始化部分 Matplotlib 的绘图参数,其中就包含字体相关配置,相当于把之前设置的「黑体」给覆盖掉了,恢复了 Seaborn 的默认字体。

解决:调换代码的先后顺序,Seaborn 的配置函数(set_style()/set_context())要放在 Matplotlib 的中文配置之前。

Kepler.gl地理数据可视化

Kepler.gl是Uber开源的高性能地理数据可视化工具,支持大规模点、线、面数据的交互可视化,无需前端开发即可制作专业地图

关键操作

KeplerGl():创建地图实例

python 复制代码
KeplerGl(
    data=None,  # 直接传入数据集,支持DataFrame/GeoJSON格式
    config=None,  # 地图配置(样式、图层、交互规则等,默认自动生成)
    height=600,  # 地图高度(像素),默认600
    width=None,  # 地图宽度(像素),默认None
    read_only=False  #是否只读(禁止修改地图配置),默认False
)

add_data():添加数据集

python 复制代码
map_instance.add_data(
    data,  # 必选,地理数据集(pandas.DataFrame 或 GeoJSON)
    name=None,  # 数据集名称
    overwrite=False  # 是否覆盖已存在的同名数据集,默认False
)

save_to_html():保存为可交互的HTML文件

python 复制代码
map_instance.save_to_html(
    file_name='keplergl_map.html',  #保存的HTML文件名(含路径),默认#keplergl_map.html
    config=None,  #额外传入的地图配置(覆盖地图实例中的配置)
    read_only=False  #是否设置为只读模式,默认False
)

完整代码

python 复制代码
from keplergl import KeplerGl
import pandas as pd

#实验数据(必须包含经纬度)
city_poi_data = pd.DataFrame({
    '城市': ['北京', '上海', '广州', '深圳', '杭州', '成都', '重庆'],
    '季度': ['Q3', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3', 'Q3'],
    '经度': [116.4074, 121.4737, 113.2644, 114.0579, 120.1590, 104.0657, 106.5049],
    '纬度': [39.9042, 31.2304, 23.1291, 22.5431, 30.2795, 30.6594, 29.5630],
    'POI新增量': [1800, 1950, 1700, 1650, 1500, 1400, 1350]
})


#创建地图实例
poi_map=KeplerGl(height=800,read_only=False)
#添加数据集
poi_map.add_data(data=city_poi_data,name='各城市第三季度poi新增量')
#保存为可分享的HTML文件
poi_map.save_to_html(file_name=r'C:\Users\Lenovo\Desktop\Python\visualize.html')

感觉渲染得好慢,不好用不好用。

相关推荐
半路_出家ren2 小时前
3.python模拟勒索病毒
python·网络安全·密码学·网络攻击模型·base64·病毒·勒索病毒
jhf20202 小时前
2026汽车4S店GEO优化高性价比公司选型指南:从效果、成本到适配
python·汽车
叫我:松哥2 小时前
基于scrapy的网易云音乐数据采集与分析设计实现
python·信息可视化·数据分析·beautifulsoup·numpy·pandas
极智-9962 小时前
GitHub 热榜项目-日榜精选(2026-01-24)| AI智能体工具、Python生态等 | remotion、VibeVoice、goose等
人工智能·python·github·ai智能体·大模型部署·语音ai
YMLT花岗岩3 小时前
Python学习之-函数-入门训练-具有多个返回值的函数
python·学习
北鹤M3 小时前
用MeteoStat计算任意时刻经纬度真实气象数据
人工智能·python
星瞳科技OpenMV3 小时前
星瞳OpenMV官方机械臂教程|从零开始:Robot Arm机械臂快速上手
arm开发·图像处理·python·计算机视觉·ai·机器人·openmv
写代码的【黑咖啡】3 小时前
Python中的lxml:高效XML处理库
xml·开发语言·python
人工智能AI技术3 小时前
【Agent从入门到实践】29 开发第一个Agent——需求定义
人工智能·python