如何通过Scatter Plot with 2 Y-axis完整呈现表格全量信息?含多维度配置
双Y轴散点图全量数据可视化实现方案
核心思路
将分类字段source_city、destination_city转换为可映射到Y轴的数值编码,以price为X轴变量,每个散点标注对应airline信息,通过双Y轴分别展示出发/到达城市与价格的关联,确保表格全量信息完整呈现。
具体实现步骤(Python + Matplotlib)
1. 数据预处理
- 对
source_city和destination_city做分类编码,将城市名称映射为唯一数值(便于Y轴绘制) - 确保
price字段为数值类型
2. 完整代码示例
import matplotlib.pyplot as plt import pandas as pd from sklearn.preprocessing import LabelEncoder # 替换为你的实际表格数据 data = pd.DataFrame({ 'source_city': ['Delhi', 'Mumbai', 'Bangalore', 'Delhi', 'Mumbai'], 'destination_city': ['Mumbai', 'Delhi', 'Delhi', 'Bangalore', 'Bangalore'], 'price': [5000, 4800, 6200, 5500, 5900], 'airline': ['Indigo', 'Air India', 'SpiceJet', 'Indigo', 'Air India'] }) # 城市分类变量编码 le_source = LabelEncoder() le_dest = LabelEncoder() data['source_code'] = le_source.fit_transform(data['source_city']) data['dest_code'] = le_dest.fit_transform(data['destination_city']) # 创建画布与主Y轴 fig, ax1 = plt.subplots(figsize=(10, 6)) # 主Y轴:出发城市散点 scatter_source = ax1.scatter(data['price'], data['source_code'], color='#1f77b4', s=120) ax1.set_xlabel('Price', fontsize=12) ax1.set_ylabel('Source City', color='#1f77b4', fontsize=12) ax1.tick_params(axis='y', labelcolor='#1f77b4') # 替换Y轴刻度为原城市名称 ax1.set_yticks(range(len(le_source.classes_))) ax1.set_yticklabels(le_source.classes_) # 创建副Y轴(共享X轴) ax2 = ax1.twinx() # 副Y轴:到达城市散点 scatter_dest = ax2.scatter(data['price'], data['dest_code'], color='#ff7f0e', s=120, marker='^') ax2.set_ylabel('Destination City', color='#ff7f0e', fontsize=12) ax2.tick_params(axis='y', labelcolor='#ff7f0e') # 替换Y轴刻度为原城市名称 ax2.set_yticks(range(len(le_dest.classes_))) ax2.set_yticklabels(le_dest.classes_) # 为每个散点添加航空公司标签 for idx, row in data.iterrows(): ax1.annotate(row['airline'], (row['price'], row['source_code']), xytext=(5, 3), textcoords='offset points', fontsize=9) ax2.annotate(row['airline'], (row['price'], row['dest_code']), xytext=(5, 3), textcoords='offset points', fontsize=9) # 添加图例与标题 plt.legend([scatter_source, scatter_dest], ['Source City', 'Destination City'], loc='upper left') plt.title('Price vs City Pair (Airline as Data Label)', fontsize=14) plt.tight_layout() plt.show()
3. 关键细节优化
- 分类编码还原:编码后将Y轴刻度替换为原城市名称,避免数值编码降低可读性
- 双轴区分:用不同颜色、标记样式区分两个Y轴的散点,减少视觉混淆
- 标签定位:通过
xytext微调标签位置,避免遮挡散点 - 布局适配:用
tight_layout()自动调整元素位置,防止内容截断
替代方案(Seaborn风格实现)
若偏好更简洁的统计绘图风格,可使用Seaborn配合双Y轴:
import seaborn as sns fig, ax1 = plt.subplots(figsize=(10, 6)) # 主Y轴:出发城市散点(按航空公司区分颜色) sns.scatterplot(data=data, x='price', y='source_code', hue='airline', ax=ax1, s=150) ax1.set_ylabel('Source City', color='#1f77b4', fontsize=12) ax1.set_yticks(range(len(le_source.classes_))) ax1.set_yticklabels(le_source.classes_) # 副Y轴:到达城市散点 ax2 = ax1.twinx() sns.scatterplot(data=data, x='price', y='dest_code', hue='airline', ax=ax2, marker='s', s=150) ax2.set_ylabel('Destination City', color='#ff7f0e', fontsize=12) ax2.set_yticks(range(len(le_dest.classes_))) ax2.set_yticklabels(le_dest.classes_) plt.title('Price vs City Pair with Airline Labels', fontsize=14) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Raj Mehta
相关产品推荐
相关产品推荐

