Plotly 箱线图的四分位数字中的舍入数

Rounding Numbers in a Quartile Figures of a Plotly Box Plot

我已经研究了一段时间,试图弄清楚如何舍入悬停功能中显示的四分位数字中显示的数字。必须有一个简单的方法来执行此操作,因为它是 x 和 y 坐标。在这种情况下四舍五入到两位小数就足够了。

df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/tips.csv")

fig = go.Figure(data=go.Box(y=df['total_bill'],
                            name='total_bill',
                            boxmean=True,
                           )
               )

fig.update_layout(width=800, height=800,
                  hoverlabel=dict(bgcolor="white",
                                  font_size=16,
                                  font_family="Arial",
                                 )
                 )
fig.show()

不幸的是,这似乎是 Plotly 无法轻易做到的。如果您修改 hovertemplate,它将仅适用于您悬停的标记(离群值),并且每个箱线图统计数据后的小数点在悬停时将保持不变。 plotly-python 的另一个问题是您无法提取箱线图统计信息,因为这需要您与引擎盖下的 javascript 进行交互。

但是,您可以使用与 plotly 相同的方法自行计算箱线图统计数据,并将所有统计数据四舍五入到小数点后两位。然后你可以通过箱线图统计:lowerfence, q1, median, mean, q3, upperfence强制plotly手动构建箱线图,并将所有异常值绘制为另一条散点图。

这是一个非常丑陋的 hack,因为您实际上是在重做 Plotly 已经完成的所有计算,然后手动构建箱线图,但它确实强制箱线图统计显示到小数点后两位。

from math import floor, ceil
from numpy import mean
import pandas as pd
import plotly.graph_objects as go

df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/tips.csv")

## calculate quartiles as outlined in the plotly documentation 
def get_percentile(data, p):
    data.sort()
    n = len(data)
    x = n*p + 0.5
    x1, x2 = floor(x), ceil(x)
    y1, y2 = data[x1-1], data[x2-1] # account for zero-indexing
    return round(y1 + ((x - x1) / (x2 - x1))*(y2 - y1), 2)

## calculate all boxplot statistics
y = df['total_bill'].values
lowerfence = min(y)
q1, median, q3 = get_percentile(y, 0.25), get_percentile(y, 0.50), get_percentile(y, 0.75)
upperfence = max([y0 for y0 in y if y0 < (q3 + 1.5*(q3-q1))])

## construct the boxplot
fig = go.Figure(data=go.Box(
    x=["total_bill"]*len(y),
    q1=[q1], median=[median], mean=[round(mean(y),2)],
    q3=[q3], lowerfence=[lowerfence],
    upperfence=[upperfence], orientation='v', showlegend=False,
    )
)

outliers = y[y>upperfence]
fig.add_trace(go.Scatter(x=["total_bill"]*len(outliers), y=outliers, showlegend=False, mode='markers', marker={'color':'#1f77b4'}))
               

fig.update_layout(width=800, height=800,
                  hoverlabel=dict(bgcolor="white",
                                  font_size=16,
                                  font_family="Arial",
                                 )
                 )

fig.show()