Plotly中go.Scatter实现strip图可行性及代码转换为px.strip的技术咨询
Plotly中go.Scatter实现strip图可行性及代码转换为px.strip的技术咨询
问题描述
用户提问:Is it possible to do the strip with go.scatter ? If not, can you help me in transforming my code with px.strip function ?
数据生成代码
import pandas as pd import random # 生成df_test rows = [] for i in range(0, 130, 1): rows.append([i+57, i+39585, [random.randint(1,100) for _ in range(15)]]) df_test = pd.DataFrame(rows, columns=['Measure Number', 'Timer', 'Values']) display(df_test) # 生成df_test2 rows2 = [] for i in range(70, 200, 1): rows2.append([i+57, i+39585, [random.randint(1,100) for _ in range(15)]]) df_test2 = pd.DataFrame(rows2, columns=['Measure Number', 'Timer', 'Values']) display(df_test2) # 生成df_test3 rows3 = [] for i in range(170, 300, 1): rows3.append([i+57, i+39585, [random.randint(1,100) for _ in range(15)]]) df_test3 = pd.DataFrame(rows3, columns=['Measure Number', 'Timer', 'Values']) display(df_test3)
原Plotly绘图代码
from plotly.offline import init_notebook_mode, iplot from plotly.graph_objs import * import plotly.graph_objects as go import plotly.express as px init_notebook_mode(connected=True) # 初始化离线绘图环境 fig = go.Figure() for i in range(0, 130, 1): # 添加df_test对应的散点 fig.add_trace( go.Scatter( x=[j for j in range(15)], y=df_test['Values'][i], mode="markers", marker=dict(color="DarkOrange") ) ) # 添加df_test2对应的散点 fig.add_trace( go.Scatter( x=[j for j in range(15)], y=df_test2['Values'][i], mode="markers", marker=dict(color="Crimson") ) ) # 添加df_test3对应的散点 fig.add_trace( go.Scatter( x=[j for j in range(15)], y=df_test3['Values'][i], mode="markers", marker=dict(color="RebeccaPurple") ) ) fig.show()
当前绘图效果

需求说明
用户希望将当前重叠严重的散点图转换为strip图(带状图),让同一位置的点分散开,解决点重叠问题,实现更清晰的分布展示。
解答
1. 用go.Scatter实现strip图的可行性
其实用go.Scatter是能实现strip图的,但过程会比较麻烦。因为strip图的核心是把同一位置上重叠的点沿水平方向分散开,而go.Scatter本身没有内置这个分散逻辑,得咱们自己手动给每个点计算偏移量——比如加个随机小偏移,或者按顺序排列偏移,代码量会大很多,远不如直接用px.strip来得省心高效。
2. 转换为px.strip的代码实现
要用上px.strip,首先得把咱们现在的数据格式调整成长格式(整洁表结构),因为Plotly Express的函数一般都要求数据是这种结构,而不是每个单元格存个列表的宽表。
步骤1:数据格式转换
把三个DataFrame合并,并将Values列展开成单独的行,同时添加分组标签区分不同的数据源:
import pandas as pd import random # 简化数据生成逻辑 def generate_df(start, end): rows = [] for i in range(start, end, 1): rows.append([i+57, i+39585, [random.randint(1,100) for _ in range(15)]]) df = pd.DataFrame(rows, columns=['Measure Number', 'Timer', 'Values']) return df df_test = generate_df(0, 130) df_test2 = generate_df(70, 200) df_test3 = generate_df(170, 300) # 给每个数据集添加分组标签 df_test['Group'] = 'DarkOrange' df_test2['Group'] = 'Crimson' df_test3['Group'] = 'RebeccaPurple' # 合并三个数据集 combined_df = pd.concat([df_test, df_test2, df_test3], ignore_index=True) # 展开Values列,把列表中的每个值拆成单独行 long_df = combined_df.explode('Values', ignore_index=True) # 将Values转为数值类型 long_df['Values'] = long_df['Values'].astype(int) # 添加x轴位置标签(对应原来的0-14索引) long_df['X_Position'] = long_df.groupby(['Measure Number', 'Timer']).cumcount()
步骤2:用px.strip绘制带状图
import plotly.express as px fig = px.strip(long_df, x='X_Position', y='Values', color='Group', color_discrete_map={'DarkOrange': 'DarkOrange', 'Crimson': 'Crimson', 'RebeccaPurple': 'RebeccaPurple'}, hover_data=['Measure Number', 'Timer']) # 调整布局让图更清晰 fig.update_layout(title='Strip Plot with px.strip', xaxis_title='Position Index', yaxis_title='Value') fig.show()
代码说明
- 数据转换:通过
explode把每个列表中的值拆成单独的行,让每个点都有对应的x位置、y值和分组标签,完全符合px.strip的输入要求。 - px.strip参数:
x指定水平轴的类别(这里是原来的0-14位置索引),y是数值,color区分不同数据源,color_discrete_map保持你原来的颜色设置不变。 - 优势:px.strip会自动处理点的重叠问题,把同一x位置的点沿水平方向分散开,生成清晰的带状图,不需要手动计算偏移量,代码更简洁易维护。
备注:内容来源于stack exchange,提问作者Sparrow
相关产品推荐
相关产品推荐

