在 Plotly 2D 直方图中,如何指定 z 值而不是依赖数据的密度?

In Plotly 2D histogram, how can I specify a z value instead of relying on the density of my data?

看着 https://plot.ly/javascript/2D-Histogram/ 我看到他们给了 500 分,他们绘制了密度的热图。

但我有这样的数据

(x=0-1, y=0-1, z00)
(x=0-1, y=1-2, z01)
(x=0-1, y=2-3, z02)
(x=1-2, y=0-1, z10)
(x=1-2, y=1-2, z11)
(x=1-2, y=2-3, z12)

我想实现他们所展示的。我该怎么做? 我想过复制我的数据来给 Plotly 一个在他看来像是分布的东西(即重复 (0, 0, 1) z00 次,重复 (0, 1, 1) z01 次,等等)但感觉不对

有什么想法吗?

注意:x=0-1 表示我有从 x=0 到 x=1 的一桶点,y 也一样。 所以我希望我的正方形从 x,y=0,0 到 x,y=1,1 的值为 z00,上面的正方形 (x,y=0,1 to x,y=1,2) 的值为值 z01 等)

据我所知,您不能直接在 Plotly 中执行此操作,即您需要复制数据。 使用直方图的问题是您的 z00 bin 需要针对零值进行调整。

var z = [[], []];
z[0][0] = 1;
z[0][1] = 18;
z[0][2] = 5;
z[1][0] = 25;
z[1][1] = 12;
z[1][2] = 30;

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

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

var data = [
  {
    x: x,
    y: y,
    type: 'histogram2d',
  }
];
Plotly.newPlot('histo', data);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="histo"></div>

替代方法是使用带正方形的气泡图,但在这里您只能以像素为单位指定大小,而不是相对于轴大小。此外,对于不是正方形的矩形,它看起来很奇怪。

var z = [[], []];
z[0][0] = 1;
z[0][1] = 18;
z[0][2] = 5;
z[1][0] = 25;
z[1][1] = 12;
z[1][2] = 30;

var x = [];
var y = [];
var colors = [];
for (var i = 0; i < z.length; i += 1) {
    for (var j = 0; j < z[i].length; j += 1) {
        x.push(i);
        y.push(j);
        colors.push(z[i][j]);
    }
}
var data = [
  {
    x: x,
    y: y,
    mode: 'markers',
    marker: {
        color: colors,
        symbol: Array(x.length).fill('square'),
        size: Array(x.length).fill(100),
        sizemode: 'diameter'
    }
  }
];

layout = {
  showlegend: false,
  height: 600,
  width: 600
};

Plotly.newPlot('bubbles', data, layout);
<div id="bubbles"></div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

第三种选择是(误)使用形状,但您需要指定自己的色标。此解决方案需要最少的数据复制并且相当灵活。

var z = [[], []];
z[0][0] = 1;
z[0][1] = 18;
z[0][2] = 5;
z[1][0] = 25;
z[1][1] = 12;
z[1][2] = 30;

var c_max = 30; // the max value of your array, pre-defined for brevity
var c_min = 1; // the min value of your array
var shapes = [];
var annotations = [];
for (var i = 0; i < z.length; i += 1) {
    for (var j = 0; j < z[i].length; j += 1) {
        shapes.push({
         type: 'rect',
   x0: i,
   y0: j,
   x1: i + 1,
   y1: j + 1,
   line: {
       width: 2
   },
   fillcolor: 'rgb(' + 255 * (z[i][j] - c_min) / (c_max - c_min) + ', 128, 128)'
     });
        annotations.push({
            x: i + 0.5,
     y: j + 0.5,
      text: z[i][j],
    showarrow: false
        });
    }
}

var trace0 = {
    x: [],
 y: [],
 text: [],
 mode: 'text',
 type: 'scatter'
};

var layout = {
    height: 700,
 width: 700,
 shapes: shapes,
 hovermode: 'closest',
 annotations: annotations,
 xaxis: {
     showgrid: false,
  zeroline: false
 },
 yaxis: {
     showgrid: false,
  zeroline: false
 }
};

Plotly.newPlot('shapes', [trace0], layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="shapes"></div>

我很欣赏这是一个老问题,但如果有人像我一样偶然发现这个问题并寻找相同的答案。以下代码将为 OP 的问题提供解决方案。重要的是要注意 histfun:'sum',仅添加 z 值将导致它们被忽略。

Plotly.newPlot(‘graph’, [{
    type: ‘histogram2dcontour’,
    x: [1,1.1,1.2,1,3,3,4],
    y: [1,1.1,1.2,2,4,4,5],
    histfunc: ‘sum’,
    z: [0.1,0.1,0.1,0.1,0.2,0.3,0.1]
}])

来自文档:

histfunc(str(如果未提供参数则默认 'count',否则 'sum'))——'count'、'sum'、'avg' 之一'min' 或 'max'。用于汇总值的函数(注意:可以使用 histnorm 进行归一化)。此函数的参数是 y(x) 的值(如果方向为 'v'(‘h’)。