简体   繁体   English

Matlab / Octave:如何在指定网格线间距的同时显示矩阵?

[英]Matlab/Octave: how to display a matrix while specifying grid line spacing?

I would like to display a 2D array named C under MATLAB/Octave; 我想在MATLAB / Octave下显示一个名为C的二维数组; I would normally use imagesc , but this time I would like to specify multiple cell sizes. 我通常会使用imagesc ,但这次我想指定多个单元格大小。

imagesc does not allow me to do this: if I set x and y as two elements vectors, imagesc(x,y,C) simply specifies the image location, but does not give me control over the grid spacing. imagesc不允许我这样做:如果我将xy设置为两个元素向量, imagesc(x,y,C)只是指定图像位置,但不能让我控制网格间距。

I was thinking of using pcolor , but it creates a pseudocolor plot using each set of four adjacent points in C to define a surface rectangle. 我正在考虑使用pcolor ,但它使用C中的每组四个相邻点创建一个伪彩色图,以定义一个表面矩形。 Therefore a 4x4 matrix will appear as a 3x3 grid! 因此,4x4矩阵将显示为3x3网格!

QUESTION: do you know about any built-in function that would allow me to display a 2D array while specifying grid lines spacing? 问题:您是否知道任何内置函数可以让我在指定网格线间距时显示2D数组?

Thanks a lot for your answer! 非常感谢您的回答!

EXAMPLE

Here is an example of what I would like to achieve. 这是我想要实现的一个例子。
Let's say I want to display the matrix C=magic(4) 假设我要显示矩阵C=magic(4)

imagesc(C) will return: imagesc(C)将返回:

imagesc(C)返回的图像

Now let's define two arrays X and Y containing the pixel's width and height (or length): 现在让我们定义两个包含像素宽度和高度(或长度)的数组XY

X=[1, 1, 2, 1]
Y=[1, 1, 1, 1]

I am looking for a function of X , Y and C that would return the following image: 我正在寻找XYC的函数,它将返回以下图像:

我试图实现的表示形象

Please note that I created the image above using paint! 请注意,我使用油漆创建了上面的图像!

Disclaimer: this solution is simple, and close to the intended result, but it will distort the data due to the way pcolor creates the plot. 免责声明:此解决方案很简单,并且接近预期的结果,但由于pcolor创建绘图的方式,它会扭曲数据。 For a more cumbersome but precise solution, see the answer by Tasos Papastylianou . 有关更麻烦但更精确的解决方案,请参阅Tasos Papastylianou的答案

You could kludge your way with pcolor , you just have to use cumsum to turn your pixel widths into coordinates. 你可以使用pcolor cumsum你的方式,你只需要使用cumsum将像素宽度转换为坐标。 The kludgy bit is adding zero-padding that is later thrown away by pcolor : kludgy位正在添加零填充,后来被pcolor抛弃:

C = magic(4);
X = [1, 1, 2, 1];
Y = [1, 1, 1, 1];
Xt = [0, cumsum(X)];
Yt = [0, cumsum(Y)];
Ct = C;
Ct(end+1,end+1) = 0; % or more nicely: pre-allocate and overwrite with C

pcolor(Xt,Yt,Ct);
%optionally flip y axis to reconstruct imagesc() output
axis ij;

产量

tl;dr : control aspect ratio with daspect and draw custom gridlines tl; dr :使用daspect控制纵横比并绘制自定义网格线


Explanation : Find below several examples which will give you an understanding of what's going on. 说明 :在下面找到几个可以让您了解正在发生的事情的示例。

Here is the solution I mentioned in the comments. 这是我在评论中提到的解决方案。 It involves drawing an image with imagesc and coordinates, as you hinted, and also controlling the pixel aspect ratio using daspect . 它包括在您暗示的情况下使用imagesc和坐标绘制图像,并使用daspect控制像素长宽比。 For complete control, it's best to draw your gridlines separately. 为了完全控制,最好分别绘制网格线。

Run each cell separately to see what it does. 分别运行每个单元格以查看它的作用。

%%%% In file LookAtMeHacker.m
[Shodan,M] = imread('http://vignette2.wikia.nocookie.net/shodan/images/0/09/SHODAN_1.jpg');

%% Aspect ratios for normal imagesc
% Default aspect ratio, automatically calculated from image size
imagesc(Shodan); 
ImageSize   = size(Shodan)
AspectRatio = daspect()
title(sprintf('Default view. Aspect Ratio= %d:%d', ...
              AspectRatio(2), AspectRatio(1)));
%% Isotropic pixels
axis equal; AspectRatio = daspect();
title(sprintf('Axis ''equal''. Aspect Radio= %d:%d', ...
              AspectRatio(2), AspectRatio(1)));

%% Custom aspect ratio: 16:9
daspect([9,16,1]); AspectRatio = daspect();
title(sprintf('Custom Aspect Radio= %d:%d', ...
              AspectRatio(2), AspectRatio(1)));

%% Aspect ratios for imagesc with coordinates
% Default view
imagesc([0,40], [10, 30], Shodan)
AspectRatio = daspect()
title(sprintf('Default view.with coordinates; Aspect Ratio= %d:%d', ...
              AspectRatio(2), AspectRatio(1)));

%% Isotropic pixels IN TERMS OF COORDINATES
axis equal; AspectRatio = daspect();
title(sprintf('Axis ''equal''. Aspect Radio= %d:%d', ...
              AspectRatio(2), AspectRatio(1)));

%% Custom VISUAL aspect ratio: 16:9
daspect([9/20,16/40,1]); AspectRatio = daspect();
title('Custom Aspect Radio= 16:9')

%% Custom gridlines:
for i = 10:5:30; line(xlim, i, 'linestyle',':','color','w', 'linewidth',3); end;
for i = 0:5:40; line(i, ylim, 'linestyle',':','color','w', 'linewidth',3); end;

End result: 最终结果:

在此输入图像描述

This adds on Andras' nice cumsum approach; 这增加了Andras的漂亮的cumsum方法; however, the problem with pcolor is that the values you get in the faces are not the values / colours you expect in your matrix, but interpolations from the values applied at the vertices of the pcolor graph. 然而, pcolor的问题在于,您在中获得的值不是您在矩阵中所期望的值/颜色,而是来自在pcolor图的顶点处应用的值的插值

Here's an approach that works around this. 这是一种可以解决这个问题的方法。 It's slow, because we're essentially plotting an area for each patch, and manually assigning colour, but you'll get the idea. 它很慢,因为我们实际上是为每个补丁绘制一个区域,并手动分配颜色,但你会得到这个想法。

C = magic(4);
X = [1, 1, 2, 1];
Y = [1, 1, 1, 1];
Xt = [0, cumsum(X)];
Yt = [0, cumsum(Y)];

Ct = round(1 + (255 * mat2gray(C))); % convert to 256 colourmap indices
Cmap = permute(jet(256),[1,3,2]);
Ct = Cmap(Ct,1,:);
Ct = reshape(Ct, size(C,1), size(C,2), []);

LimX = Xt(end);
for i = size(C,1):-1:1
  for j = 1:size(C,2);
    area([Xt(j),LimX],[Yt(i+1),Yt(i+1)], 'edgecolor','none','facecolor', squeeze(Ct(i,j,:))); hold on;
  end
end
hold off;
axis ij; daspect([1,1,1]);

Result / Comparisons: 结果/比较:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM