Fixed node locations using graphplot() with Markov chains

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);

 Accepted Answer

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 Comments

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
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
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.
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');
@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)
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);
@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
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.

Sign in to comment.

More Answers (0)

Products

Release

R2021b

Community Treasure Hunt

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

Start Hunting!