Plotly imshow 反转 y 标签反转图像

Ebr*_*rin 10 python plotly plotly-python

我想可视化一个 20x20 矩阵,其中左上角点是 (-10, 9),右下角是 (9, -10)。所以x从左到右递增,y从上到下递减。所以我的想法是将 x 标签作为列表传递:[-10, -9 ... 9, 9],将 y 标签作为 [9, 8 ... -9, -10] 传递。这在seaborn(matplotlib)中按预期工作,但是在plotly中这样做只会垂直反转图像。这是代码:

import numpy as np
import plotly.express as px

img = np.arange(20**2).reshape((20, 20))
fig = px.imshow(img,
            x=list(range(-10, 10)),
            y=list(range(-10, 10)),
            )
fig.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

import numpy as np
import plotly.express as px

img = np.arange(20**2).reshape((20, 20))
fig = px.imshow(img,
            x=list(range(-10, 10)),
            y=list(reversed(range(-10, 10))),
            )
fig.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

为什么会发生这种情况以及如何解决它?

编辑:添加seaborn代码以查看差异。如您所见,反转标签的范围只会更改标签,对图像没有任何影响,这就是我想要的效果。

import seaborn as sns
import numpy as np

img = np.arange(20**2).reshape((20, 20))

sns.heatmap(img, 
            xticklabels=list(range(-10, 10)),
            yticklabels=list(range(-10, 10))
            )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

import seaborn as sns
import numpy as np

img = np.arange(20**2).reshape((20, 20))

sns.heatmap(img, 
            xticklabels=list(range(-10, 10)),
            yticklabels=list(reversed(range(-10, 10)))
            )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Eri*_*ult 9

你应该使用origin

\n
\n

origin (str, \'upper\' 或 \'lower\' (默认 \'upper\')) \xe2\x80\x93 图像数组的 [0, 0] 像素的位置,在左上角或下角左角。约定 \xe2\x80\x98upper\xe2\x80\x99 通常用于矩阵和图像。

\n
\n
import numpy as np\nimport plotly.express as px\n\nimg = np.arange(20**2).reshape((20, 20))\nx = list(range(-10, 10))\ny = list(reversed(range(-10, 10)))\n\nfig = px.imshow(img, x=x, y=y, origin=\'lower\')\nfig.show()\n
Run Code Online (Sandbox Code Playgroud)\n
\n

为什么反转标签不能按预期工作?

\n

对于单通道数组(2d,而不是 rgb),px.imshow()默认情况下使用autorange=\'reversed\'y 轴上的参数构建热图跟踪,因为“约定 \xe2\x80\x98upper\xe2\x80\x99 通常用于矩阵”。这采用以下的形式:

\n
autorange = True if origin == "lower" else "reversed"\n
Run Code Online (Sandbox Code Playgroud)\n

问题是该autorange功能强制轴的方向:当“反转”时,y 应该从上到下增加(根据输入数据推断增加与减少,与非数字字符串的行为不同) ,这意味着y 轴翻转当且仅当 y 的范围尚未反转,在这种情况下,整体垂直翻转(任何点 (x, y) 保持其值)。这就是你开始的地方。

\n

现在,如果您反转 中的标签,它实际上会反转y数据的y 轴坐标(值应随着 y 的增加而减少),但通过这样做,由于 y 范围现在已经反转,自动范围不必翻转图像,因此它会导致 y 轴反转(预期)并且图像不翻转,因此与您开始时相比,图像从翻转\n变为未翻转(意外)。

\n
\n

备择方案

\n

在这种情况下,为了避免任何混淆,上述解决方案的替代方案是定义一个特定的range

\n
fig = px.imshow(img, x=x, y=y)\nfig.update_yaxes(autorange=False, range=[-10.5, 9.5])\n
Run Code Online (Sandbox Code Playgroud)\n

或者预先重新定向数据,在这种情况下,不需要反转 y(甚至更少指定tickvals/ticktext,除非根据偏好):

\n
img = img.tolist()[::-1]    # reverse data\nx = list(range(-10, 10))\ny = list(range(-10, 10))    # instead of y\n\nfig = px.imshow(img, x=x, y=y, origin=\'lower\')\n
Run Code Online (Sandbox Code Playgroud)\n
\n

输出(3 个代码片段相同)

\n

热图截图

\n