如何使用Python绘制含标签的分类XY数据(如BCG矩阵)避免同值标签重叠
Python可以完美实现你的需求,核心通过adjustText库解决同坐标标签重叠问题,完整实现方案如下:
依赖安装
首先安装所需第三方库:
pip install pandas matplotlib adjusttext
完整实现代码
import pandas as pd import matplotlib.pyplot as plt from adjustText import adjust_text # 读入自有数据可以用以下代码读取csv # df = pd.read_csv('your_data.csv') # 以下内置示例数据可直接运行测试 data = [ ["A","topic_1",2,4],["B","topic_2",4,2],["C","topic_3",3,3],["D","topic_4",3,5],["E","topic_5",3,4], ["F","topic_6",5,1],["G","topic_7",4,5],["H","topic_8",1,2],["I","topic_9",4,1],["J","topic_10",3,3], ["K","topic_11",5,5],["L","topic_12",5,3],["M","topic_13",3,5],["N","topic_14",1,5],["O","topic_15",4,1], ["P","topic_16",4,2],["Q","topic_17",1,5],["R","topic_18",2,3],["S","topic_19",1,2],["T","topic_20",5,1], ["U","topic_21",3,4],["V","topic_22",2,5],["W","topic_23",1,3],["X","topic_24",3,3],["Y","topic_25",4,1], ["Z","topic_26",2,4],["1","topic_27",2,4],["2","topic_28",5,4],["3","topic_29",3,3],["4","topic_30",4,4], ["5","topic_31",3,2],["6","topic_32",4,2],["7","topic_33",2,3],["8","topic_34",2,3],["9","topic_35",2,5], ["10","topic_36",4,2] ] df = pd.DataFrame(data, columns=["ID","Name","value_A","value_B"]) # 计算BCG矩阵分割阈值,默认取两个维度的中位数,也可以自定义固定值比如 threshold_a = 3 threshold_a = df['value_A'].median() threshold_b = df['value_B'].median() # 初始化画布 plt.figure(figsize=(10,10), dpi=100) texts = [] # 遍历数据添加标记和ID标签 for idx, row in df.iterrows(): # 半透明散点标记坐标位置 plt.scatter(row['value_A'], row['value_B'], c='gray', alpha=0.3, s=50) # 收集文本对象用于后续自动调整位置 texts.append(plt.text(row['value_A'], row['value_B'], row['ID'], fontsize=12)) # 绘制BCG十字分割线 plt.axvline(x=threshold_a, c='black', linestyle='--') plt.axhline(y=threshold_b, c='black', linestyle='--') # 自动调整文本位置解决重叠,参数可根据显示效果调整 adjust_text( texts, force_text=0.5, # 文本之间的排斥力,数值越大间距越宽 expand=(1.2, 1.2), # 文本和原坐标的距离系数,数值越小越贴近原点位 arrowprops=dict(arrowstyle='-', color='gray', lw=0.5) # 重叠较多时可加细线连回原坐标,不需要可以删掉该行 ) # 调整图表样式 plt.xlim(df['value_A'].min()-0.5, df['value_A'].max()+0.5) plt.ylim(df['value_B'].min()-0.5, df['value_B'].max()+0.5) plt.xlabel('value_A', fontsize=14) plt.ylabel('value_B', fontsize=14) plt.title('BCG矩阵', fontsize=16) plt.grid(alpha=0.2) plt.show()
补充说明
- 上述代码支持超过50个主题的数据集调整,可通过修改
adjust_text的参数适配不同密度的数据 - 不需要代码的场景可以用Tableau实现:导入数据后选择散点图,标签设置为ID,打开标签的「避免重叠」开关,选择自动排列即可
内容的提问来源于stack exchange,提问作者StefanOverFlow
相关产品推荐
相关产品推荐

