【问题标题】:Plotly: Dodge overlapping points on scatterplot categorical axisPlotly:在散点图分类轴上躲避重叠点
【发布时间】:2020-11-06 04:30:49
【问题描述】:

我正在尝试使用 plotly 来比较回归模型的系数,使用误差条作为置信区间。我使用下面的代码来绘制它,使用变量作为散点图中的分类y 轴。问题是这些点是重叠的,我想像设置barmode='group' 时在条形图中发生的那样避开它们。如果我有一个数字轴,我可以手动躲避它们,但我做不到。

fig = px.scatter(
        df, y='index', x='coef', text='label', color='model',
        error_x_minus='lerr', error_x='uerr',
        hover_data=['coef', 'pvalue', 'lower', 'upper']
    )
fig.update_traces(textposition='top center')
fig.update_yaxes(autorange="reversed")

使用构面,我几乎得到了我想要的结果,但有些标签偏离了情节并且不可见:

fig = px.scatter(
    df, y='model', x='coef', text='label', color='model',
    facet_row='index',
    error_x_minus='lerr', error_x='uerr',
    hover_data=['coef', 'pvalue', 'lower', 'upper']
)
fig.update_traces(textposition='top center')
fig.update_yaxes(visible=False)
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))

有人对在第一种情况下躲避点或在第二种情况下显示标签有任何想法或解决方法吗?

提前致谢。

PS:这是我为生成图而制作的随机假数据框:

df = pd.DataFrame({'coef': {0: 1.0018729737113143,
  1: 0.9408864645423858,
  2: 0.29796556981484884,
  3: -0.6844053575764955,
  4: -0.13689631932690113,
  5: 0.1473096200402363,
  6: 0.9564712505670716,
  7: 0.956099003887811,
  8: 0.33319108930207175,
  9: -0.7022778825729681,
  10: -0.1773916842612131,
  11: 0.09485417304851751},
 'index': {0: 'const',
  1: 'x1',
  2: 'x2',
  3: 'x3',
  4: 'x4',
  5: 'x5',
  6: 'const',
  7: 'x1',
  8: 'x2',
  9: 'x3',
  10: 'x4',
  11: 'x5'},
 'label': {0: '1.002***',
  1: '0.941***',
  2: '0.298***',
  3: '-0.684***',
  4: '-0.137',
  5: '0.147',
  6: '0.956***',
  7: '0.956***',
  8: '0.333***',
  9: '-0.702***',
  10: '-0.177',
  11: '0.095'},
 'lerr': {0: 0.19788416996400904,
  1: 0.19972987383410545,
  2: 0.0606849959013587,
  3: 0.1772734289533593,
  4: 0.1988122854078155,
  5: 0.21870366703236832,
  6: 0.2734783191688098,
  7: 0.2760291042678362,
  8: 0.08386739920069491,
  9: 0.2449940255063039,
  10: 0.27476098595116555,
  11: 0.3022511162310027},
 'lower': {0: 0.8039888037473053,
  1: 0.7411565907082803,
  2: 0.23728057391349014,
  3: -0.8616787865298547,
  4: -0.33570860473471664,
  5: -0.07139404699213203,
  6: 0.6829929313982618,
  7: 0.6800698996199748,
  8: 0.24932369010137684,
  9: -0.947271908079272,
  10: -0.45215267021237865,
  11: -0.2073969431824852},
 'model': {0: 'OLS',
  1: 'OLS',
  2: 'OLS',
  3: 'OLS',
  4: 'OLS',
  5: 'OLS',
  6: 'QuantReg',
  7: 'QuantReg',
  8: 'QuantReg',
  9: 'QuantReg',
  10: 'QuantReg',
  11: 'QuantReg'},
 'pvalue': {0: 1.4211692095019375e-16,
  1: 4.3583690618389965e-15,
  2: 6.278403727223468e-16,
  3: 1.596372747840846e-11,
  4: 0.17483151363955116,
  5: 0.18433051296752084,
  6: 4.877385844808361e-10,
  7: 6.665860891682504e-10,
  8: 5.476882838731488e-12,
  9: 1.4240852942202845e-07,
  10: 0.20303143985022934,
  11: 0.5347222575215599},
 'uerr': {0: 0.19788416996400904,
  1: 0.19972987383410556,
  2: 0.06068499590135873,
  3: 0.1772734289533593,
  4: 0.19881228540781554,
  5: 0.21870366703236832,
  6: 0.27347831916880994,
  7: 0.2760291042678362,
  8: 0.08386739920069491,
  9: 0.2449940255063039,
  10: 0.27476098595116555,
  11: 0.3022511162310027},
 'upper': {0: 1.1997571436753234,
  1: 1.1406163383764913,
  2: 0.35865056571620757,
  3: -0.5071319286231362,
  4: 0.0619159660809144,
  5: 0.3660132870726046,
  6: 1.2299495697358815,
  7: 1.2321281081556472,
  8: 0.41705848850276667,
  9: -0.4572838570666642,
  10: 0.09736930168995245,
  11: 0.3971052892795202}})

【问题讨论】:

    标签: python plotly plotly-python plotly-express


    【解决方案1】:

    您的第二次尝试非常接近可行的解决方案。只需为您的标签腾出更多空间:

    height=600, width=800
    

    然后将名为'OLS' 的轨迹的标签放置在每个子图的边界内:

    fig.for_each_trace(lambda t: t.update(textposition='bottom center') if t.name == 'OLS' else ())
    

    剧情:

    完整代码:

    import plotly.express as px
    import pandas as pd
    
    df = pd.DataFrame({'coef': {0: 1.0018729737113143,
      1: 0.9408864645423858,
      2: 0.29796556981484884,
      3: -0.6844053575764955,
      4: -0.13689631932690113,
      5: 0.1473096200402363,
      6: 0.9564712505670716,
      7: 0.956099003887811,
      8: 0.33319108930207175,
      9: -0.7022778825729681,
      10: -0.1773916842612131,
      11: 0.09485417304851751},
     'index': {0: 'const',
      1: 'x1',
      2: 'x2',
      3: 'x3',
      4: 'x4',
      5: 'x5',
      6: 'const',
      7: 'x1',
      8: 'x2',
      9: 'x3',
      10: 'x4',
      11: 'x5'},
     'label': {0: '1.002***',
      1: '0.941***',
      2: '0.298***',
      3: '-0.684***',
      4: '-0.137',
      5: '0.147',
      6: '0.956***',
      7: '0.956***',
      8: '0.333***',
      9: '-0.702***',
      10: '-0.177',
      11: '0.095'},
     'lerr': {0: 0.19788416996400904,
      1: 0.19972987383410545,
      2: 0.0606849959013587,
      3: 0.1772734289533593,
      4: 0.1988122854078155,
      5: 0.21870366703236832,
      6: 0.2734783191688098,
      7: 0.2760291042678362,
      8: 0.08386739920069491,
      9: 0.2449940255063039,
      10: 0.27476098595116555,
      11: 0.3022511162310027},
     'lower': {0: 0.8039888037473053,
      1: 0.7411565907082803,
      2: 0.23728057391349014,
      3: -0.8616787865298547,
      4: -0.33570860473471664,
      5: -0.07139404699213203,
      6: 0.6829929313982618,
      7: 0.6800698996199748,
      8: 0.24932369010137684,
      9: -0.947271908079272,
      10: -0.45215267021237865,
      11: -0.2073969431824852},
     'model': {0: 'OLS',
      1: 'OLS',
      2: 'OLS',
      3: 'OLS',
      4: 'OLS',
      5: 'OLS',
      6: 'QuantReg',
      7: 'QuantReg',
      8: 'QuantReg',
      9: 'QuantReg',
      10: 'QuantReg',
      11: 'QuantReg'},
     'pvalue': {0: 1.4211692095019375e-16,
      1: 4.3583690618389965e-15,
      2: 6.278403727223468e-16,
      3: 1.596372747840846e-11,
      4: 0.17483151363955116,
      5: 0.18433051296752084,
      6: 4.877385844808361e-10,
      7: 6.665860891682504e-10,
      8: 5.476882838731488e-12,
      9: 1.4240852942202845e-07,
      10: 0.20303143985022934,
      11: 0.5347222575215599},
     'uerr': {0: 0.19788416996400904,
      1: 0.19972987383410556,
      2: 0.06068499590135873,
      3: 0.1772734289533593,
      4: 0.19881228540781554,
      5: 0.21870366703236832,
      6: 0.27347831916880994,
      7: 0.2760291042678362,
      8: 0.08386739920069491,
      9: 0.2449940255063039,
      10: 0.27476098595116555,
      11: 0.3022511162310027},
     'upper': {0: 1.1997571436753234,
      1: 1.1406163383764913,
      2: 0.35865056571620757,
      3: -0.5071319286231362,
      4: 0.0619159660809144,
      5: 0.3660132870726046,
      6: 1.2299495697358815,
      7: 1.2321281081556472,
      8: 0.41705848850276667,
      9: -0.4572838570666642,
      10: 0.09736930168995245,
      11: 0.3971052892795202}})
    
    fig = px.scatter(
        df, y='model', x='coef', text='label', color='model',
        facet_row='index',
        error_x_minus='lerr', error_x='uerr',
        hover_data=['coef', 'pvalue', 'lower', 'upper'],
        height=600, width=800,
    )
    fig.update_traces(textposition='top center')
    fig.update_yaxes(visible=False)
    fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
    
    fig.for_each_trace(lambda t: t.update(textposition='bottom center') if t.name == 'OLS' else ())
    
    fig.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-11
      • 2020-09-04
      • 2017-02-24
      • 1970-01-01
      • 2012-01-30
      • 2020-10-19
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多