AnyMath 文档

像素完美渲染

该页面正在翻译中。

假设您在矩阵中有一些数据,并希望完全按照原样绘制它。 更明确地说,您希望每个绘制的像素从矩阵的一个值中采样,而不发生插值。 本教程将解释如何做到这一点。

热图图像

要绘制一个值矩阵,我们可以使用 图像热图. 使用默认设置 图像 被插值并使用灰度颜色表 热图 是像素化的,并使用了一个彩色的颜色表(viridis). 它们在单元格或"像素"的位置上也有所不同。 在 图像 您可以设置绘图开始和结束的位置,即设置最左边像素的左边缘和最右边像素的右边缘的位置。 (对于底部和顶部像素也是如此。)在 热图 您通常设置单元格中心的位置,但您也可以通过传递来设置边缘 尺寸+1 x和y值。 通过正确的设置,两者都可以看起来相同: </无翻译>

using CairoMakie
using CairoMakie

data = [1 2; 3 4; 5 6]

f = Figure()

a1, p = image(f[1, 1], data)
a2, p = heatmap(f[1, 2], data)

# 0..3, 0..2 is the default, we could omit it
a3, p = image(f[2, 1], 0..3, 0..2, data, colormap = :viridis, interpolate = false)
a4, p = heatmap(f[2, 2], 0:3, 0:2, data, colormap = :viridis, interpolate = false)
# Note that length(0:3), length(0:2) == size(data) .+ 1

limits!.([a1, a2, a3, a4], -1, 4, -1, 3)

f
9f42337

全屏剧情

让我们考虑从一些数据创建一个普通图像的情况,没有任何通常的轴装饰。 在这种情况下,使用它是没有用的 轴心,轴心 因为它们都通过填充和布局来消耗空间。 相反,我们使用 场景 直接。 可以使用以下方法创建特定大小的空场景 </无翻译>

using CairoMakie
using CairoMakie

scene = Scene(size = (200, 100), camera = campixel!)
20b4101

在这里我们明确地设置 相机=campixel! 使场景采用像素单位。 更具体地说,这将场景的左下角设置为(0,0),右上角设置为 大小. 使用这些限制,我们现在可以绘制一个 图像 (或 热图)完全填充场景的情节: </无翻译>

using CairoMakie
using CairoMakie

data = [ifelse(x > 180, 0, x/100) * ifelse(y > 80, 0, y/50) for x in 1:200, y in 1:100]

scene = Scene(size = (200, 100), camera = campixel!)

# image will have the correct limits by default (0..200, 0..100)
image!(scene, data, colormap = :viridis, interpolate = false)

# alternatively with heatmap:
# heatmap!(scene, 0:200, 0:100, data)

scene
8dca907

如果我们想放大图像,我们可以简单地调整场景的大小和情节的限制。 为 热图 我们需要小心一点,因为 0:600 将给我们601个值,而不是我们需要的201个值。 为了解决这个问题,我们需要明确地包含每个单元格的大小作为范围的步骤。 </无翻译>

using CairoMakie
using CairoMakie

data = [ifelse(x > 180, 0, x/100) * ifelse(y > 80, 0, y/50) for x in 1:200, y in 1:100]
scene = Scene(size = (3 * 200, 2 * 100), camera = campixel!)
image!(scene, 0..600, 0..200, data, colormap = :viridis, interpolate = false)
# heatmap!(scene, 0:3:600, 0:2:200, data)

scene
c8f024f

另一种选择是改变 px_per_unit 时保存场景。 使用 麦琪保存(文件名,场景,px_per_unit=2) 场景中的每个"像素"由保存图像中的2个像素表示。 这不会影响情节的限制,即在(200,100)场景中,您应该使用(200,100)作为情节的限制。 (如果你检查这里生成的图像,你会看到它们有两倍的大小给场景,因为文档呈现与 pixel_per_unit=2)

注意事项

照相机

虽然像素相机是直观的使用在这种情况下,它是没有必要的。 如果您创建的场景没有相机,它将默认为剪辑空间相机。 因此,场景坐标的大小总是从-1到1。 这可能会简化绘图,因为在调整场景限制时不必调整图像限制: </无翻译>

using CairoMakie
using CairoMakie

data = [ifelse(x > 180, 0, x/100) * ifelse(y > 80, 0, y/50) for x in 1:200, y in 1:100]
scene = Scene(size = (3 * 200, 2 * 100))
image!(scene, -1..1, -1..1, data, colormap = :viridis, interpolate = false)
scene
f5d63c9

同样也可以使用 相机=cam_relative! 以得到0。.1坐标。

GLMakie抗锯齿

GLMakie使用FXAA平滑渲染图像中的硬边缘。 这意味着它将插值和/或模糊具有显着亮度差异的像素。 这是我们不想要的东西,所以我们应该把它关掉: </无翻译>

using GLMakie
using GLMakie

data = [ifelse(x > 180, 0, x/100) * ifelse(y > 80, 0, y/50) for x in 1:200, y in 1:100]
scene = Scene(size = (3 * 200, 2 * 100))
image!(scene, -1..1, -1..1, data, colormap = :viridis, interpolate = false, fxaa = false)
scene
3decdc9

WGLMakie使用MSAA代替,它在多个子像素处对每个像素进行采样。 通过像素完美映射,这将多次采样相同的颜色,从而产生相同的最终颜色。 所以在WGLMakie我们没有这个问题。

像素完美绘制在一个数字

使用LScene

如果你想绘制多个像素完美矩阵使用 对于布局是非常有用的。 我们可以继续依靠 场景 我们上面使用的力学 LScene,LScene. 在这里,我们需要设置 阔度身高 而不是 大小 让layouting知道LScene需要多少空间。 resize_to_layout!() 对于使图形适应场景的大小也非常有用: </无翻译>

using CairoMakie
using CairoMakie

# length(50:50) = 101
data = [x*y/1000 for x in -50:50, y in -50:50]

fig = Figure()

s1 = LScene(fig[1, 1], width = 101, height = 101, show_axis = false, scenekw = (camera = cam_relative!,))
image!(s1, 0..1, 0..1, data, colormap = :viridis, interpolate = false)

s2 = LScene(fig[1, 2], width = 101, height = 101, show_axis = false, scenekw = (camera = campixel!,))
heatmap!(s2, 0:101, 0:101, data)

resize_to_layout!(fig)
fig
8387a2b

要控制图形生成的空白,您可以调整 图(figure_padding=。..) 用于外填充物和 rowgap!(图,。..)colgap!(图)布局,。..) 为内间隙。

使用轴

如果你想策划一个 轴心,轴心 你可以有效地只是更换 LScene,LScene 在上面的例子中: </无翻译>

using CairoMakie
using CairoMakie

# length(50:50) = 101
data = [x*y/1000 for x in -50:50, y in -50:50]

fig = Figure()

a1 = Axis(fig[1, 1], width = 101, height = 101)
image!(a1, data, colormap = :viridis, interpolate = false)

a2 = Axis(fig[1, 2], width = 101, height = 101)
heatmap!(a2, data)

resize_to_layout!(fig)
fig
9bfdbd0

图像热图 轴将选择与相应绘图紧密对齐的限制。 因此,您不需要将绘图的x和y值与数据和轴的维度进行匹配。 但是,您可能仍然希望将它们设置为 热图 所以蜱不会与细胞中心对齐。 您可能还想关闭棘(leftspinevisible=错误 等),因为它们重叠图像的边缘。