线条颜色超出定义的颜色条色阶范围,导致线条颜色和颜色条之间不匹配

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

使用plotly.graph_objects模块Scatter3D和scatter3d.Line我无法让线条颜色落在定义色标的范围内。

我尝试了以下代码,通过将相应的“go.Scatter3D”附加到作为数据提供给“go.FigureWidget”的数据列表中,将点绘制为标记和线条

import numpy as np
import plotly.graph_objects as go

# define function
def get_3D_plot_stack(x,y,z,connections,elongation_values):

    data_list = [] #initializing empty list

    ### Points, gathering data and appending to data_list
    for i,(xi,yi,zi) in enumerate(zip(x,y,z)): # looping through each point_list
        data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
                                      mode='markers',
                                      marker=dict(color='black',size=2),
                                      showlegend= False))

    ### Lines, gathering data and appending to data_list
    for i,(conn,elongation_i) in enumerate(zip(connections,elongation_values)):
        xi_conn = [x[conn[0]], x[conn[1]]]
        yi_conn = [y[conn[0]], y[conn[1]]]
        zi_conn = [z[conn[0]], z[conn[1]]]

        data_list.append(go.Scatter3d(
                                    x=xi_conn, y=yi_conn, z=zi_conn,
                                    mode='lines',
                                    line=go.scatter3d.Line(
                                        width = 4,
                                        color=elongation_i,
                                        colorscale='Viridis',
                                        showscale=True, #set to TRUE
                                    ),
                                showlegend=False
                            ))
    
    ### Create figure
    fig = go.FigureWidget(data=data_list)

    fig.show()
    return()

x,y,z = np.random.random_sample((3,10)) # random points
connections = np.array([[0,1],[9,2],[2,3],[5,7],[6,8],[2,8],[1,2],[4,5]]) # line connections
elongation_values = np.random.random_sample((len(connections))) # random colors

get_3D_plot_stack(x,y,z,connections,elongation_values)

The results show that each colorbar values are plotted (ugly) and that the lines of the colors fall outside of the 'Viridis' colorscale

通过绘制一次所有线条的颜色条值进行了改进。但这并不能解决问题(使用此 GitHub 问题中找到的旧解决方法实现颜色栏也没有解决:https://github.com/plotly/plotly.py/issues/1085

import numpy as np
import plotly.graph_objects as go

def get_3D_plot_stack(x,y,z,connections,elongation_values):

    data_list = [] #initializing an empty list

    ### Points, gathering data and appending to data_list
    for i,(xi,yi,zi) in enumerate(zip(x,y,z)): # looping through each point_list
        data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
                                      mode='markers',
                                      marker=dict(color='black',size=2),
                                      showlegend= False))

    ### Lines, gathering data and appending to data_list
    x_conn, y_conn, z_conn = np.empty((len(connections),2)), np.empty((len(connections),2)), np.empty((len(connections),2))
    for i,(conn,elongation_i) in enumerate(zip(connections,elongation_values)):
        xi_conn = [x[conn[0]], x[conn[1]]]
        yi_conn = [y[conn[0]], y[conn[1]]]
        zi_conn = [z[conn[0]], z[conn[1]]]

        # storing data
        x_conn[i], y_conn[i], z_conn[i] = xi_conn, yi_conn, zi_conn

        data_list.append(go.Scatter3d(
                                    x=xi_conn, y=yi_conn, z=zi_conn,
                                    mode='lines',
                                    line=go.scatter3d.Line(
                                        width = 4,
                                        color=elongation_i,
                                        colorscale='Viridis',
                                        showscale=False, #set to FALSE
                                    ),
                                showlegend=False
                            ))
    
    ## getting the colorbar once
    line_trace_all = go.Scatter3d( x=x_conn, y=y_conn, z=z_conn,
                                    mode='lines',
                                    line=go.scatter3d.Line(
                                        color=elongation_values,
                                        colorscale='Viridis',
                                        showscale=True),
                                    showlegend=False)
    
    data_list.append(line_trace_all)

    ### Create figure
    fig = go.FigureWidget(data=data_list)

    fig.show()
    return()

x,y,z = np.random.random_sample((3,10))
connections = np.array([[0,1],[9,2],[2,3],[5,7],[6,8],[2,8],[1,2],[4,5]]) #random
elongation_values = np.random.random_sample((len(connections)))

get_3D_plot_stack(x,y,z,connections,elongation_values)

Figure shows how colorbar values are only plotted once, but the colors are still off..

python colorbar plotly.graph-objects
1个回答
0
投票

下面的代码试图使用

matplotlib
来完成此任务。我的理解是
elongation_values
代表要连接的点的索引;您希望颜色由
elongation_values
定义;并且颜色条应缩放到
elongation_values
的范围。

代码首先绘制散点。然后它迭代

connections
,每次绘制一条连接由
connections
定义的两个点的线。

import matplotlib.pyplot as plt
import matplotlib
import numpy as np

#Random points
np.random.seed(8)
rand_pts = np.random.random_sample(size=(10, 3))
x_vals, y_vals, z_vals = rand_pts.T

#Lines connecting some points, and their colours
connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]]) # line connections
elongation_values = np.random.random_sample((len(connections))) # random colors

fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(projection='3d')
colourmap = matplotlib.cm.viridis

#Plot points
ax.scatter3D(x_vals, y_vals, z_vals, c='k', s=60, alpha=1)

#For each entry in 'connections', plot a line joining two points
for (conn0, conn1), elong_val in zip(connections, elongation_values):
    x0, y0, z0 = rand_pts[conn0]
    x1, y1, z1 = rand_pts[conn1]
    
    ax.plot3D([x0, x1], [y0, y1], [z0, z1], c=colourmap(elong_val), linewidth=3.2)

#Make a new axis for the colourbar, positioning it at the right
ax_pos = ax.get_position()
cax = fig.add_axes([ax_pos.x0 + ax_pos.width * 1.1, ax_pos.y0 + 0.1, ax_pos.width / 15, ax_pos.height * 0.7])
#Add colorbar
# First define a scale where the min elongation is mapped to 0, and
# the max elongation is mapped to 1
colour_scaling = matplotlib.colors.Normalize(vmin=elongation_values.min(),
                                             vmax=elongation_values.max())
fig.colorbar(matplotlib.cm.ScalarMappable(norm=colour_scaling, cmap=colourmap), cax=cax)
© www.soinside.com 2019 - 2024. All rights reserved.