我有以下代表图表的Matlab图。我希望在较轻的那些上方显示较暗的颜色,使得较浅的边缘在穿过它们时不会改变较暗的边缘。我该怎么办?
编辑:用于重现示例的Matlab代码如下
plot(G, 'XData', Xcoords, 'YData', Ycoords,'NodeLabel',{}, 'MarkerSize', 7,...
'Linewidth',1.6, 'EdgeCData', G.Edges.Weight)
colormap(flipud(gray(40)));
colorbar('southoutside');
caxis([min(G.Edges.Weight) max(G.Edges.Weight)])
axis off
其中边的权重以G.Edges.Weight编码
要重现效果(使用较小的图形),您可以尝试使用以下代码:
A= zeros(4,4);
A(1,[2 3 4])=1;
A(2,4)=0.04;
A(2,[1 3])=1;
A(3,[2 1 4])=1;
A(4,2)=0.04;
A(4,[3 1])=1;
Xcoords=[1 2 2 1]';
Ycoords= [1 1 2 2 ]';
G= graph(A);% base toolbox
figure()
plot(G, 'XData', Xcoords, 'YData', Ycoords, 'NodeLabel',{}, 'MarkerSize', 7,...
'LineWidth', 3.8, 'EdgeCdata', G.Edges.Weight)
colormap(flipud(gray(40)));
colorbar('southoutside'); caxis([0 1]);
axis off
似乎是边缘的排序决定了谁在最顶层。例如,如果将权重0.04分配给另一个交叉边(A(1,3)= A(3,1)),则效果不可见,因为边A(2,4)= A(4,2)来了之后。
MATLAB的graph
类中的边表的顺序似乎非常依赖于图的邻接矩阵中的位置,这本身就不可能以保证某些任意边序的方式进行设计。所以我认为你只有两个选择:
第二种选择是可能的,注意到绘制的GraphPlot
对象在其LineStrip
中有一个NodeChildren
对象,它负责绘制所有相关边。因为您正在使用灰度颜色贴图,所以您需要了解此对象中的RGB数据,以确定如何对其顶点进行排序以获得正确的绘图顺序。
首先,将绘制的结果存储在P
中并将EdgeAlpha
设置为1
,以便绘制图形
以这种方式,较轻的边缘在穿过它们时不会改变较暗的边缘
P = plot(G, 'XData', Xcoords, 'YData', Ycoords, 'NodeLabel',{}, 'MarkerSize', 7,...
'LineWidth', 3.8, 'EdgeCdata', G.Edges.Weight, 'EdgeAlpha',1);
colormap(flipud(gray(40)));
colorbar('southoutside'); caxis([0 1]);
axis off
然后找到在绘图过程中创建的LineStrip
:
drawnow
s = P.NodeChildren(arrayfun(@(o) isa(o,'matlab.graphics.primitive.world.LineStrip'), P.NodeChildren));
然后可以从s
中确定ColorData
中顶点的新顺序,然后必须将其应用于ColorData
和VertexData
属性以重新排序边缘而不进行任何其他更改:
[~,idx] = sortrows(s.ColorData','desc');
set(s, 'VertexData',s.VertexData(:,idx), 'ColorData',s.ColorData(:,idx));
这可能会被任何进一步的重绘所覆盖,并且没有文档的功能无法保证它的行为 - 但从表面上看它似乎正在寻找你正在寻找的东西。