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

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

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"来绘制点和线:

  1. import numpy as np
  2. import plotly.graph_objects as go
  3. # 定义函数
  4. def get_3D_plot_stack(x, y, z, connections, elongation_values):
  5. data_list = [] # 初始化空列表
  6. ### 点,收集数据并附加到data_list
  7. for i, (xi, yi, zi) in enumerate(zip(x, y, z)): # 循环遍历每个点列表
  8. data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
  9. mode='markers',
  10. marker=dict(color='black', size=2),
  11. showlegend=False))
  12. ### 线,收集数据并附加到data_list
  13. for i, (conn, elongation_i) in enumerate(zip(connections, elongation_values)):
  14. xi_conn = [x[conn[0]], x[conn[1]]]
  15. yi_conn = [y[conn[0]], y[conn[1]]]
  16. zi_conn = [z[conn[0]], z[conn[1]]]
  17. data_list.append(go.Scatter3d(
  18. x=xi_conn, y=yi_conn, z=zi_conn,
  19. mode='lines',
  20. line=go.scatter3d.Line(
  21. width=4,
  22. color=elongation_i,
  23. colorscale='Viridis',
  24. showscale=True,
  25. ),
  26. showlegend=False
  27. ))
  28. ### 创建图形
  29. fig = go.FigureWidget(data=data_list)
  30. fig.show()
  31. return()
  32. x, y, z = np.random.random_sample((3, 10)) # 随机点
  33. connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]]) # 连接线
  34. elongation_values = np.random.random_sample((len(connections))) # 随机颜色
  35. get_3D_plot_stack(x, y, z, connections, elongation_values)

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

通过一次绘制所有线条的颜色条值来改进,但这并没有解决问题(在此GitHub问题中找到的旧解决方法也没有解决:https://github.com/plotly/plotly.py/issues/1085)

  1. import numpy as np
  2. import plotly.graph_objects as go
  3. def get_3D_plot_stack(x, y, z, connections, elongation_values):
  4. data_list = [] # 初始化一个空列表
  5. ### 点,收集数据并附加到data_list
  6. for i, (xi, yi, zi) in enumerate(zip(x, y, z)): # 循环遍历每个点列表
  7. data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
  8. mode='markers',
  9. marker=dict(color='black', size=2),
  10. showlegend=False))
  11. ### 线,收集数据并附加到data_list
  12. x_conn, y_conn, z_conn = np.empty((len(connections), 2)), np.empty((len(connections), 2)), np.empty((len(connections), 2))
  13. for i, (conn, elongation_i) in enumerate(zip(connections, elongation_values)):
  14. xi_conn = [x[conn[0]], x[conn[1]]]
  15. yi_conn = [y[conn[0]], y[conn[1]]]
  16. zi_conn = [z[conn[0]], z[conn[1]]]
  17. # 存储数据
  18. x_conn[i], y_conn[i], z_conn[i] = xi_conn, yi_conn, zi_conn
  19. data_list.append(go.Scatter3d(
  20. x=xi_conn, y=yi_conn, z=zi_conn,
  21. mode='lines',
  22. line=go.scatter3d.Line(
  23. width=4,
  24. color=elongation_i,
  25. colorscale='Viridis',
  26. showscale=False,
  27. ),
  28. showlegend=False
  29. ))
  30. ## 一次获取颜色条
  31. line_trace_all = go.Scatter3d( x=x_conn, y=y_conn, z=z_conn,
  32. mode='lines',
  33. line=go.scatter3d.Line(
  34. color=elongation_values,
  35. colorscale='Viridis',
  36. showscale=True),
  37. showlegend=False)
  38. data_list.append(line_trace_all)
  39. ### 创建图形
  40. fig = go.FigureWidget(data=data_list)
  41. fig.show()
  42. return()
  43. x, y, z = np.random.random_sample((3, 10))
  44. connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]]) # 随机
  45. elongation_values = np.random.random_sample((len(connections)))
  46. 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"

  1. import numpy as np
  2. import plotly.graph_objects as go
  3. # define function
  4. def get_3D_plot_stack(x,y,z,connections,elongation_values):
  5. data_list = [] #initializing empty list
  6. ### Points, gathering data and appending to data_list
  7. for i,(xi,yi,zi) in enumerate(zip(x,y,z)): # looping through each point_list
  8. data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
  9. mode='markers',
  10. marker=dict(color='black',size=2),
  11. showlegend= False))
  12. ### Lines, gathering data and appending to data_list
  13. for i,(conn,elongation_i) in enumerate(zip(connections,elongation_values)):
  14. xi_conn = [x[conn[0]], x[conn[1]]]
  15. yi_conn = [y[conn[0]], y[conn[1]]]
  16. zi_conn = [z[conn[0]], z[conn[1]]]
  17. data_list.append(go.Scatter3d(
  18. x=xi_conn, y=yi_conn, z=zi_conn,
  19. mode='lines',
  20. line=go.scatter3d.Line(
  21. width = 4,
  22. color=elongation_i,
  23. colorscale='Viridis',
  24. showscale=True, #set to TRUE
  25. ),
  26. showlegend=False
  27. ))
  28. ### Create figure
  29. fig = go.FigureWidget(data=data_list)
  30. fig.show()
  31. return()
  32. x,y,z = np.random.random_sample((3,10)) # random points
  33. connections = np.array([[0,1],[9,2],[2,3],[5,7],[6,8],[2,8],[1,2],[4,5]]) # line connections
  34. elongation_values = np.random.random_sample((len(connections))) # random colors
  35. 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 )

  1. import numpy as np
  2. import plotly.graph_objects as go
  3. def get_3D_plot_stack(x,y,z,connections,elongation_values):
  4. data_list = [] #initializing an empty list
  5. ### Points, gathering data and appending to data_list
  6. for i,(xi,yi,zi) in enumerate(zip(x,y,z)): # looping through each point_list
  7. data_list.append(go.Scatter3d(x=[xi], y=[yi], z=[zi],
  8. mode='markers',
  9. marker=dict(color='black',size=2),
  10. showlegend= False))
  11. ### Lines, gathering data and appending to data_list
  12. x_conn, y_conn, z_conn = np.empty((len(connections),2)), np.empty((len(connections),2)), np.empty((len(connections),2))
  13. for i,(conn,elongation_i) in enumerate(zip(connections,elongation_values)):
  14. xi_conn = [x[conn[0]], x[conn[1]]]
  15. yi_conn = [y[conn[0]], y[conn[1]]]
  16. zi_conn = [z[conn[0]], z[conn[1]]]
  17. # storing data
  18. x_conn[i], y_conn[i], z_conn[i] = xi_conn, yi_conn, zi_conn
  19. data_list.append(go.Scatter3d(
  20. x=xi_conn, y=yi_conn, z=zi_conn,
  21. mode='lines',
  22. line=go.scatter3d.Line(
  23. width = 4,
  24. color=elongation_i,
  25. colorscale='Viridis',
  26. showscale=False, #set to FALSE
  27. ),
  28. showlegend=False
  29. ))
  30. ## getting the colorbar once
  31. line_trace_all = go.Scatter3d( x=x_conn, y=y_conn, z=z_conn,
  32. mode='lines',
  33. line=go.scatter3d.Line(
  34. color=elongation_values,
  35. colorscale='Viridis',
  36. showscale=True),
  37. showlegend=False)
  38. data_list.append(line_trace_all)
  39. ### Create figure
  40. fig = go.FigureWidget(data=data_list)
  41. fig.show()
  42. return()
  43. x,y,z = np.random.random_sample((3,10))
  44. connections = np.array([[0,1],[9,2],[2,3],[5,7],[6,8],[2,8],[1,2],[4,5]]) #random
  45. elongation_values = np.random.random_sample((len(connections)))
  46. 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

