动画条形图不显示过渡,只有 Plotly.js 中的关键帧

Animated bar graph not showing transitions, only key frames in Plotly.js

我一直在尝试使用 Plotly.js 使用 addFrames 函数为包含三个数据集的堆叠条形图制作动画。我想为条形图的长度(x 值)和条形图的宽度设置动画。不幸的是,除非我使用 redraw: true 在每帧结束时强制重绘,否则屏幕上不会呈现任何内容。然后,它只渲染我设置的没有过渡的帧。

为了创建脚本,我主要参考了 Plotly 网站上的 this example

这是片段:

//Load in data
var supply = [
  [280, 720, 476.6666667, 876.4705882, 650, 736.6666667, 1831.333333, 1005.714286, 390, 462.3529412, 0, 611.4102564, 800, 526.5217391, 503.030303, 543.6111111, 1023.529412, 1360, 1980, 1651.612903, 1000, 1760, 886.6666667, 0, 0, 0, 2220],
  [280, 720, 476.6666667, 876.4705882, 650, 736.6666667, 1831.333333, 1025.357143, 390, 462.3529412, 0, 760, 800, 526.5217391, 503.030303, 543.6111111, 1200, 1360, 1800, 1920, 1000, 1760, 886.6666667, 0, 0, 0, 2220],
  [280, 720, 476.6666667, 876.4705882, 650, 736.6666667, 1831.333333, 1056.785714, 390, 462.3529412, 0, 760, 800, 538.6956522, 527.2727273, 435.4166667, 1200, 1360, 1800, 1920, 1000, 2053.333333, 886.6666667, 0, 0, 0, 2220],
  [280, 900, 476.6666667, 900, 879.5454545, 487.5, 1831.333333, 1056.785714, 390, 462.3529412, 0, 760, 800, 523.4782609, 527.2727273, 527.7777778, 1200, 900, 1800, 1800, 1000, 2170.666667, 886.6666667, 0, 0, 1350, 1350],
  [280, 900, 476.6666667, 900, 1350, 487.5, 1831.333333, 937.5, 390, 575, 390, 785.4166667, 0, 504.1666667, 750, 595.5882353, 900, 900, 1800, 1800, 1000, 2170.666667, 886.6666667, 0, 0, 1350, 1350],
  [420, 900, 476.6666667, 900, 1350, 487.5, 1831.333333, 937.5, 390, 575, 390, 900, 0, 504.1666667, 750, 595.5882353, 900, 900, 1800, 1800, 900, 900, 837.5, 525, 1350, 1350, 1350],
  [548.5714286, 900, 476.6666667, 900, 1350, 487.5, 1831.333333, 937.5, 390, 641.6666667, 390, 900, 0, 496.1538462, 750, 767.6470588, 900, 900, 1800, 1800, 900, 900, 900, 900, 1350, 1350, 1350],
  [720, 900, 476.6666667, 900, 1350, 900, 1640, 900, 390, 725, 390, 900, 0, 487.5, 750, 767.6470588, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 390, 725, 390, 900, 0, 900, 750, 767.6470588, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 540, 825, 540, 900, 0, 900, 825, 833.8235294, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 540, 700, 540, 900, 0, 0, 900, 900, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 540, 700, 540, 900, 0, 0, 900, 900, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 540, 700, 540, 900, 0, 0, 900, 900, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350],
  [720, 900, 880, 900, 1350, 900, 1640, 900, 540, 700, 540, 900, 0, 0, 900, 900, 900, 900, 1800, 1800, 900, 1050, 900, 900, 1350, 1350, 1350]
];

