简体   繁体   English

如何在 Plotly“象限”图表之外添加注释?

[英]How can I add annotations outside a Plotly "Quandrant" Chart?

I'm working on a quadrant chart, but a bit stumped on how to get some annotations outside of my Plotly quadrant chart.我正在制作一个象限图,但是对于如何在我的Plotly象限图之外获取一些注释有点难过。 I have provided some data data and code that I used below.我提供了一些我在下面使用的数据数据和代码。

#the libraries
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

Sample of the data that I used:我使用的数据样本:

#the data
data = pd.DataFrame({
    'label': ['bf', 'lv', 'emp', 'ovg', 'cfr', 'osc', 'osh', 'osc', 'ost', 'osp'],
    'score': [0.407, 0.392, 0.562, 0.456, 0.350, 0.410, 0.362, 0.373, 0.313, 0.342],
    'wgt': [26.43, 16.80, 16.08, 15.86, 6.83, 5.31, 4.77, 2.99, 2.80, 2.13]
    })
print(data)

Finally, the code that I used in generating the quadrant chart is below.最后,我在生成象限图时使用的代码如下。 Some of it borrowed from this Medium article .其中一些是从这篇 Medium 文章中借来的。

fig = px.scatter(data, x=data.score, y=data.wgt, text=data.label, 
                 title='main_title',
                 width=800, height=600)

# calculate averages
x_avg = data['score'].mean()
y_avg = data['wgt'].mean()

# add horizontal and vertical lines
fig.add_vline(x=x_avg, line_width=1, opacity=0.2)
fig.add_hline(y=y_avg, line_width=1, opacity=0.2)

# set x limits
adj_x = max((data['score'].max() - x_avg), (x_avg - data['score'].min())) * 1.1
lb_x, ub_x = (x_avg - adj_x, x_avg + adj_x)
fig.update_xaxes(range = [lb_x, ub_x])

# set y limits
adj_y = max((data['wgt'].max() - y_avg), (y_avg - data['wgt'].min())) * 1.1
lb_y, ub_y = (y_avg - adj_y, y_avg + adj_y)
fig.update_yaxes(range = [lb_y, ub_y])

# update x tick labels
axis = ['Low', 'High']     
fig.update_layout(
    xaxis_title='xtitle',
    xaxis = dict(
        tickmode = 'array',
        tickvals = ([(x_avg - adj_x / 2), (x_avg + adj_x / 2)]),
        ticktext = axis
      )
    )

# update y tick labels
fig.update_layout(
    yaxis_title='ytitle',
    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'})

# where I need the help with annotation
fig.add_annotation(x=data['score'].min(), y=data['wgt'].min(),
                   text="Quad 3",
                   yref='paper', 
                   showarrow=False)
fig.add_annotation(x=data['score'].max(), y=data['wgt'].min(),
                   text="Quad 4",
                   yref='paper',
                   showarrow=False)
fig.add_annotation(x=data['score'].min(), y=data['wgt'].max(),
                   text="Quad 1",
                   yref='paper',
                   showarrow=False)
fig.add_annotation(x=data['score'].max(), y=data['wgt'].max(),
                   text="Quad 2",
                   yref='paper',
                   showarrow=False)
fig.show()

The final output I am looking for should look like the chart below.我正在寻找的最终 output 应该如下图所示。 So, specifically, what I need some assistance with is how to position the texts Quad 1 through 4 outside as shown below:所以,具体来说,我需要一些帮助的是如何 position 外部的文本 Quad 1 到 4,如下所示: 在此处输入图像描述

You need to add margins and then set the coordinates accordingly for each position.您需要添加边距,然后为每个 position 相应地设置坐标。 here is a code I used with absolute coordinates.这是我使用绝对坐标的代码。

fig = px.scatter(data, x=data.score, y=data.wgt, text=data.label, 
                 title='main_title',
                 width=800, height=600)

# calculate averages
x_avg = data['score'].mean()
y_avg = data['wgt'].mean()

# add horizontal and vertical lines
fig.add_vline(x=x_avg, line_width=1, opacity=0.2)
fig.add_hline(y=y_avg, line_width=1, opacity=0.2)

# set x limits
adj_x = max((data['score'].max() - x_avg), (x_avg - data['score'].min())) * 1.1
lb_x, ub_x = (x_avg - adj_x, x_avg + adj_x)
fig.update_xaxes(range = [lb_x, ub_x])

# set y limits
adj_y = max((data['wgt'].max() - y_avg), (y_avg - data['wgt'].min())) * 1.1
lb_y, ub_y = (y_avg - adj_y, y_avg + adj_y)
fig.update_yaxes(range = [lb_y, ub_y])

# update x tick labels
axis = ['Low', 'High']     
fig.update_layout(
    xaxis_title='xtitle',
    xaxis = dict(
        tickmode = 'array',
        tickvals = ([(x_avg - adj_x / 2), (x_avg + adj_x / 2)]),
        ticktext = axis
      )
    )

# update y tick labels
fig.update_layout(
    yaxis_title='ytitle',
    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'})

# where I need the help with annotation
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=0, y=-0.15,#data['score'].min()-0.2, y=data['wgt'].min()-0.2,
                        text="Quad 3",
                        xref='paper',
                        yref='paper', 
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=1, y=-0.15,#x=data['score'].max(), y=data['wgt'].min(),
                        text="Quad 4",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=0, y=1.15, #x=data['score'].min(), y=data['wgt'].max(),
                        text="Quad 1",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=18),
                        x=1, y=1.15, #x=data['score'].max(), y=data['wgt'].max(),
                        text="Quad 2",
                        xref='paper',
                        yref='paper',
                        showarrow=False))

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


fig.show()


更新的情节

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM