You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Plotly.js中3D网络图的锥体设置不同颜色

解决Plotly.js 3D锥体独立着色问题

在Plotly.js中,单个cone trace默认共享颜色映射,直接设置color数组时需要正确配置才能让每个锥体显示不同颜色。以下是两种可行的解决方案:

方案1:单个trace内通过color数组指定独立颜色

直接在traceCone的color属性中传入RGB字符串数组,每个元素对应一个锥体的颜色:

var traceCone = {
  type: "cone",
  x: [0.5, 1.5, 2.5, 3.5], 
  y: [0.5, 0.5, 0.5, 0.5], 
  z: [0.5, 1.5, 2.5, 3.5],
  u: [1,1,1,1], 
  v: [1,-1,1,-1], 
  w: [1,1,1,1],
  sizemode: "absolute",
  sizeref: 0.5,
  // 为每个锥体指定不同的RGB颜色
  color: ['rgb(255, 0, 0)', 'rgb(0, 255, 0)', 'rgb(0, 0, 255)', 'rgb(255, 255, 0)'],
  showscale: false
};

如果需要使用颜色渐变映射,可以保留colorscale并传入数值数组,每个数值会映射到colorscale对应的颜色区间:

var traceCone = {
  type: "cone",
  x: [0.5, 1.5, 2.5, 3.5], 
  y: [0.5, 0.5, 0.5, 0.5], 
  z: [0.5, 1.5, 2.5, 3.5],
  u: [1,1,1,1], 
  v: [1,-1,1,-1], 
  w: [1,1,1,1],
  sizemode: "absolute",
  sizeref: 0.5,
  color: [1, 2, 3, 4], // 数值数组对应每个锥体的颜色映射值
  colorscale: [[0, 'rgb(255, 0, 0)'], [0.33, 'rgb(0, 255, 0)'], [0.66, 'rgb(0, 0, 255)'], [1, 'rgb(255, 255, 0)']],
  showscale: false
};

方案2:为每个锥体创建独立的cone trace

如果需要对每个锥体做更精细的单独配置(比如不同大小、透明度),可以为每个锥体创建独立的cone trace:

// 定义所有锥体的配置参数
var coneConfigs = [
  {x: 0.5, y: 0.5, z: 0.5, u:1, v:1, w:1, color: 'rgb(255, 0, 0)'},
  {x: 1.5, y: 0.5, z: 1.5, u:1, v:-1, w:1, color: 'rgb(0, 255, 0)'},
  {x: 2.5, y: 0.5, z: 2.5, u:1, v:1, w:1, color: 'rgb(0, 0, 255)'},
  {x: 3.5, y: 0.5, z: 3.5, u:1, v:-1, w:1, color: 'rgb(255, 255, 0)'}
];

// 生成多个cone trace
var coneTraces = coneConfigs.map(config => ({
  type: "cone",
  x: [config.x],
  y: [config.y],
  z: [config.z],
  u: [config.u],
  v: [config.v],
  w: [config.w],
  sizemode: "absolute",
  sizeref: 0.5,
  color: config.color,
  showscale: false
}));

// 绘图时将所有trace传入
Plotly.newPlot('myDiv', [traceNodes, traceEdges, ...coneTraces], layout, { displayModeBar: false });

修改后的完整代码(方案1示例)

<html>
  <head>
    <script src="https://cdn.plot.ly/plotly-1.58.5.min.js"></script>
    <style>
      .graph-container {
        display: flex;
        justify-content: center;
        align-items: center;
      }

      .main-panel {
        width: 70%;
        float: left;
      }

      .side-panel {
        width: 30%;
        background-color: lightgray;
        min-height: 300px;
        overflow: auto;
        float: right;
      }
    </style>
  </head>
  <body>
    <div class="graph-container">
      <div id="myDiv" class="main-panel"></div>
      <div id="lineGraph" class="side-panel"></div>
    </div>
    <script>

      var nodes = [
        { x: 0, y: 0, z: 0, value: [1, 2, 3] },
        { x: 1, y: 1, z: 1, value: [4, 5, 6] },
        { x: 2, y: 0, z: 2, value: [7, 8, 9] },
        { x: 3, y: 1, z: 3, value: [10, 11, 12] },
        { x: 4, y: 0, z: 4, value: [13, 14, 15] }
      ];

      var edges = [
        { source: 0, target: 1 },
        { source: 1, target: 2 },
        { source: 2, target: 3 },
        { source: 3, target: 4 }
      ];

      var x = [];
      var y = [];
      var z = [];

      for (var i = 0; i < nodes.length; i++) {
        x.push(nodes[i].x);
        y.push(nodes[i].y);
        z.push(nodes[i].z);
      }

      const edge_x  = [];
      const edge_y  = [];
      const edge_z  = [];

      for (var i = 0; i < edges.length; i++) {
        const a = nodes[edges[i].source];
        const b = nodes[edges[i].target];
        edge_x.push(a.x, b.x, null);
        edge_y.push(a.y, b.y, null);
        edge_z.push(a.z, b.z, null);
      }

      var traceNodes = {
        x: x, y: y, z: z,
        mode: 'markers',
        text: [0, 1, 2, 3, 4],
        marker:{color: [1,2,3,4,5],colorscale: [[0, 'rgb(255, 0, 0)'], [1, 'rgb(0, 0, 255)']], showscale: true, size: 12},
        hoverinfo: 'text',
        hoverlabel: {
          bgcolor: 'white'
        },
        customdata: nodes.map(function(node) {
            if (node.value !== undefined)
               return node.value;
        }),
        type: 'scatter3d'
      };

      var traceEdges = {
        x: edge_x,
        y: edge_y,
        z: edge_z,
        line: {
        color: [4,1,4,1,4,1],
        colorscale: [[0, 'rgb(255, 0, 0)'], [1, 'rgb(0, 0, 255)']],
        showscale: true,
        width: 5
        },
        type: 'scatter3d',
        mode: 'lines',
        opacity: 2.8
      };

      var layout = {
        margin: { l: 0, r: 0, b: 0, t: 0 }
      };

      // 修改后的锥体配置,每个锥体使用不同颜色
      var traceCone = {
        type: "cone",
        x: [0.5, 1.5, 2.5, 3.5], y: [0.5, 0.5, 0.5, 0.5], z: [0.5, 1.5, 2.5, 3.5],
        u: [1,1,1,1], v: [1,-1,1,-1], w: [1,1,1,1],
        sizemode: "absolute",
        sizeref: 0.5,
        color: ['rgb(255, 0, 0)', 'rgb(0, 255, 0)', 'rgb(0, 0, 255)', 'rgb(255, 255, 0)'],
        showscale: false
      };
      

      Plotly.newPlot('myDiv', [traceNodes, traceEdges,traceCone],layout, { displayModeBar: false });

      const ymax = Math.max(...nodes.map(n => n.value).flat());

      document.getElementById('myDiv').on('plotly_click', function(data){
      var nodeIndex = data.points[0].pointNumber;
      var values = nodes[nodeIndex].value;

      var update = {
        marker: { color: [1,2,3,4,5],colorscale: [[0, 'rgb(255, 0, 0)'], [1, 'rgb(0, 0, 255)']], showscale: true, size: 12}
      };
      update.marker.color[nodeIndex] = 'blue';

      setTimeout(function() {
        Plotly.restyle('myDiv', update);
      }, 50);


      Plotly.newPlot('lineGraph', [{
          type: 'scatter',
          mode: 'lines',
          x: [0, 1, 2],
          y: values
      }], {
          margin: { t: 0 },
          yaxis: {autorange: false, range: [0, ymax + 1]}
      });
      });
    </script>
   </body>
</html>

内容的提问来源于stack exchange,提问作者LaluBadmaash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:45:20