plotly.js y轴与零线位置相同

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

plotly.js y-axis same position of zero-line

问题

我有一堆散点线要绘制。其中一些值在0到10k之间,而另一些范围在-1到1之间。不同应用程序的值范围不同,因此我不能将它们设置为固定值。

我的问题有点类似于这个问题:
https://stackoverflow.com/questions/71798553/plotly-two-y-axis-same-position-of-zero-line
但是我的第二个Y轴上有负值,因此rangemode='tozero'对我不起作用。

我希望两个轴共享相同的X轴/在相同位置具有y=0的值。我在CodePen中使用了我的代码。
https://codepen.io/kesslerf/pen/mdQJQbY

以下是代码:
HTML:

  1. <head>
  2. <!-- Load plotly.js into the DOM -->
  3. <script src='https://cdn.plot.ly/plotly-2.16.1.min.js'></script>
  4. </head>
  5. <body>
  6. <div id='ts' class='ts' style="width:1200px; height:800px; background-color: aliceblue"></div>
  7. </body>

JS部分:

  1. var data_all = {
  2. "b02": {
  3. "min_value": 562,
  4. "max_value": 1007,
  5. "values": [
  6. {
  7. "date": "2018-07-01 00:00:00",
  8. "value": "587"
  9. },
  10. {
  11. "date": "2018-07-04 00:00:00",
  12. "value": "562"
  13. },
  14. {
  15. "date": "2018-07-16 00:00:00",
  16. "value": "794"
  17. },
  18. {
  19. "date": "2018-07-19 00:00:00",
  20. "value": "966"
  21. },
  22. {
  23. "date": "2018-07-24 00:00:00",
  24. "value": "1007"
  25. }
  26. ]
  27. },
  28. // 其他数据...
  29. }
  30. // 其余代码...

希望这对你有所帮助。

英文:

I have a bunch of scatter-lines that I want to plot. There are some that have values between 0 and 10k and some where the range is -1 -> 1. The value-ranges are different for different applications, so I can not set them to fixed values.

My question is kind of similar to this one:
https://stackoverflow.com/questions/71798553/plotly-two-y-axis-same-position-of-zero-line
But I have negative values on my second Y-Axis, thus the rangemode='tozero' is not working for me.

I want both axis to share the same X-axis/have the y=0 value on the same position. I made a codepen with my code.
https://codepen.io/kesslerf/pen/mdQJQbY

Here is the code:
HTML:

  1. &lt;head&gt;
  2. &lt;!-- Load plotly.js into the DOM --&gt;
  3. &lt;script src=&#39;https://cdn.plot.ly/plotly-2.16.1.min.js&#39;&gt;&lt;/script&gt;
  4. &lt;/head&gt;
  5. &lt;body&gt;
  6. &lt;div id=&#39;ts&#39; class=&#39;ts&#39; style=&quot;width:1200px; height:800px; background-color: aliceblue&quot;&gt;&lt;/div&gt;
  7. &lt;/body&gt;