var demand = [
  [221.3333333, 571.6666667, 391.3333333, 886, 108.6666667, 611, 1142.333333, 945.6666667, 221, 557.3333333, 0, 500.6666667, 568.3333333, 576.6666667, 550, 418.6666667, 820.6666667, 706, 1331.333333, 904, 979.6666667, 1176, 511, 0, 0, 0, 1384.666667],
  [299.7553333, 552.4706667, 419.5093333, 895.267, 159.3846667, 622.133, 1244.153333, 1086.046667, 222.2333, 530.5553333, 0, 571.1776667, 619.2893333, 580.1646667, 560.267, 447.7106667, 1059.226667, 810.73, 1333.155633, 1044.47, 1164.106667, 1347.2, 679.87, 0, 0, 0, 1240.306667],
  [378.1773333, 533.2746667, 447.6853333, 904.534, 210.1026667, 633.266, 1345.973333, 1226.426667, 223.4666, 503.7773333, 0, 641.6886667, 670.2453333, 583.6626667, 570.534, 476.7546667, 1297.786667, 915.46, 1334.977933, 1184.94, 1348.546667, 1518.4, 848.74, 0, 0, 0, 1095.946667],
  [456.6, 690.6, 480, 901.8, 552, 631.68, 1447.8, 1366.8, 218.82, 477, 0, 712.2, 712.2, 587.16, 580.8, 505.8, 1536.36, 691.8, 1410, 1233, 1533, 1689.6, 1017.6, 0, 0, 775.74, 814.8],
  [472.44, 708.12, 501.12, 915.72, 580.56, 702.492, 1413, 1420.32, 218.148, 546, 422.16, 882.96, 0, 588.888, 1007.58, 613.56, 1623.384, 701.868, 1420.32, 1262.508, 1475.4, 1567.8, 1052.28, 0, 0, 819.588, 1106.16],
  [805.44, 725.64, 522.24, 929.64, 609.12, 773.304, 1340.64, 1430.64, 217.476, 572.88, 418.92, 875.52, 0, 573.816, 1011.36, 639.72, 1717.968, 711.936, 1430.64, 1292.016, 1011.24, 1586.64, 786.408, 1086.96, 409.08, 863.436, 1397.52],
  [845.16, 743.16, 543.36, 943.56, 637.68, 844.116, 1337.76, 1440.96, 216.804, 599.76, 415.68, 868.08, 0, 558.744, 1015.14, 665.88, 1812.552, 722.004, 1440.96, 1321.524, 1016.76, 1488.96, 751.212, 1121.64, 613.62, 907.284, 1688.88],
  [884.88, 760.68, 564.48, 957.48, 666.24, 914.928, 1334.88, 1451.28, 216.132, 626.64, 412.44, 860.64, 0, 543.672, 1018.92, 692.04, 1907.136, 732.072, 1451.28, 1351.032, 1022.28, 1391.28, 716.016, 1156.32, 818.16, 951.132, 1980.24],
  [924.6, 778.2, 585.6, 971.4, 694.8, 985.74, 1332, 1461.6, 215.46, 653.52, 409.2, 853.2, 0, 528.6, 1022.7, 718.2, 2001.72, 742.14, 1461.6, 1380.54, 1027.8, 1293.6, 680.82, 1191, 1022.7, 994.98, 2271.6],
  [958.8, 766.44, 601.44, 977.64, 727.92, 999.432, 1387.656, 1502.928, 218.688, 691.992, 412.56, 861, 0, 528.6, 1018.5, 743.16, 2012.22, 749.712, 1498.56, 1438.08, 1069.8, 1304.64, 737.856, 1184.76, 1030.596, 1002.024, 2284.2],
  [993, 754.68, 617.28, 983.88, 761.04, 1013.124, 1443.312, 1544.256, 221.916, 730.464, 415.92, 868.8, 0, 0, 1014.3, 768.12, 2022.72, 757.284, 1535.52, 1495.62, 1111.8, 1315.68, 794.892, 1178.52, 1038.492, 1009.068, 2296.8],
  [1027.2, 742.92, 633.12, 990.12, 794.16, 1026.816, 1498.968, 1585.584, 225.144, 768.936, 419.28, 876.6, 0, 0, 1010.1, 793.08, 2033.22, 764.856, 1572.48, 1553.16, 1153.8, 1326.72, 851.928, 1172.28, 1046.388, 1016.112, 2309.4],
  [1061.4, 731.16, 648.96, 996.36, 827.28, 1040.508, 1554.624, 1626.912, 228.372, 807.408, 422.64, 884.4, 0, 0, 1005.9, 818.04, 2043.72, 772.428, 1609.44, 1610.7, 1195.8, 1337.76, 908.964, 1166.04, 1054.284, 1023.156, 2322],
  [1095.6, 719.4, 664.8, 1002.6, 860.4, 1054.2, 1610.28, 1668.24, 231.6, 845.88, 426, 892.2, 0, 0, 1001.7, 843, 2054.22, 780, 1646.4, 1668.24, 1237.8, 1348.8, 966, 1159.8, 1062.18, 1030.2, 2334.6]
];

