情节时间序列中的多个X轴

Posted

技术标签:

【中文标题】情节时间序列中的多个X轴【英文标题】:Multiple X axis in plotly timeseries 【发布时间】:2021-12-20 18:55:36 【问题描述】:

我正在尝试在 Plotly.js 中创建一个时序序列,该时序序列具有多个 X 轴来直观地对游戏的各个部分进行分组。所需最终状态的粗略描述:

我知道 Plotly.js 支持多个 x 轴,但我遇到了一些奇怪的行为,其中标签在图表中未正确呈现。我的尝试基于 plotly 提供的用于处理多轴的示例 - 核心区别在于我的数据是基于时间的并且是面向 x 的:https://plotly.com/javascript/multiple-axes/

这是我的代码和奇怪的行为:

Codepen

data = [
    
        "x": [
            "2020-01-08 00:00:29",
            "2020-01-08 00:00:40",
            "2020-01-08 00:00:55",
            "2020-01-08 00:01:38",
            "2020-01-08 00:01:52",
            "2020-01-08 00:02:17",
            "2020-01-08 00:02:25",
            "2020-01-08 00:02:41",
            "2020-01-08 00:03:12",
            "2020-01-08 00:03:28",
            "2020-01-08 00:03:59",
            "2020-01-08 00:04:07",
            "2020-01-08 00:04:49",
            "2020-01-08 00:05:06",
            "2020-01-08 00:05:23",
            "2020-01-08 00:06:14",
            "2020-01-08 00:07:53",
            "2020-01-08 00:08:04",
            "2020-01-08 00:09:42",
            "2020-01-08 00:10:04",
            "2020-01-08 00:10:25",
            "2020-01-08 00:11:24"
        ],
        "y": [
            -2,
            1,
            -1,
            -4,
            -2,
            0,
            -2,
            0,
            -1,
            1,
            3,
            1,
            -2,
            0,
            -2,
            -7,
            -7,
            -9,
            -13,
            -16,
            -14,
            -10
        ],
        "mode": "lines",
        "name": "Q1",
        "xaxis": "xaxis"
    ,
    
        "x": [
            "2020-01-08 00:12:42",
            "2020-01-08 00:13:43",
            "2020-01-08 00:14:03",
            "2020-01-08 00:14:37",
            "2020-01-08 00:14:48",
            "2020-01-08 00:16:15",
            "2020-01-08 00:16:31",
            "2020-01-08 00:16:59",
            "2020-01-08 00:17:23",
            "2020-01-08 00:17:55",
            "2020-01-08 00:18:34",
            "2020-01-08 00:19:07",
            "2020-01-08 00:19:38",
            "2020-01-08 00:20:11",
            "2020-01-08 00:21:03",
            "2020-01-08 00:21:23",
            "2020-01-08 00:21:59",
            "2020-01-08 00:22:33",
            "2020-01-08 00:23:43"
        ],
        "y": [
            -8,
            -6,
            -8,
            -10,
            -8,
            -5,
            -8,
            -6,
            -8,
            -6,
            -8,
            -6,
            -4,
            -2,
            -4,
            -6,
            -4,
            -5,
            -4
        ],

        "mode": "lines",
        "name": "Q2",
        "xaxis": "xaxis2"
    ,
    
        "x": [
            "2020-01-08 00:24:41",
            "2020-01-08 00:24:58",
            "2020-01-08 00:25:21",
            "2020-01-08 00:25:46",
            "2020-01-08 00:26:12",
            "2020-01-08 00:26:32",
            "2020-01-08 00:27:19",
            "2020-01-08 00:28:01",
            "2020-01-08 00:28:34",
            "2020-01-08 00:29:08",
            "2020-01-08 00:30:34",
            "2020-01-08 00:31:05",
            "2020-01-08 00:32:02",
            "2020-01-08 00:32:21",
            "2020-01-08 00:32:55",
            "2020-01-08 00:33:42",
            "2020-01-08 00:34:09",
            "2020-01-08 00:34:22",
            "2020-01-08 00:34:58",
            "2020-01-08 00:35:09"
        ],
        "y": [
            -2,
            -4,
            -6,
            -9,
            -12,
            -10,
            -13,
            -10,
            -7,
            -5,
            -5,
            -3,
            -4,
            -6,
            -9,
            -7,
            -9,
            -7,
            -5,
            -7
        ],
        "line": 
            "shape": "linear"
        ,
        "mode": "lines",
        "name": "Q3",
        "xaxis": "xaxis3"
    ,
    
        "x": [
            "2020-01-08 00:36:46",
            "2020-01-08 00:37:44",
            "2020-01-08 00:38:23",
            "2020-01-08 00:39:02",
            "2020-01-08 00:40:29",
            "2020-01-08 00:40:59",
            "2020-01-08 00:41:07",
            "2020-01-08 00:41:28",
            "2020-01-08 00:42:00",
            "2020-01-08 00:42:13",
            "2020-01-08 00:42:50",
            "2020-01-08 00:43:29",
            "2020-01-08 00:43:59",
            "2020-01-08 00:44:23",
            "2020-01-08 00:44:53",
            "2020-01-08 00:44:59",
            "2020-01-08 00:45:29",
            "2020-01-08 00:46:14",
            "2020-01-08 00:46:55",
            "2020-01-08 00:47:49",
            "2020-01-08 00:47:57"
        ],
        "y": [
            -9,
            -11,
            -5,
            -8,
            -11,
            -13,
            -10,
            -12,
            -14,
            -12,
            -14,
            -12,
            -10,
            -11,
            -11,
            -10,
            -7,
            -4,
            -1,
            1,
            -1
        ],
        "line": 
            "shape": "linear"
        ,
        "mode": "lines",
        "name": "Q4",
        "xaxis": "xaxis4"
    
]

