Hi,
I have developed a few lines of code to generate markov chains from a transition vector ('stagesVec'). The code works well and I now wish to compare multiple transition vectors. If I run the code a second time with a second transition vector I get a new Markov chain with the new infromation.
My problem is this, the two Markov chains have the same nodes, however the nodes move (plotting location) between graphs, this makes a visual inspection very difficult. I would like for the nodes to remain in the same place, but edges (the connecting lines between the nodes) to be removed as required by the probability matrix. I will include a couple of images below to hopefully make this easier to understand! I have had a look at both doc graphplot and figure -> edit but cannot see anything obvious.
Thanks for the help,
Christopher
tm = full(sparse(stagesVec(1:end-1),stagesVec(2:end),1));
stateNames = ["N1" "N2" "N3" "R" "U" "W" ];
mc = dtmc(tm,"StateNames",stateNames);
figure()
graphplot(mc);

 採用された回答

Steven Lord
Steven Lord 2022 年 2 月 18 日

1 投票

Store the handle of the GraphPlot in a variable, h1 in the code below.
adjacency1 = sprand(6, 6, 0.2);
D1 = digraph(adjacency1);
h1 = plot(D1);
When you plot the second graph or digraph, specify the XData and YData name-value pair arguments using the XData and YData properties of the GraphPlot created from the first graph or digraph.
adjacency2 = sprand(6, 6, 0.2);
D2 = digraph(adjacency2); % Different digraph
h2 = plot(D2, 'XData', h1.XData, 'YData', h1.YData);
To show that the second digraph, if left to its own devices, would plot the nodes in different locations:
h3 = plot(D2);

8 件のコメント

Christopher McCausland
Christopher McCausland 2022 年 2 月 21 日
Hi Steven,
Sorry for the slow reply on this, its been a busy few days!
I wanted to say thank you for a great indepth answer, I hadn't realised that the graphplot X and Y handles were specified as such, this is really handy to know!
I have tried to implement this;
nodePlace = graphplot(mc); % Created the first graph and store it in nodePlace
graphplot(mc,'XData', nodePlace.XData, 'YData', nodePlace.YData); % Use the .XData and .YData stored handles
The problem being that graphplot() doesn't accept 'XData', 'YData' as an input. I suspect this is why you swapped to just plot(), hopwever plot() doesn't accept a 1x1 dtmc object (markov chain 'mc') being passed to it. Am I missing soemthing obvious?
Christopher
Christopher McCausland
Christopher McCausland 2022 年 2 月 21 日
Hi Steven,
Never mind I have discovered my error, you (very cleverly) use the digraph() command inside the plot() command, for anyone else, it should look like this:
nodePlace = graphplot(mc);
D2 = digraph(mc.P,mc.StateNames); % Different digraph
h2 = plot(D2, 'XData', nodePlace.XData, 'YData', nodePlace.YData);
I will probably generate two vectors at the start for the X and Y data but this now makes much more sense in terms of the the calls are handled. Thank you so much for your help!
Christopher
Zeeshan Mumtaz
Zeeshan Mumtaz 2023 年 5 月 2 日
編集済み: Zeeshan Mumtaz 2023 年 5 月 2 日
Hi Christopher, I am having similar kind of issue, but I am unable to fix the node to left of the graphplot so that I can show a smooth state transition from state E0 to E3. The sample code is written down:
clear all
clc
A=[0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03]
mc=dtmc(A)
mc.StateNames=["E0" "E1" "E2" "E3"]
nodePlace = graphplot(mc);
D2 = digraph(mc.P,mc.StateNames); % Different digraph
h2 = plot(D2, 'XData', nodePlace.XData, 'YData', nodePlace.YData);
I want my nodes to be aligned from left to right in progressive order of E0 to E3.
Steven Lord
Steven Lord 2023 年 5 月 2 日
Is this close to what you want? This uses plot to plot the digraph then layout to force it into a 'layered' layout heading from left to right with specified source and sink nodes.
A=[0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03];
mc=dtmc(A);
mc.StateNames=["E0" "E1" "E2" "E3"];
nodePlace = graphplot(mc);
D2 = digraph(mc.P,mc.StateNames); % Different digraph
h = plot(D2);
layout(h, 'layered', 'Direction', 'right', 'Sources', 'E0', 'Sinks', 'E3')
Alternately you can pass the options that layout accepts into plot directly after specifying a layout.
figure
plot(D2, 'Layout', 'layered', ...
'Direction', 'right', ...
'Sources', 'E0', ...
'Sinks', 'E3');
Zeeshan Mumtaz
Zeeshan Mumtaz 2023 年 5 月 2 日
@Steven Lord Thank you very much for your prompt response.
It is quite closer to what I need. I needed that all states from E0 till E3 are aligned in a straight line. Furthermore, the addition of 'layout' command restricts 'LabelEdges' option in conventional graphplot. I have tried to use this command after layout, but does not work at all:
labeledge(h,1:numedges(D2),A)
Steven Lord
Steven Lord 2023 年 5 月 2 日
A=[0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03];
mc=dtmc(A);
mc.StateNames=["E0" "E1" "E2" "E3"];
nodePlace = graphplot(mc);
D2 = digraph(mc.P,mc.StateNames); % Different digraph
h = plot(D2);
layout(h, 'layered', 'Direction', 'right', 'Sources', 'E0', 'Sinks', 'E3');
You can manually adjust the coordinates after the automatic layout function has done its work. This makes the self loops look a little odd, but I'm assuming your actual data may not have so many self loops and edges.
h.YData(2) = h.YData(1);
As for labeling, rather than using the values from A I'd use the values from the Weight variable in the Edges table of the digraph.
labeledge(h,1:numedges(D2),string(D2.Edges.Weight))
Or just use the EdgeLabelMode property to automatically add labels to the edges.
figure
h = plot(D2, 'Layout', 'layered', ...
'Direction', 'right', ...
'Sources', 'E0', ...
'Sinks', 'E3', ...
'EdgeLabelMode', 'auto');
h.YData(2) = h.YData(1);
Zeeshan Mumtaz
Zeeshan Mumtaz 2023 年 5 月 2 日
@Steven Lord Thanks alot. It worked well for me. I have initiated a loop so that all successive nodes align themselves with the previous one.
for i=1:n-1
h.YData(i+1) = h.YData(i);
end
Steven Lord
Steven Lord 2023 年 5 月 2 日
You could use scalar expansion
A=[0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03;0.5,0.4,0.07,0.03];
mc=dtmc(A);
mc.StateNames=["E0" "E1" "E2" "E3"];
nodePlace = graphplot(mc);
D2 = digraph(mc.P,mc.StateNames); % Different digraph
h = plot(D2);
layout(h, 'layered', 'Direction', 'right', 'Sources', 'E0', 'Sinks', 'E3');
h.YData(1:3) = h.YData(2); % Leaving E3 in place so you can see that E0 & E2 moved
You could use : instead of 1:3 if you want to move all the nodes to the same Y coordinates as E1.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File Exchange で Graph and Network Algorithms についてさらに検索

製品

リリース

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by