注释未在带有自定义按钮的 3D Plotly 折线图中显示

问题描述 投票:0回答:1

单击自定义按钮时不显示注释。我想要的是通过单击按钮来显示行注释。他们没有表现出来;仅行 ID“Member 35”写在左下角,并带有我当前的代码(如下)。

我认为是位置问题或者定义注释的问题;我不清楚。我多次寻找解决方案,但一直未能找到。

  • xxx
    是一些长度为
    tmm
  • 的二维数组
  • mem_index
    包含会员ID
        anno=[]
        for i in range(0,tmm,2):
            
            fig2.add_trace(go.Scatter3d(x=xxx[i:i+2,2],y=xxx[i:i+2,0],z=xxx[i:i+2,1], mode='lines',      
                line=dict(
                        color="black",                
                        width=10),))

            ax= xxx[i,2].item() 
            bx= xxx[i+1,2].item() 
            ay= xxx[i,0].item() 
            by= xxx[i+1,0].item() 
            az= xxx[i,1].item() 
            bz= xxx[i+1,1].item() 

            x_annotate=((ax+bx)/2)+0.1
            y_annotate=((ay+by)/2)+0.1
            z_annotate=((az+bz)/2)+0.1
            
            #(x_annotate, y_annotate, z_annotate)
            a1= dict(
            showarrow=False,
            x=x_annotate,
            y=y_annotate,
            z=z_annotate,
            text=f"Member {mem_index[kk]}",
            font=dict(
                color="black",
                size=8
            ),)

            anno.append(a1)
            kk= kk+1

      button1= [True for i in range ( fig2)]

      Model.update_layout(
            updatemenus=[
                dict(
                    type = "buttons",
                    direction = "left",
                    buttons=list([
                        dict(
                            args=[{'visible': button1},
                                  {"title": "RC Model",
                                    "annotations": []}],
                            label="RC Model",
                            method="update",
                        ),
                        dict(
                            args=[{'visible': button1},
                                  {"title": "Members ID's",
                                    "annotations": anno}],
                            label="Member Ids",
                            method="update"
                        ),
                   
                    pad={"r": 10, "t": 10},
                    showactive=True,
                    x=0.11,
                    xanchor="left",
                    y=1.1,
                    yanchor="middle"
                ),
            ]
        )

        Model.update_layout(height=800, width=800)
        Model.show()

python python-3.x plotly annotations plotly-python
1个回答
1
投票

您可以尝试为每条线绘制另一个绘图 3D 散点对象,但使用
mode='text'
除外,作为实现 3D 线文本注释的解决方法

重现您的问题有点困难,下面的代码必须适应您的具体实现和数据结构;但是,希望这有助于推动您继续尝试做的事情。我在下面所做的就是使用绘图立方体函数通过近似重新创建您的屏幕截图。然后,我使用每行附加的

fig.add_trace
调用,使用“成员 X”ID 来命名构成立方网格 3D 结构的每一行。 (注意:这个演示方法会导致许多重叠的标签,因此我添加了一个抖动“shift”函数的怪癖;您可能不需要它。

import random

import plotly.graph_objects as go
import numpy as np


def add_cube(fig, origin, size=1, line_id_start=0):
    """
    Add a cube to a Plotly figure.
    
    Parameters:
        fig (go.Figure): The Plotly figure to which the cube will be added.
        origin (tuple): Coordinates (x, y, z) representing the bottom-left-front corner of the cube.
        size (int, optional): The side length of the cube.
        line_id_start (int, optional): The starting line ID for annotation.
    
    Returns:
        int: `line_id` for keeping track of how many lines have been traced.
    """

    def shift():
        """Random jiggle for moving overlapping labels.
        
        Returns:
            float: A small (non-zero) number -0.1 < x < 0.1.
        """
        return (random.randint(0, 100) / 1e3) * random.choice([1, -1])

    x0, y0, z0 = origin
    line_id = line_id_start
    for dx in [0, size]:
        for dy in [0, size]:
            for coords in [
                ([x0 + dx, x0 + dx], [y0, y0 + size], [z0, z0]),
                ([x0 + dx, x0 + dx], [y0 + dy, y0 + dy], [z0, z0 + size]),
                ([x0, x0 + size], [y0 + dy, y0 + dy], [z0 + dx, z0 + dx]),
            ]:
                x, y, z = coords
                x_annotate, y_annotate, z_annotate = (
                    np.mean(x) + shift(),
                    np.mean(y) + shift(),
                    np.mean(z) + shift(),
                )
                fig.add_trace(
                    go.Scatter3d(
                        x=x,
                        y=y,
                        z=z,
                        mode="lines",
                        line=dict(color="black", width=5),
                    )
                )
                fig.add_trace(
                    go.Scatter3d(
                        x=[x_annotate],
                        y=[y_annotate],
                        z=[z_annotate],
                        mode="text",
                        text=[f"Member {line_id}"],
                        name=f"Member {line_id}",
                        visible=False,
                    )
                )
                line_id += 1
    return line_id


fig = go.Figure()

# Add cubes to the figure
n_cubes = 3  # Number of cubes
total_lines = 0

for i in range(n_cubes):
    for j in range(
        n_cubes - 1
    ):  # Minus 1 results in a 3x2 cube like shown in OP question
        for k in range(n_cubes):
            total_lines = add_cube(fig, (i, j, k), line_id_start=total_lines,)

# Update layout with buttons
show_labels = [True for _ in range(len(fig.data))]
hide_labels = [True if (x % 2 == 0) else False for x in range(len(fig.data))]

fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            x=0.1,
            y=0.95,
            buttons=[
                dict(
                    label="Member IDs",
                    method="update",
                    args=[
                        {"visible": show_labels},
                        {"title": "3D Cubic Mesh Plot ~ Member IDs"},
                    ],
                ),
                dict(
                    label="Turn Off Labels",
                    method="update",
                    args=[
                        {"visible": hide_labels},
                        {"title": "3D Cubic Mesh Plot"},
                    ],
                ),
            ],
        )
    ]
)

fig.update_layout(height=800, width=800)
fig.show()

产生此功能:

上述代码的版本略有不同(其中我仅在

line_id
模 12 > 4 且 < 9; just a quick hack to diminish the excess of labels - these specific aspects of the code will obviously be not exactly relevant to your implementation but were needed for me to demonstrate) gave:

时分配文本标签
© www.soinside.com 2019 - 2024. All rights reserved.