layout = 
    "title": 
        "text": "Game data"
    ,
    "xaxis": 
        "title": 
            "text": "q1"
        ,
        "tickvals": [
            "2020-01-08 00:00:00",
            "2020-01-08 00:02:00",
            "2020-01-08 00:04:00",
            "2020-01-08 00:06:00",
            "2020-01-08 00:08:00",
            "2020-01-08 00:12:00"
        ],
        "tickformat": "%M:%S",
        "type": "date",
    ,
    "xaxis2": 
        "title": 
            "text": "q2"
        ,
        "tickvals": [
            "2020-01-08 00:12:00",
            "2020-01-08 00:14:00",
            "2020-01-08 00:16:00",
            "2020-01-08 00:18:00",
            "2020-01-08 00:20:00",
            "2020-01-08 00:22:00",
            "2020-01-08 00:24:00"
        ],
        "tickformat": "%M:%S",
        "type": "date",
    ,
    "xaxis3": 
        "title": 
            "text": "q3"
        ,
        "tickvals": [
            "2020-01-08 00:24:00",
            "2020-01-08 00:26:00",
            "2020-01-08 00:28:00",
            "2020-01-08 00:30:00",
            "2020-01-08 00:32:00",
            "2020-01-08 00:34:00",
            "2020-01-08 00:36:00"
        ],
        "tickformat": "%M:%S",
        "type": "date",
    ,
    "xaxis4": 
        "title": 
            "text": "q4"
        ,
        "tickvals": [
            "2020-01-08 00:36:00",
            "2020-01-08 00:38:00",
            "2020-01-08 00:40:00",
            "2020-01-08 00:42:00",
            "2020-01-08 00:44:00",
            "2020-01-08 00:46:00",
            "2020-01-08 00:48:00"
        ],
        "tickformat": "%M:%S",
        "type": "date",
    ,
    "yaxis": 
        "type": "linear",
        "autorange": true
    


Plotly.newPlot('myDiv', data, layout);

【问题讨论】:

【参考方案1】:

我不认为多 x 轴正是您要寻找的,因为这通常意味着您有另一个 x 轴,其比例与主 x 轴相反,但在您想要的输出中,您只有一个 x 轴。

相反,您可以使用 multi-categorical x-axis,但我认为您不能将 x 轴指定为 "type": "date",因为一个类别将是日期,而另一个类别将是像“Q1”这样的字符串”。

因此,我认为表示多类别 x 轴的最佳方法是简单地将字符串 "Q1", ... "Q4" 添加为文本注释,并通过使用纸张坐标定位它们将它们放置在日期刻度下方。

