在 Plotly Express 中如何找到分组条形图上的 x 坐标?

huangapple go评论74阅读模式
英文:

How to find the x coordinate on a grouped bar chart on plotly express?

问题

以下是翻译好的部分:

跟随这里的回答 https://stackoverflow.com/questions/71610356/how-to-specify-the-x-coordinate-on-a-grouped-bar-chart-on-plotly

我想要以编程方式获取所有的x坐标。

我可以通过调整硬编码的数字来获得工作解决方案,例如:

    import plotly.express as px
    import plotly.graph_objects as go
    import numpy as np
    
    df = px.data.tips()
    print(df.head())
    fig = px.histogram(
        df, x="sex", y="total_bill", color="time", barmode="group", height=400
    )
    
    # 添加覆盖分类x轴的次要x轴
    fig.layout.xaxis2 = go.layout.XAxis(
        overlaying='x', range=[0, 2], showticklabels=False)
    
    # 添加线条跟踪,并与第二个x轴关联
    bargap = 0.2
    for i in range(2):
        x = bargap/2 + (1-bargap)/4
        y = [1111]
        print(111,x, y)
        scatt = fig.add_scatter(x=[i+x], y=y, xaxis='x2',
                                showlegend=False, line={'color': 'gray'})
        x *=2.3
        print(22222,x, y)
        scatt = fig.add_scatter(x=[i+x], y=y, xaxis='x2',
                                showlegend=False, line={'color': 'gray'})
    fig

但我需要一个动态解决方案,当我将颜色更改为“day”时也能正常工作:

    fig = px.histogram(
        df, x="sex", y="total_bill", color="day", barmode="group", height=400
    )

然后在子图中有4个框。在我处理的数据中,总是有不同数量的图和子图。

我真的希望plotly的开发人员能够帮助解决这个问题,这是我在使用plotly时遇到的第一个主要限制。
英文:

Following on from the response here https://stackoverflow.com/questions/71610356/how-to-specify-the-x-coordinate-on-a-grouped-bar-chart-on-plotly

I would like to get ALL the x coords, programatically.

I can get a working solution by playing around with hard coded numbers like:

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

df = px.data.tips()
print(df.head())
fig = px.histogram(
    df, x="sex", y="total_bill", color="time", barmode="group", height=400
)

# Add secondary x-axis that overlays categorical xaxis
fig.layout.xaxis2 = go.layout.XAxis(
    overlaying='x', range=[0, 2], showticklabels=False)

# Add a line traces, and associate with the second xaxis
bargap = 0.2
for i in range(2):
    x = bargap/2 + (1-bargap)/4
    y = [1111]
    print(111,x, y)
    scatt = fig.add_scatter(x=[i+x], y=y, xaxis='x2',
                            showlegend=False, line={'color': 'gray'})
    x *=2.3
    print(22222,x, y)
    scatt = fig.add_scatter(x=[i+x], y=y, xaxis='x2',
                            showlegend=False, line={'color': 'gray'})
fig

But I need a dynamic solution that works when I change color to day:

fig = px.histogram(
    df, x="sex", y="total_bill", color="day", barmode="group", height=400
)

and then have 4 boxes in the sub plot. In the data I'm working with there's always a different number of plots and sub plots.

I really hope the devs from plotly can help with this, it's the first major limitation I have come up against using plotly.

答案1

得分: 1

import plotly.express as px

df = px.data.tips()

# Use primary and secondary in your function to vary

primary = 'day'
secondary = 'sex'

fig = px.histogram(df, x=primary, y="total_bill", color=secondary, barmode="group", height=400)

nPri = len(df[primary].unique())
nSec = len(df[secondary].unique())

N = nPri

# Group centers
xrange = N-1  # the underlying x-axis is scaled with N automatically
xGp = [xrange * n / (N-1) for n in range(N)]

# Plot group centers
for ix in xGp:
    fig.add_vline(x=ix)

bargap = 0.2  # I tried it with some variation. Still works.
fig.layout.bargap = bargap

# Calculate bar sizing
gpWidth = 1 - bargap
barWidth = gpWidth / nSec

# Left and right edges of each group
gpEdges = [(x - gpWidth / 2, x + gpWidth / 2) for x in xGp]

for ix1, ix2 in gpEdges:

    gpRange = ix2 - ix1 # group range

    xB = [ix1 + barWidth/2 + barWidth * n for n in range(nSec)]  # list of x coordinates of each bar in the group
    print(xB)

    for x in xB:
        fig.add_vline(x=x, line_color='blue')

fig.show()
英文:

Found it.

import plotly.express as px

df = px.data.tips()

# Use primary and secondary in your function to vary

primary = 'day'
secondary = 'sex'

fig = px.histogram(df, x=primary, y="total_bill", color=secondary, barmode="group", height=400)

nPri = len(df[primary].unique())
nSec = len(df[secondary].unique())

N = nPri

# Group centers
xrange = N-1  # the underlying x-axis is scaled with N automatically
xGp = [xrange * n / (N-1) for n in range(N)]

# Plot group centers
for ix in xGp:
    fig.add_vline(x=ix)

bargap = 0.2  # I tried it with some variation. Still works.
fig.layout.bargap = bargap

# Calculate bar sizing
gpWidth = 1 - bargap
barWidth = gpWidth / nSec

# Left and right edges of each group
gpEdges = [(x - gpWidth / 2, x + gpWidth / 2) for x in xGp]

for ix1, ix2 in gpEdges:

    gpRange = ix2 - ix1 # group range

    xB = [ix1 + barWidth/2 + barWidth * n for n in range(nSec)]  # list of x coordinates of each bar in the group
    print(xB)

    for x in xB:
        fig.add_vline(x=x, line_color='blue')

fig.show()

huangapple
  • 本文由 发表于 2023年6月29日 10:08:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定