带有gnuplot或八度音阶的3D直方图

use*_*333 7 matlab gnuplot histogram octave

我想画一个3D直方图(用gnuplot或octave)来表示我的数据.假设我有一个以下形式的数据文件:

2 3 4    
8 4 10    
5 6 7
Run Code Online (Sandbox Code Playgroud)

我想在集合[1,3] x [1,3]中绘制九个彩色条(矩阵的大小),这样条的颜色与条的高度成比例.我怎样才能做到这一点?

Amr*_*mro 12

下面是我实现的一个函数,它可以作为bar3替换(部分).

在我的版本中,通过创建补丁图形对象来渲染条形图:我们构建顶点坐标矩阵和连接这些顶点的面列表.

我们的想法是首先构建一个"3d立方体"作为模板,然后将它复制到我们所拥有的多个条形图.每个杆根据其位置和高度进行移动和缩放.

顶点/面矩阵以矢量化方式构造(看起来没有循环!),结果是为所有条形绘制的单个patch对象,而不是每个条形一个多个补丁(这在图形性能方面更有效)).

该函数可能已经通过指定形成的多边形连接顶点的坐标,通过使用实现XData,YData,ZDataCData属性,而不是VerticesFaces性质.事实上,这就是bar3内部所做的.这种方法通常需要更大的数据来定义补丁(因为我们不能在补丁面上有共享点,尽管我在实现中并不关心这一点).这是一个相关的帖子,我试图解释由其构造的数据的结构bar3.

my_bar3.m

function pp = my_bar3(M, width)
    % MY_BAR3  3D bar graph.
    %
    % M     - 2D matrix
    % width - bar width (1 means no separation between bars)
    %
    % See also: bar3, hist3

    %% construct patch
    if nargin < 2, width = 0.8; end
    assert(ismatrix(M), 'Matrix expected.')

    % size of matrix
    [ny,nx] = size(M);

    % first we build a "template" column-bar (8 vertices and 6 faces)
    % (bar is initially centered at position (1,1) with width=? and height=1)
    hw = width / 2;    % half width
    [X,Y,Z] = ndgrid([1-hw 1+hw], [1-hw 1+hw], [0 1]);
    v = [X(:) Y(:) Z(:)];
    f = [
        1 2 4 3 ; % bottom
        5 6 8 7 ; % top
        1 2 6 5 ; % front
        3 4 8 7 ; % back
        1 5 7 3 ; % left
        2 6 8 4   % right
    ];

    % replicate vertices of "template" to form nx*ny bars
    [offsetX,offsetY] = meshgrid(0:nx-1,0:ny-1);
    offset = [offsetX(:) offsetY(:)]; offset(:,3) = 0;
    v = bsxfun(@plus, v, permute(offset,[3 2 1]));
    v = reshape(permute(v,[2 1 3]), 3,[]).';

    % adjust bar heights to be equal to matrix values
    v(:,3) = v(:,3) .* kron(M(:), ones(8,1));

    % replicate faces of "template" to form nx*ny bars
    increments = 0:8:8*(nx*ny-1);
    f = bsxfun(@plus, f, permute(increments,[1 3 2]));
    f = reshape(permute(f,[2 1 3]), 4,[]).';

    %% plot
    % prepare plot
    if exist('OCTAVE_VERSION','builtin') > 0
        % If running Octave, select OpenGL backend, gnuplot wont work
        graphics_toolkit('fltk');
        hax = gca;
    else
        hax = newplot();
        set(ancestor(hax,'figure'), 'Renderer','opengl')
    end


    % draw patch specified by faces/vertices
    % (we use a solid color for all faces)
    p = patch('Faces',f, 'Vertices',v, ...
        'FaceColor',[0.75 0.85 0.95], 'EdgeColor','k', 'Parent',hax);
    view(hax,3); grid(hax,'on');
    set(hax, 'XTick',1:nx, 'YTick',1:ny, 'Box','off', 'YDir','reverse', ...
        'PlotBoxAspectRatio',[1 1 (sqrt(5)-1)/2]) % 1/GR (GR: golden ratio)

    % return handle to patch object if requested
    if nargout > 0
        pp = p;
    end
end
Run Code Online (Sandbox Code Playgroud)

下面是一个将它与bar3MATLAB 中的内置函数进行比较的示例:

