Reloading handle objects from .mat files
Mostrar comentarios más antiguos
Why does isequal() return false when the reloaded handle is compared to the original handle, in the code below.
h=plot(1:5);
save tst h
h2=load('tst').h;
isequal(h,h2)
Respuesta aceptada
Más respuestas (1)
f1 = figure(1);
ax1 = axes('Parent', f1);
h1 = plot(ax1, 1:10);
save tst f1
h1.YData(end) = 5
datastruct = load('tst');
f2 = datastruct.f1;
isequal(f1, f2)
f1.Number
f2.Number
double(f1)
double(f2)
f1.Children(1).Children(1).YData
f2.Children(1).Children(1).YData
Now, under your hypothesis, f1 (the live figure handle) should isequal() f2 (the retrieved saved version of the figure handle). But if they are isequal() then how would you account for the fact that the YData for the two needs to be different, since the plot for f1 was modified after it was saved? Should the retrieved copy have been updated to reflect the changes to f1, or should the active f1 have been regressed to reverse the changes so as to match the restored figure handle?
Or is it your position that when we modified the YData underneath the first figure, that the handle f1 should itself have changed?
5 comentarios
Matt J
el 27 de Mayo de 2023
Walter Roberson
el 28 de Mayo de 2023
line() objects contain:
Edge: [1×1 LineStrip]
MarkerHandle: [1×1 Marker]
SelectionHandle: [0×0 GraphicsPlaceholder]
BrushHandles: [0×0 GraphicsPlaceholder]
NodeParent: [1×1 ScissorRectangleClipNode]
NodeChildren: [2×1 Graphics]
SerializableUIContextMenu: [0×0 GraphicsPlaceholder]
ContextMenu: [0×0 GraphicsPlaceholder]
UIContextMenu: [0×0 GraphicsPlaceholder] Annotation: [1×1 matlab.graphics.eventdata.Annotation]
Annotation: [1×1 matlab.graphics.eventdata.Annotation]
DataTipTemplate: [1×1 matlab.graphics.datatip.DataTipTemplate]
so imagine that you save a line handle, and then you change the Marker object associated with the active version of the handle, and then you ask to load the saved handle.
Which of the following is the mechanism you envision:
- when you load() a handle that has been modified since the time it was saved, that the in-memory version should have its properties modified to be the same as what was stored, so in this case the modification of the Marker object should be undone when you load() the version of the handle that was saved before the modification ??
- load()'d handle has a different identity than the still-in-memory handle because load() always generates a new unused ID, so there are no clashes to worry about? (This possibility is inconsistent with your question) ??
- load()'d handle has a different identity than the still-in-memory handle because save stores the original identity but load() checks to see if that identity is already in use and if so generates a new identity ??
- load()'d handle has a different identity than the still-in-memory handle because save stores the original identity together with a property hash, and load() checks to see whether the identity is in use and if so then whether the hash of the in-use version is the same as the hash of the stored version, and if the hashes are the same then load() restores the same identity but if the hashes were different then load generates a new identity ??
- when you modify the properties of the still-in-memory handle after saving it, then the modification process should hunt down all in-memory copies of the handle (including in other workspaces) and modify the identity, and thus the reason that there would not be any clash between the modified in-memory version and the restored version is that the modification of the properties gave a new identification to the still-in-memory object ??
h=plot(1:5);
double(h)
save tst h
h2 = load('tst').h;
double(h2)
Different handles, even without having made any modification. So regardless of what you believe "should" happen, this rules out several of the possibilities of what does happen.
Walter Roberson
el 28 de Mayo de 2023
When handle objects are created, are they created with a UUID / GUID ? https://en.wikipedia.org/wiki/Universally_unique_identifier
Suppose I create a figure and axes and h = plot(), and save("tst1.mat","h"); and loop from iteration = 2 to something big
h.YData = rand(1,1);
save("tst"+iteration+".mat", "h");
but first, before changing YData, every once in a while,
if rand() < 0.01
idx_to_restore = randi(iteration, 1, 1);
h2 = load("tst" + idx_to_restore + "mat", "h").h;
idx_to_restore = randi(iteration, 1, 1);
h3 = load("tst" + idx_to_restore + "mat", "h").h;
end
What is the identity that should be associated with h2 and h3? h still exists but with modified value.
Should h become a different handle (different identity) every time its YData is modified? That would be inconsistent with the idea that once you get a handle that it always refers to the current version of the object. If you pass in h to a function that modifies h.MarkerSize and then ask isequal(evalin('caller','h'), h) then the two must be equal even though you did not modify the caller's version of h explicitly. Because handles are effectively pointers, and the pointer stays the same even when the properties pointed to are modified: this is inherent in what handles are
So the handle (pointer) associated with h is not changing as you modify the properties of h.
When you restore h2, then "should" h2 have the same pointer as h? Even though h2 probably has different properties than h ?
When you restore h3, then "should" h3 have the same pointer as h2? Even though h3 probably has different properties than h2 ?
Under hg1 and still under hg2, there is a mapping between handles and double. Even now, double(h) will produce a double precision number that you can set() the properties of, or handle() to get back a handle object. If a loop similar to the above were left to run long enough, on a large enough file system, eventually the same double precision number would end up getting used again for something that "should" be a different handle. If we load() back something that had the same double precision number as an existing handle, "should" it conflict with the existing handle with that double precision number? But that's easy enough to manufacturer:
fig = figure(1);
fig1 = handle(1);
isequal(fig, fig1)
ans =
logical
1
so all figure(1) have the same double precision number as their handle, namely the double precision number 1.0 . If we save two different figure 1 to different files, and load() both of them back in, then should they conflict with each other since they have the same handle?
Or should handle identity only be preserved for objects that do not "contain" other objects? Which is why I pointed out earlier that line() objects contain a series of other object types: line() objects are containers in the object sense just as much as figures are containers in the object sense.
Or... so this be resolved by having handles be associated with UUID / GUID, so that it is the UUID that is recorded in the save file rather than the double precision handle? So that no matter how many times we mix and match storing and retrieving two copies of the same handle, when we eventually load both of them together, that they will compare equal because it would have matched the (hypothetical) UUID ?
Categorías
Más información sobre Creating, Deleting, and Querying Graphics Objects en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




