Matplotlib:用图片替代散点出现拉伸问题的解决方法
为什么归一化到0-1能解决散点图图像标记的拉伸问题?
嘿,这个问题我之前做类似的图像标记散点图时也碰到过,咱们来一步步拆解背后的原理:
1. 图像数据的两种常见范围差异
咱们平时接触的位图(比如你的白底黑矩形图),通常是以uint8类型存储的,像素值范围是0-255:
- 0代表纯黑,255代表纯白,中间值对应不同灰度。
而0-1的范围是浮点型的归一化数据,把原0-255的像素值除以255得到,此时0依然是黑,1依然是白,但每个像素值是小数形式。
2. 绘图库对两种数据的渲染逻辑不同
大部分绘图库(比如Stack Overflow上这类问题最常用的matplotlib)对这两种数据的处理规则有本质区别:
- 当传入uint8类型的0-255图像时,库会默认把它当成「已经标准化的8位图像」,但在将其缩放到散点标记的小尺寸时,底层的插值/缩放逻辑会受到整数类型的限制:整数的步长是1,缩放时像素映射只能取整数值,很容易导致图像的宽高比被破坏,出现拉伸变形。尤其是你的图像只有黑(0)和白(255)两种极端值,这种生硬的整数插值会让矩形的边缘变形、整体比例失调。
- 当传入0-1的浮点型图像时,库会将其识别为「浮点型图像数据」,此时会启用更平滑的浮点插值算法。而且库会自动以0作为最小值(黑)、1作为最大值(白)来渲染,缩放时能精准保持原图像的宽高比和形状,不会因为整数步长的限制导致拉伸。
3. 结合你的场景具体解释
你的白底黑矩形图像,原数据是0和255的uint8数组。之前用Stack Overflow的代码时,绘图库在把这个图像缩放到散点标记大小的过程中,因为整数类型的限制,插值时无法平滑过渡,导致矩形被拉伸。而当你把数据归一化到0-1后,浮点型的插值能精准匹配原图像的比例,所以拉伸问题就解决了。
简单来说:归一化到0-1相当于给绘图库传递了「这是需要平滑处理的相对亮度数据」的信号,而不是「这是固定步长的8位像素数据」,从而让缩放逻辑正确工作。
内容的提问来源于stack exchange,提问作者jds