以下是翻译好的部分:

  1. # 随机点
  2. np.random.seed(8)
  3. rand_pts = np.random.random_sample(size=(10, 3))
  4. x_vals, y_vals, z_vals = rand_pts.T
  5. # 连接一些点的线和它们的颜色
  6. connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]]) # 线连接
  7. elongation_values = np.random.random_sample((len(connections))) # 随机颜色
  8. fig = plt.figure(figsize=(5, 5))
  9. ax = fig.add_subplot(projection='3d')
  10. colourmap = matplotlib.cm.viridis
  11. # 绘制点
  12. ax.scatter3D(x_vals, y_vals, z_vals, c='k', s=60, alpha=1)
  13. # 对于'connections'中的每个条目,绘制连接两点的线
  14. for (conn0, conn1), elong_val in zip(connections, elongation_values):
  15. x0, y0, z0 = rand_pts[conn0]
  16. x1, y1, z1 = rand_pts[conn1]
  17. ax.plot3D([x0, x1], [y0, y1], [z0, z1], c=colourmap(elong_val), linewidth=3.2)
  18. # 为颜色条创建一个新的坐标轴,并将其放置在右侧
  19. ax_pos = ax.get_position()
  20. 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])
  21. # 添加颜色条
  22. # 首先定义一个标度,其中最小的延伸映射为0,最大的延伸映射为1
  23. colour_scaling = matplotlib.colors.Normalize(vmin=elongation_values.min(),
  24. vmax=elongation_values.max())
  25. 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.

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

  1. import matplotlib.pyplot as plt
  2. import matplotlib
  3. import numpy as np
  4. #Random points
  5. np.random.seed(8)
  6. rand_pts = np.random.random_sample(size=(10, 3))
  7. x_vals, y_vals, z_vals = rand_pts.T
  8. #Lines connecting some points, and their colours
  9. connections = np.array([[0, 1], [9, 2], [2, 3], [5, 7], [6, 8], [2, 8], [1, 2], [4, 5]]) # line connections
  10. elongation_values = np.random.random_sample((len(connections))) # random colors
  11. fig = plt.figure(figsize=(5, 5))
  12. ax = fig.add_subplot(projection='3d')
  13. colourmap = matplotlib.cm.viridis
  14. #Plot points
  15. ax.scatter3D(x_vals, y_vals, z_vals, c='k', s=60, alpha=1)
  16. #For each entry in 'connections', plot a line joining two points
  17. for (conn0, conn1), elong_val in zip(connections, elongation_values):
  18. x0, y0, z0 = rand_pts[conn0]
  19. x1, y1, z1 = rand_pts[conn1]
  20. ax.plot3D([x0, x1], [y0, y1], [z0, z1], c=colourmap(elong_val), linewidth=3.2)
  21. #Make a new axis for the colourbar, positioning it at the right
  22. ax_pos = ax.get_position()
  23. 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])
  24. #Add colorbar
  25. # First define a scale where the min elongation is mapped to 0, and
  26. # the max elongation is mapped to 1
  27. colour_scaling = matplotlib.colors.Normalize(vmin=elongation_values.min(),
  28. vmax=elongation_values.max())
  29. 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:

确定