subplot(121), bar3(magic(7)), axis tight
subplot(122), my_bar3(magic(7)), axis tight
Run Code Online (Sandbox Code Playgroud)

comparison_bar3

请注意,我选择以单一纯色(与hist3函数的输出类似)为所有条纹着色,而MATLAB强调具有匹配颜色的矩阵列.

虽然很容易定制补丁 ; 以下是使用索引颜色映射(缩放)匹配bar3 着色模式的示例:

M = membrane(1); M = M(1:3:end,1:3:end);
h = my_bar3(M, 1.0);

% 6 faces per bar
fvcd = kron((1:numel(M))', ones(6,1));
set(h, 'FaceVertexCData',fvcd, 'FaceColor','flat', 'CDataMapping','scaled')

colormap hsv; axis tight; view(50,25)
set(h, 'FaceAlpha',0.85)   % semi-transparent bars
Run Code Online (Sandbox Code Playgroud)

bar3_coloring

或者说你想根据它们的高度使用渐变为条形着色:

M = 9^2 - spiral(9);
h = my_bar3(M, 0.8);

% use Z-coordinates as vertex colors (indexed color mapping)
v = get(h, 'Vertices');
fvcd = v(:,3);
set(h, 'FaceVertexCData',fvcd, 'FaceColor','interp')

axis tight vis3d; daspect([1 1 10]); view(-40,20)
set(h, 'EdgeColor','k', 'EdgeAlpha',0.1)
Run Code Online (Sandbox Code Playgroud)

gradient_bars_animation

请注意,在最后一个示例中,图形"渲染器"属性将影响渐变的外观.在MATLAB中,'OpenGL'渲染器将沿RGB颜色空间插入颜色,而其他两个渲染器('Painters'和'ZBuffer')将在所使用的当前颜色映射的颜色之间进行插值(因此直方图条看起来像迷你colorbars穿过jet调色板,而不是从底部的蓝色到任何颜色在定义高度的渐变,如上所示).有关详细信息,请参阅此帖子.


我已经测试了在Windows上运行的Octave 3.6.43.8.1中的功能,它运行良好.如果您运行我上面显示的示例,您会发现某些高级3D功能尚未在Octave中正确实现(这包括透明度,照明等等).我也使用了Octave中不可用的函数membranespiral构建样本矩阵,但这些对于代码来说并不重要,只需用你自己的数据替换它们:)

octave_my_bar3


RTL*_*RTL 6

仅使用 OCTAVE 中可用函数的解决方案,经Octave-online测试

该解决方案以类似于 Matlabshist3d函数内部的方式生成表面。

简单来说:

  • 创建一个带有 4 个点的表面,每个值的“高度”都绘制在每个 bin 边缘。
  • 每个都被零包围,零也绘制在每个 bin 边缘。
  • 颜色设置为基于 bin 值,并应用于 4 个点和周围的零点。(以便“条”的边缘和顶部着色以匹配“高度”。)

对于作为包含 bin 高度的矩阵给出的数据(代码中的 bin_values):

代码

bin_values=rand(5,4); %some random data

bin_edges_x=[0:size(bin_values,2)]; 
x=kron(bin_edges_x,ones(1,5));
x=x(4:end-2);

bin_edges_y=[0:size(bin_values,1)]; 
y=kron(bin_edges_y,ones(1,5));
y=y(4:end-2);

mask_z=[0,0,0,0,0;0,1,1,0,0;0,1,1,0,0;0,0,0,0,0;0,0,0,0,0];
mask_c=ones(5);
z=kron(bin_values,mask_z);
c=kron(bin_values,mask_c);

surf(x,y,z,c)
Run Code Online (Sandbox Code Playgroud)

输出

3dhist


Sha*_*hai 2

您看过本教程吗bar3

稍微调整一下:

Z=[2 3 4
   8 4 10
   5 6 7]; % input data
figure; 
h = bar3(Z); % get handle to graphics
for k=1:numel(h), 
    z=get(h(k),'ZData'); % old data - need for its NaN pattern
    nn = isnan(z); 
    nz = kron( Z(:,k),ones(6,4) ); % map color to height 6 faces per data point 
    nz(nn) = NaN; % used saved NaN pattern for transparent faces 
    set(h(k),'CData', nz); % set the new colors
end
colorbar;
Run Code Online (Sandbox Code Playgroud)

这就是你最后得到的: 在此输入图像描述