然后使用Plotly shapes,您可以在每个四分之一时间刻度线周围画线,使您的 xaxis 看起来有一个多类别。

您可以查看密码笔here。

category_annotations = [];
text_annotations = []
quarter_names = ["Q1","Q2","Q3","Q4"]
quarter_positions = [0.125,0.375,0.625,0.875]
quarter_times = [
  "2020-01-08 00:00:00",
  "2020-01-08 00:12:00",
  "2020-01-08 00:24:00",
  "2020-01-08 00:36:00",
  "2020-01-08 00:48:00"
]

for (let i = 0; i < quarter_times.length; i++) 
  category_annotations.push(
    
        type: 'line',
        x0: quarter_times[i],
        x1: quarter_times[i],
        y0: -0.20,
        y1: 0.05,
        xref: 'x',
        yref: 'paper',
        line: 
          color: 'black',
          width: 1
        
    
  )


category_annotations.push(
  
        type: 'line',
        x0: 0,
        x1: 1,
        y0: 0.05,
        y1: 0.05,
        xref: 'paper',
        yref: 'paper',
        line: 
          color: 'black',
          width: 1
        
    
)

for (let i = 0; i < quarter_names.length; i++) 
  text_annotations.push(
    
      x: quarter_positions[i],
      y: -0.15,
      xref: 'paper',
      yref: 'paper',
      text: quarter_names[i],
      showarrow: false,
    
  )


data = [
    
        "x": [
            "2020-01-08 00:00:29",
            "2020-01-08 00:00:40",
            "2020-01-08 00:00:55",
            "2020-01-08 00:01:38",
            "2020-01-08 00:01:52",
            "2020-01-08 00:02:17",
            "2020-01-08 00:02:25",
            "2020-01-08 00:02:41",
            "2020-01-08 00:03:12",
            "2020-01-08 00:03:28",
            "2020-01-08 00:03:59",
            "2020-01-08 00:04:07",
            "2020-01-08 00:04:49",
            "2020-01-08 00:05:06",
            "2020-01-08 00:05:23",
            "2020-01-08 00:06:14",
            "2020-01-08 00:07:53",
            "2020-01-08 00:08:04",
            "2020-01-08 00:09:42",
            "2020-01-08 00:10:04",
            "2020-01-08 00:10:25",
            "2020-01-08 00:11:24"
        ],
        "y": [
            -2,
            1,
            -1,
            -4,
            -2,
            0,
            -2,
            0,
            -1,
            1,
            3,
            1,
            -2,
            0,
            -2,
            -7,
            -7,
            -9,
            -13,
            -16,
            -14,
            -10
        ],
        "mode": "lines",
        "name": "Q1",
    ,
    
        "x": [
            "2020-01-08 00:12:42",
            "2020-01-08 00:13:43",
            "2020-01-08 00:14:03",
            "2020-01-08 00:14:37",
            "2020-01-08 00:14:48",
            "2020-01-08 00:16:15",
            "2020-01-08 00:16:31",
            "2020-01-08 00:16:59",
            "2020-01-08 00:17:23",
            "2020-01-08 00:17:55",
            "2020-01-08 00:18:34",
            "2020-01-08 00:19:07",
            "2020-01-08 00:19:38",
            "2020-01-08 00:20:11",
            "2020-01-08 00:21:03",
            "2020-01-08 00:21:23",
            "2020-01-08 00:21:59",
            "2020-01-08 00:22:33",
            "2020-01-08 00:23:43"
        ],
        "y": [
            -8,
            -6,
            -8,
            -10,
            -8,
            -5,
            -8,
            -6,
            -8,
            -6,
            -8,
            -6,
            -4,
            -2,
            -4,
            -6,
            -4,
            -5,
            -4
        ],

        "mode": "lines",
        "name": "Q2",
    ,
    
        "x": [
            "2020-01-08 00:24:41",
            "2020-01-08 00:24:58",
            "2020-01-08 00:25:21",
            "2020-01-08 00:25:46",
            "2020-01-08 00:26:12",
            "2020-01-08 00:26:32",
            "2020-01-08 00:27:19",
            "2020-01-08 00:28:01",
            "2020-01-08 00:28:34",
            "2020-01-08 00:29:08",
            "2020-01-08 00:30:34",
            "2020-01-08 00:31:05",
            "2020-01-08 00:32:02",
            "2020-01-08 00:32:21",
            "2020-01-08 00:32:55",
            "2020-01-08 00:33:42",
            "2020-01-08 00:34:09",
            "2020-01-08 00:34:22",
            "2020-01-08 00:34:58",
            "2020-01-08 00:35:09"
        ],
        "y": [
            -2,
            -4,
            -6,
            -9,
            -12,
            -10,
            -13,
            -10,
            -7,
            -5,
            -5,
            -3,
            -4,
            -6,
            -9,
            -7,
            -9,
            -7,
            -5,
            -7
        ],
        "line": 
            "shape": "linear"
        ,
        "mode": "lines",
        "name": "Q3",
    ,
    
        "x": [
            "2020-01-08 00:36:46",
            "2020-01-08 00:37:44",
            "2020-01-08 00:38:23",
            "2020-01-08 00:39:02",
            "2020-01-08 00:40:29",
            "2020-01-08 00:40:59",
            "2020-01-08 00:41:07",
            "2020-01-08 00:41:28",
            "2020-01-08 00:42:00",
            "2020-01-08 00:42:13",
            "2020-01-08 00:42:50",
            "2020-01-08 00:43:29",
            "2020-01-08 00:43:59",
            "2020-01-08 00:44:23",
            "2020-01-08 00:44:53",
            "2020-01-08 00:44:59",
            "2020-01-08 00:45:29",
            "2020-01-08 00:46:14",
            "2020-01-08 00:46:55",
            "2020-01-08 00:47:49",
            "2020-01-08 00:47:57"
        ],
        "y": [
            -9,
            -11,
            -5,
            -8,
            -11,
            -13,
            -10,
            -12,
            -14,
            -12,
            -14,
            -12,
            -10,
            -11,
            -11,
            -10,
            -7,
            -4,
            -1,
            1,
            -1
        ],
        "line": 
            "shape": "linear"
        ,
        "mode": "lines",
        "name": "Q4",
    
];