var freq = [
  [4, 6, 7.333333333, 10, 10, 11.33333333, 13.66666667, 11, 6, 6, 0, 6.333333333, 6.666666667, 7, 6.666666667, 6.333333333, 10, 11.33333333, 11, 10.66666667, 8.333333333, 14.66666667, 12.66666667, 0, 0, 0, 12.33333333],
  [4, 6, 7.333333333, 10, 10, 11.33333333, 13.66666667, 11, 6, 6, 0, 6.333333333, 6.666666667, 7, 6.666666667, 6.333333333, 10, 11.33333333, 10, 10.66666667, 8.333333333, 14.66666667, 12.66666667, 0, 0, 0, 12.33333333],
  [4, 6, 7.333333333, 10, 10, 11.33333333, 13.66666667, 11, 6, 6, 0, 6.333333333, 6.666666667, 7, 6.666666667, 6.333333333, 10, 11.33333333, 10, 10.66666667, 8.333333333, 14.66666667, 12.66666667, 0, 0, 0, 12.33333333],
  [4, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 11, 6, 6, 0, 6.333333333, 6.666666667, 7, 6.666666667, 6.333333333, 10, 7.5, 10, 10, 8.333333333, 14.66666667, 12.66666667, 0, 0, 7.5, 7.5],
  [4, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 8.333333333, 14.66666667, 12.66666667, 0, 0, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 7.5, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 0, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 0, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 0, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5],
  [6, 7.5, 7.333333333, 7.5, 7.5, 7.5, 13.66666667, 7.5, 6, 7.5, 6, 7.5, 0, 0, 7.5, 7.5, 7.5, 7.5, 10, 10, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5, 7.5]
];

//Prepare the stack values
var usedSupply = [];
var excessSupply = [];
var excessDemand = [];
for (let a = 0; a < supply.length; a++) {
  let usTemp = [];
  let esTemp = [];
  let edTemp = [];
  for (let b = 0; b < supply[a].length; b++) {
    if (supply[a][b] > demand[a][b]) usTemp.push(demand[a][b]);
    else usTemp.push(supply[a][b]);
    if (supply[a][b] - demand[a][b] > 0) esTemp.push(supply[a][b] - demand[a][b]);
    else esTemp.push(0);
    if (demand[a][b] - supply[a][b] > 0) edTemp.push(demand[a][b] - supply[a][b]);
    else edTemp.push(0);
  }
  usedSupply.push(usTemp);
  excessSupply.push(esTemp);
  excessDemand.push(edTemp);
}

//Prepare the y-axis tick locations
var tickSum = 0;
var tickVals = [];
for (let a = 0; a < freq.length; a++) {
  tickVals.push(15 * a + 7.5);
}

//Prepare the initial graph data
var trace0 = {
  name: 'Used Supply',
  type: 'bar',
  x: usedSupply[0],
  y: tickVals,
  width: freq[0],
  orientation: "h",
  marker: {
    color: '#cccccc',
    opacity: '1.0'
  }
}
var trace1 = {
  name: 'Excess Supply',
  type: 'bar',
  x: excessSupply[0],
  y: tickVals,
  width: freq[0],
  orientation: "h",
  marker: {
    color: '#00ff00',
    opacity: '0.5'
  }
}
var trace2 = {
  name: 'Excess Demand',
  type: 'bar',
  x: excessDemand[0],
  y: tickVals,
  width: freq[0],
  orientation: "h",
  marker: {
    color: '#ff0000',
    opacity: '0.5'
  }
}

var data = [trace0, trace1, trace2]

//Prepare the layout object
var layout = {
  barmode: 'stack',
  yaxis: {
    tickvals: tickVals
  }
}

//Generate key frames for animation
let frames = [];
let frameNames = [];
for (let a = 0; a < usedSupply.length; a++) {
  frames.push({
    name: 'frame' + a,
    x: excessSupply[a],
    width: freq[a]
  });
  frameNames.push('frame' + a);
}

//Load the plot and animate

Plotly.plot('plotly-div', data, layout, {
  showSendToCloud: true,
  responsive: true
}).then(function() {
  Plotly.addFrames('plotly-div', frames);
}).then(function() {
  Plotly.animate('plotly-div', frameNames, {
    transition: {
      duration: 1000,
      easing: 'linear'
    },
    frame: {
      duration: 500,
      redraw: false
    },
    mode: 'afterall'
  });
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>


<!-- Plotly chart will be drawn inside this div -->
<div id="plotly-div"></div>

我还尝试从框架中删除 width 属性 以查看是否会导致问题。我也尝试添加 y 值(不会改变),但这也没有帮助。

截至撰写本文时,尚无法使用 Plot.ly 为条形图制作动画。隐藏在 documentation 中的是这一行:

Currently, only scatter traces may be smoothly transitioned from one state to the next. Other traces are compatible with frames and animations but will be updated instantaneously.

这应该很快就会改变。现在已经有 commits awaiting to be merged into the master to allow bar graphs to animate. Hopefully, this answer can be updated with a working solution in the near future. If you are confident building your own version of Plot.ly, you could build this 个分叉版本来制作条形图动画。