线条颜色超出了定义的色标颜色范围,导致线条颜色与色标不匹配。

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

Line colors exceed the define colorbar colorscale range, results in mismatch between linecolor and colorbar

问题

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

我尝试了以下代码,将点绘制为标记点并通过将相应的"go.Scatter3D"附加到数据列表中,将数据列表作为数据传递给"go.FigureWidget"来绘制点和线:

import numpy as np
import plotly.graph_objects as go

# 定义函数
def get_3D_plot_stack(x, y, z, connections, elongation_values):

    data_list = []  # 初始化空列表

    ### 点,收集数据并附加到data_list
    for i, (xi, yi, zi) in enumerate(zip(x, y, z)):  # 循环遍历每个点列表
        data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
                                      mode='markers',
                                      marker=dict(color='black', size=2),
                                      showlegend=False))

    ### 线,收集数据并附加到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,
                                    ),
                                showlegend=False
                            ))
    
    ### 创建图形
    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]])  # 连接线
elongation_values = np.random.random_sample((len(connections)))  # 随机颜色

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

结果显示每个色标值都被绘制出来(难看),颜色的线条超出了'Viridis'颜色范围

通过一次绘制所有线条的颜色条值来改进,但这并没有解决问题(在此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 = []  # 初始化一个空列表

    ### 点,收集数据并附加到data_list
    for i, (xi, yi, zi) in enumerate(zip(x, y, z)):  # 循环遍历每个点列表
        data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
                                      mode='markers',
                                      marker=dict(color='black', size=2),
                                      showlegend=False))

    ### 线,收集数据并附加到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]]]

        # 存储数据
        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,
                                    ),
                                showlegend=False
                            ))
    
    ## 一次获取颜色条
    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)

    ### 创建图形
    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]])  # 随机
elongation_values = np.random.random_sample((len(connections)))

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

图中显示颜色条值只绘制一次,但颜色仍然不正确。

英文:

Using plotly.graph_objects modules Scatter3D & scatter3d.Line I can't get the line colors to fall within the range of the define color scale.

I tried the following code, that plots points as markers & lines by appending the respective "go.Scatter3D" into a data-list that is given as data to "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

An improvement is made, by plotting the colorbar values for all lines once. This doesn't resolve the issue however (and neither does an implementation of the colorbar using the older workaround found in this GitHub issue: 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..

答案1

得分: 1

以下是翻译好的部分:

# 随机点
np.random.seed(8)
rand_pts = np.random.random_sample(size=(10, 3))
x_vals, y_vals, z_vals = rand_pts.T

# 连接一些点的线和它们的颜色
connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]])  # 线连接
elongation_values = np.random.random_sample((len(connections)))  # 随机颜色

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

# 绘制点
ax.scatter3D(x_vals, y_vals, z_vals, c='k', s=60, alpha=1)

# 对于'connections'中的每个条目,绘制连接两点的线
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)

# 为颜色条创建一个新的坐标轴,并将其放置在右侧
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])
# 添加颜色条
# 首先定义一个标度,其中最小的延伸映射为0,最大的延伸映射为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)
英文:

The code below seeks to accomplish this using matplotlib. My understanding is that elongation_values represents the indices of the points to be connected; you want the colours to be defined by elongation_values; and the colour bar should be scaled to the range of elongation_values.

The code first plots the scatter points. Then it iterates over connections, each time plotting a line that joins two points defined by 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)

huangapple
  • 本文由 发表于 2023年7月24日 17:33:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753135.html
匿名

发表评论

匿名网友

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

确定