You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python象限图中心十字线绘制异常问题的修复咨询

象限图中心十字线异常修复方案

问题描述

我编写了如下Python代码用于生成象限图,但图表的中心十字线位置不正确,需要修复。

原代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
import seaborn as sns

# 数据准备
data = pd.DataFrame({
    'label': ['Luis', 'Sara', 'Jeroen', 'Sophie', 'Florence', 'Simeon', 'Lambert', 'Rahul', 'Peter', 'John'],
    'Data Culture': [0, 5, 10, 15, 20, 18, 13, 9, 4, 1],
    'Data Skills': [20, 15, 10, 5, 0, 3, 7, 11, 16, 18]
})
print(data)

fig = px.scatter(data, x=data["Data Culture"], y=data["Data Skills"], text=data.label, 
                 title='Data Culture vs Data Skills',
                 width=800, height=600)

# 计算平均值
x_avg = data['Data Culture'].mean()
y_avg = data['Data Skills'].mean()

# 添加横竖线(原代码问题所在)
fig.add_vline(x=10, line_width=3, opacity=0.5)
fig.add_hline(y=10, line_width=3, opacity=0.5)

# 设置X轴范围
adj_x = max((data['Data Culture'].max() - x_avg), (x_avg - data['Data Culture'].min())) * 1.1
lb_x, ub_x = (x_avg - adj_x, x_avg + adj_x)
fig.update_xaxes(range = [lb_x, ub_x])

# 设置Y轴范围
adj_y = max((data['Data Skills'].max() - y_avg), (y_avg - data['Data Skills'].min())) * 1.1
lb_y, ub_y = (y_avg - adj_y, y_avg + adj_y)
fig.update_yaxes(range = [lb_y, ub_y])

# 更新X轴刻度标签
axis = ['Low', 'High']     
fig.update_layout(
    xaxis_title='Data Culture',
    xaxis = dict(
        tickmode = 'array',
        tickvals = ([(x_avg - adj_x / 2), (x_avg + adj_x / 2)]),
        ticktext = axis
      )
)

# 更新Y轴刻度标签
fig.update_layout(
    yaxis_title='Data Skills',
    yaxis = dict(
        tickmode = 'array',
        tickvals = ([(y_avg - adj_y / 2), (y_avg + adj_y / 2)]),
        ticktext = axis,
        tickangle=270
    )
) 

# 更新标题和边距(原代码有重复设置)
fig.update_layout(margin=dict(t=50, l=5, r=5, b=50),
    title={'text': 'pl',
           'font_size': 20,
           'y':1.0,
           'x':0.5,
           'xanchor': 'center',
           'yanchor': 'top'})

# 添加象限标注
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=0, y=-0.15,
                        text="Han Solo",
                        xref='paper',
                        yref='paper', 
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=1, y=-0.15,
                        text="Young Padawan",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=0, y=1.15,
                        text="Baby Yoda",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=1, y=1.15,
                        text="Yoda",
                        xref='paper',
                        yref='paper',
                        showarrow=False))

fig.update_layout(
    margin=dict(l=20, r=20, t=100, b=100),
)

fig.show()

版本信息

import pandas as pd
import numpy as np
import matplotlib
import plotly
import seaborn as sns

print("Pandas: ",  pd.__version__)
print("numpy: ", np.__version__)
print("matplotlib: ",matplotlib.__version__)
print("seaborn: ", sns.__version__)
print("Plotly: ",plotly.__version__)

# 输出结果
Pandas:  1.1.5
numpy:  1.21.6
matplotlib:  3.2.1
seaborn:  0.11.2
Plotly:  5.10.0

问题原因

原代码中绘制十字线时使用了固定值x=10和y=10,但后续代码是基于数据的平均值x_avg和y_avg调整坐标轴范围的,导致十字线与坐标轴中心不重合。

修复方案

将绘制横竖线的固定值替换为计算出的平均值x_avg和y_avg,同时合并重复的布局设置优化代码结构:

修改后的核心代码片段

# 计算平均值
x_avg = data['Data Culture'].mean()
y_avg = data['Data Skills'].mean()

# 添加居中的横竖线(修复后)
fig.add_vline(x=x_avg, line_width=3, opacity=0.5)
fig.add_hline(y=y_avg, line_width=3, opacity=0.5)

完整修复后代码

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go

# 数据准备
data = pd.DataFrame({
    'label': ['Luis', 'Sara', 'Jeroen', 'Sophie', 'Florence', 'Simeon', 'Lambert', 'Rahul', 'Peter', 'John'],
    'Data Culture': [0, 5, 10, 15, 20, 18, 13, 9, 4, 1],
    'Data Skills': [20, 15, 10, 5, 0, 3, 7, 11, 16, 18]
})

fig = px.scatter(data, x="Data Culture", y="Data Skills", text="label", 
                 width=800, height=600)

# 计算平均值
x_avg = data['Data Culture'].mean()
y_avg = data['Data Skills'].mean()

# 添加居中的十字线
fig.add_vline(x=x_avg, line_width=3, opacity=0.5)
fig.add_hline(y=y_avg, line_width=3, opacity=0.5)

# 设置X轴范围
adj_x = max((data['Data Culture'].max() - x_avg), (x_avg - data['Data Culture'].min())) * 1.1
lb_x, ub_x = (x_avg - adj_x, x_avg + adj_x)
fig.update_xaxes(range=[lb_x, ub_x])

# 设置Y轴范围
adj_y = max((data['Data Skills'].max() - y_avg), (y_avg - data['Data Skills'].min())) * 1.1
lb_y, ub_y = (y_avg - adj_y, y_avg + adj_y)
fig.update_yaxes(range=[lb_y, ub_y])

# 更新坐标轴标签与刻度
axis_labels = ['Low', 'High']
fig.update_layout(
    xaxis_title='Data Culture',
    xaxis=dict(
        tickmode='array',
        tickvals=[x_avg - adj_x/2, x_avg + adj_x/2],
        ticktext=axis_labels
    ),
    yaxis_title='Data Skills',
    yaxis=dict(
        tickmode='array',
        tickvals=[y_avg - adj_y/2, y_avg + adj_y/2],
        ticktext=axis_labels,
        tickangle=270
    ),
    # 统一设置边距和标题
    margin=dict(t=100, l=20, r=20, b=100),
    title={
        'text': 'Data Culture vs Data Skills',
        'font_size': 20,
        'x': 0.5,
        'xanchor': 'center',
        'yanchor': 'top'
    }
)

# 添加象限标注
fig.add_annotation(
    font=dict(color="black", size=18),
    x=0, y=-0.15,
    text="Han Solo",
    xref='paper', yref='paper',
    showarrow=False
)
fig.add_annotation(
    font=dict(color="black", size=18),
    x=1, y=-0.15,
    text="Young Padawan",
    xref='paper', yref='paper',
    showarrow=False
)
fig.add_annotation(
    font=dict(color="black", size=18),
    x=0, y=1.15,
    text="Baby Yoda",
    xref='paper', yref='paper',
    showarrow=False
)
fig.add_annotation(
    font=dict(color="black", size=18),
    x=1, y=1.15,
    text="Yoda",
    xref='paper', yref='paper',
    showarrow=False
)

fig.show()

修复效果

修改后,十字线会准确对齐坐标轴的中心(即数据平均值位置),与后续基于平均值调整的坐标轴范围完全匹配,解决了十字线偏移的问题。

内容的提问来源于stack exchange,提问作者Luis Valencia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:40:34