layout = 
    "title": 
        "text": "Game data"
    ,
    "xaxis": 
      "tickformat": "%M:%S",
      "type": "date",
      "tickvals": [
            "2020-01-08 00:00:00",
            "2020-01-08 00:02:00",
            "2020-01-08 00:04:00",
            "2020-01-08 00:06:00",
            "2020-01-08 00:08:00",
            "2020-01-08 00:10:00",
            "2020-01-08 00:12:00",
            "2020-01-08 00:14:00",
            "2020-01-08 00:16:00",
            "2020-01-08 00:18:00",
            "2020-01-08 00:20:00",
            "2020-01-08 00:22:00",
            "2020-01-08 00:24:00",
            "2020-01-08 00:26:00",
            "2020-01-08 00:28:00",
            "2020-01-08 00:30:00",
            "2020-01-08 00:32:00",
            "2020-01-08 00:34:00",
            "2020-01-08 00:36:00",
            "2020-01-08 00:38:00",
            "2020-01-08 00:40:00",
            "2020-01-08 00:42:00",
            "2020-01-08 00:44:00",
            "2020-01-08 00:46:00",
            "2020-01-08 00:48:00"
      ],
    ,
    "yaxis": 
        "tickmode": "linear",
        "tick0": -1,
        "dtick": 1.00,
        "zeroline": false
    ,
    "annotations": text_annotations,
    "shapes": category_annotations


Plotly.newPlot('myDiv', data, layout);

【讨论】:

这是一个非常聪明的解决方案,我没想到会这样解决 - 谢谢! 没问题 - 很高兴听到我的回答很有帮助!

以上是关于情节时间序列中的多个X轴的主要内容,如果未能解决你的问题,请参考以下文章

在情节中,如何创建链接的 X 轴?

Plotly:是不是可以在情节时间线上添加第二个 y 轴?

为多个轴放置一个图例

如何更改 matplotlib 中的 x 轴以便没有空格?

添加多层刻度标签以绘制时间序列的 x 轴

在ggplot2中的x轴标签下方添加图像