And the JS-Part:

  1. var data_all = {
  2. &quot;b02&quot;: {
  3. &quot;min_value&quot;: 562,
  4. &quot;max_value&quot;: 1007,
  5. &quot;values&quot;: [
  6. {
  7. &quot;date&quot;: &quot;2018-07-01 00:00:00&quot;,
  8. &quot;value&quot;: &quot;587&quot;
  9. },
  10. {
  11. &quot;date&quot;: &quot;2018-07-04 00:00:00&quot;,
  12. &quot;value&quot;: &quot;562&quot;
  13. },
  14. {
  15. &quot;date&quot;: &quot;2018-07-16 00:00:00&quot;,
  16. &quot;value&quot;: &quot;794&quot;
  17. },
  18. {
  19. &quot;date&quot;: &quot;2018-07-19 00:00:00&quot;,
  20. &quot;value&quot;: &quot;966&quot;
  21. },
  22. {
  23. &quot;date&quot;: &quot;2018-07-24 00:00:00&quot;,
  24. &quot;value&quot;: &quot;1007&quot;
  25. }
  26. ]
  27. },
  28. &quot;b04&quot;: {
  29. &quot;min_value&quot;: 1091,
  30. &quot;max_value&quot;: 2549,
  31. &quot;values&quot;: [
  32. {
  33. &quot;date&quot;: &quot;2018-07-01 00:00:00&quot;,
  34. &quot;value&quot;: &quot;1091&quot;
  35. },
  36. {
  37. &quot;date&quot;: &quot;2018-07-04 00:00:00&quot;,
  38. &quot;value&quot;: &quot;1175&quot;
  39. },
  40. {
  41. &quot;date&quot;: &quot;2018-07-16 00:00:00&quot;,
  42. &quot;value&quot;: &quot;1553&quot;
  43. },
  44. {
  45. &quot;date&quot;: &quot;2018-07-19 00:00:00&quot;,
  46. &quot;value&quot;: &quot;2409&quot;
  47. },
  48. {
  49. &quot;date&quot;: &quot;2018-07-24 00:00:00&quot;,
  50. &quot;value&quot;: &quot;2549&quot;
  51. }
  52. ]
  53. },
  54. &quot;evi&quot;: {
  55. &quot;min_value&quot;: 0,
  56. &quot;max_value&quot;: 1,
  57. &quot;values&quot;: [
  58. {
  59. &quot;date&quot;: &quot;2018-07-01 00:00:00&quot;,
  60. &quot;value&quot;: &quot;1&quot;
  61. },
  62. {
  63. &quot;date&quot;: &quot;2018-07-04 00:00:00&quot;,
  64. &quot;value&quot;: &quot;1&quot;
  65. },
  66. {
  67. &quot;date&quot;: &quot;2018-07-16 00:00:00&quot;,
  68. &quot;value&quot;: &quot;0&quot;
  69. },
  70. {
  71. &quot;date&quot;: &quot;2018-07-19 00:00:00&quot;,
  72. &quot;value&quot;: &quot;0&quot;
  73. },
  74. {
  75. &quot;date&quot;: &quot;2018-07-24 00:00:00&quot;,
  76. &quot;value&quot;: &quot;0&quot;
  77. }
  78. ]
  79. },
  80. &quot;ndvi&quot;: {
  81. &quot;min_value&quot;: 0,
  82. &quot;max_value&quot;: 1,
  83. &quot;values&quot;: [
  84. {
  85. &quot;date&quot;: &quot;2018-07-01 00:00:00&quot;,
  86. &quot;value&quot;: &quot;1&quot;
  87. },
  88. {
  89. &quot;date&quot;: &quot;2018-07-04 00:00:00&quot;,
  90. &quot;value&quot;: &quot;0&quot;
  91. },
  92. {
  93. &quot;date&quot;: &quot;2018-07-16 00:00:00&quot;,
  94. &quot;value&quot;: &quot;0&quot;
  95. },
  96. {
  97. &quot;date&quot;: &quot;2018-07-19 00:00:00&quot;,
  98. &quot;value&quot;: &quot;0&quot;
  99. },
  100. {
  101. &quot;date&quot;: &quot;2018-07-24 00:00:00&quot;,
  102. &quot;value&quot;: &quot;0&quot;
  103. }
  104. ]
  105. }
  106. }
  107. var unpack = function(rows, key) {
  108. return rows.map(function(row) { return row[key]; })
  109. };
  110. var layout = {
  111. autosize: false,
  112. width: 1000,
  113. height: 420,
  114. margin: {
  115. l:50,
  116. r:150,
  117. b: 50,
  118. t: 50,
  119. pad: 4
  120. },
  121. xaxis: {title: &#39;Datum&#39;,
  122. type: &#39;date&#39;,
  123. tickformat: &#39;%d-%m-%y&#39;},
  124. yaxis: {title: &#39;Wert&#39;,
  125. side: &#39;left&#39;},
  126. yaxis2: {
  127. title: &#39;yaxis2 title&#39;,
  128. overlaying: &#39;y&#39;,
  129. side: &#39;right&#39;,
  130. },
  131. legend: {
  132. x: 1.1,
  133. y: 0
  134. }
  135. }
  136. var plotly_config = {
  137. displaylogo: false,
  138. showSendToCloud: true,
  139. };
  140. var traces = [];
  141. for (var key1 in data_all){
  142. var idx_data = data_all[key1][&#39;values&#39;];
  143. var dates = unpack(idx_data,&#39;date&#39;).map(n =&gt; n.substr(0,10));
  144. var values_dates = unpack(idx_data,&#39;value&#39;).map(n =&gt; parseFloat(n));
  145. if (key1.substr(0,1) !== &#39;b&#39;) {
  146. var cur_col = &#39;red&#39;;
  147. var trace = {
  148. x: dates,
  149. y: values_dates,
  150. name: key1,
  151. xaxis: &#39;x&#39;,
  152. yaxis: &#39;y2&#39;,
  153. type: &#39;scatter&#39;
  154. };
  155. traces.push(trace);
  156. }else {
  157. var cur_col = &#39;blue&#39;;
  158. var trace = {
  159. x: dates,
  160. y: values_dates,
  161. name: key1,
  162. xaxis: &#39;x&#39;,
  163. yaxis: &#39;y&#39;,
  164. type: &#39;scatter&#39;
  165. };
  166. traces.push(trace);
  167. }
  168. }
  169. Plotly.newPlot(&#39;ts&#39;, traces, layout, plotly_config);
  170. $(&#39;.ts&#39;)[0].on(&#39;plotly_hover&#39;, function(data){
  171. if(data.points[0].data.yaxis==&#39;y&#39;){
  172. layout.yaxis.linewidth = 5;
  173. }else if (data.points[0].data.yaxis == &#39;y2&#39;){
  174. layout.yaxis2.linewidth = 5;
  175. }
  176. Plotly.update(&#39;ts&#39;,{},layout);
  177. });
  178. $(&#39;.ts&#39;)[0].on(&#39;plotly_unhover&#39;, function(data){
  179. layout.yaxis.linewidth = 1;
  180. layout.yaxis2.linewidth = 1;
  181. Plotly.update(&#39;ts&#39;,{},layout);
  182. });

答案1

得分: 0

这是您提供的代码的中文翻译:

  1. 我刚刚编写了一个用于计算的函数并添加了在 Date-Format 中使用新的 x 范围进行缩放/重新布局的可能性
  2. var adjustYAxis = function(traces, layout, new_x_min, new_x_max) {
  3. var y1_max = 0;
  4. var y1_min = 0;
  5. var y2_max = 0;
  6. var y2_min = 0;
  7. for (let t = 0; t < traces.length; t++) {
  8. var curtrac = traces[t];
  9. if (new_x_min && new_x_max) {
  10. var dates_act = curtrac.x.map(n => (new Date(n) > new Date(new_x_min) && new Date(n) < new Date(new_x_max)));
  11. var relevant_vals = curtrac.y.slice(dates_act.indexOf(true), dates_act.lastIndexOf(true));
  12. } else {
  13. relevant_vals = curtrac.y;
  14. }
  15. if (traces[t].yaxis === 'y') {
  16. if (Math.max(...relevant_vals) > y1_max) {
  17. y1_max = Math.max(...relevant_vals);
  18. }
  19. if (Math.min(...relevant_vals) < y1_min) {
  20. y1_min = Math.min(...relevant_vals);
  21. }
  22. } else {
  23. if (Math.max(...relevant_vals) > y2_max) {
  24. y2_max = Math.max(...relevant_vals);
  25. }
  26. if (Math.min(...relevant_vals) < y2_min) {
  27. y2_min = Math.min(...relevant_vals);
  28. }
  29. }
  30. }
  31. if (y1_max > 1) {
  32. y1_max = y1_max - y1_max % 250 + 250;
  33. y2_max = y2_max - y2_max % 0.2 + 0.2;
  34. y2_min = y2_min - y2_min % 0.2 - 0.2;
  35. if (y2_min < y1_min) {
  36. y1_min = -1 * Math.abs(y2_min) * Math.abs(y1_max) / Math.abs(y2_max);
  37. }
  38. } else {
  39. y1_max = 1;
  40. y1_min = 0;
  41. }
  42. layout.yaxis.autorange = false;
  43. layout.yaxis2.autorange = false;
  44. layout.xaxis.autorange = false;
  45. layout.yaxis.range = [y1_min, y1_max];
  46. layout.yaxis2.range = [y2_min, y2_max];
  47. if (new_x_min && new_x_max) {
  48. layout.xaxis.range = [new_x_min, new_x_max];
  49. }
  50. layout.shapes[0].y0 = y1_min;
  51. layout.shapes[0].y1 = y1_max;
  52. return layout;
  53. };

希望这对您有所帮助!如果您有任何其他问题,请随时提出。

英文:

I just wrote a function to calculate it, added a possibility to use it on zoom/relayout using the new x-range if it is in Date-Format.

  1. var adjustYAxis = function(traces,layout,new_x_min, new_x_max){
  2. var y1_max = 0;
  3. var y1_min = 0;
  4. var y2_max = 0;
  5. var y2_min = 0;
  6. for (let t=0;t&lt;traces.length;t++){
  7. var curtrac = traces[t];
  8. if(new_x_min &amp;&amp; new_x_max){
  9. var dates_act = curtrac.x.map(n =&gt; (new Date(n) &gt; new Date(new_x_min) &amp;&amp; new Date(n) &lt; new Date(new_x_max)));
  10. var relevant_vals = curtrac.y.slice(dates_act.indexOf(true),dates_act.lastIndexOf(true));
  11. }else{
  12. relevant_vals = curtrac.y;
  13. }
  14. if(traces[t].yaxis === &#39;y&#39;){
  15. if (Math.max(...relevant_vals) &gt; y1_max){
  16. y1_max = Math.max(...relevant_vals);
  17. }
  18. if (Math.min(...relevant_vals) &lt; y1_min){
  19. y1_min = Math.min(...relevant_vals);
  20. }
  21. }else{
  22. if (Math.max(...relevant_vals) &gt; y2_max){
  23. y2_max = Math.max(...relevant_vals);
  24. }
  25. if (Math.min(...relevant_vals) &lt; y2_min){
  26. y2_min = Math.min(...relevant_vals);
  27. }
  28. }
  29. }
  30. if(y1_max &gt; 1){
  31. y1_max = y1_max - y1_max%250 + 250;
  32. y2_max = y2_max - y2_max%0.2 + 0.2;
  33. y2_min = y2_min - y2_min%0.2 - 0.2;
  34. if(y2_min &lt; y1_min){
  35. y1_min = -1 * Math.abs(y2_min) * Math.abs(y1_max) / Math.abs(y2_max);
  36. }
  37. }else{
  38. y1_max = 1;
  39. y1_min = 0;
  40. }
  41. layout.yaxis.autorange = false;
  42. layout.yaxis2.autorange = false;
  43. layout.xaxis.autorange = false;
  44. layout.yaxis.range = [y1_min, y1_max];
  45. layout.yaxis2.range = [y2_min, y2_max];
  46. if(new_x_min &amp;&amp; new_x_max){
  47. layout.xaxis.range = [new_x_min, new_x_max];
  48. }
  49. layout.shapes[0].y0 = y1_min;
  50. layout.shapes[0].y1 = y1_max;
  51. return layout;
  52. };

huangapple
  • 本文由 发表于 2023年6月12日 14:43:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454140.html
匿名

发表评论

匿名网友

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

确定