Plot elements of specific size

I'm plotting a polygon made of edges and vertices. I'd like to plot these elements at a specific size or proportion: whether the polygon has 10 or 1000 vertices, I'd like the elements to be drawn at the same size. When zooming in and out of the vector image, element size would remain static. For example, define a canvas of 100inx100in and draw lines .1in thick (and save to a pdf).
Currently, it seems impossible since, e.g., the LineWidth and MarkerSize are relative to the screen instead of the canvas. This means that when you zoom into the figure, the elements keep their size wrt screen. One option is to scale their size according to the zoom level. However, then the large polygon wouldn't necessarily fit the screen.
There are two ways that I see to resolve this, both seem impossible:
  1. Define the size properties wrt the canvas and not the screen.
  2. Go to the proper zoom level, and draw all elements even if they aren't in the figure clip region (save to a pdf).
Questions on the subject asked about specific elements such as lines or markers. The suggested solutions were to draw with alternative functions such as patch() and rectangle().
In that case, I'll forsake matlab's clanky drawing mechanism altogether, export the data, and draw in svg. But it would be a shame since matlab has powerful tools such as different marker shapes or a force graph.
Am I missing something fundamental or is this the worst design I've seen lately?
Edit by @Rik:
Since stackoverflow uses CC-BY-SA 4.0 and Answers uses CC-BY-SA 3.0, I took the liberty of copying the actual content of the question from the originally posted link.
Original question:
See

7 comentarios

Rik
Rik el 23 de Oct. de 2021
It sounds like you want the result from functions like patch, but want to use line objects to achieve that. There is probably a way to get that to work, but I question the underlying assumption.
You could probably use a listener to increase the MarkerSize etc as a response to zooming in or out.
Zohar
Zohar el 23 de Oct. de 2021
Editada: Zohar el 23 de Oct. de 2021
Then, I would need to ad hoc address and tweak each element size.
First, I don't care about interactive zooming. I'd like to save a pdf.
Then, even if I increase or change the marker size, it is still limited by the screen resolution. That is, the minimum marker size is bounded by a screen pixel. The 1000 polygon can't fit the screen.
Rik
Rik el 23 de Oct. de 2021
So the rescaling on zoom should happen in the pdf?
It still sounds as if you want line art to behave like patches. That sounds like an XY problem to me. Can you confirm that is what you want? Or am I not understanding you correctly?
Zohar
Zohar el 23 de Oct. de 2021
Editada: Zohar el 23 de Oct. de 2021
I'm not fully clear on your definition, but I would say yes.
A pdf is a pdf: a static image, which you can't control (ignoring the elaborate features). Same as a rastarized image such as a png. Everyone is familiar with the behavior of a common viewer of these formats. Everything is written on a canvas, and the viewer is just a tool to explor the canvas. Not unlike a camera viewing a 3D scene. When you dolly or zoom on objects, they become bigger. When I design a 3D scene, I put objects inside the scene. Matlab, for some reason, draws on the camera lens instead of the convas. Then, when you walk, everything looks the same. Also, you don't have a scene or a world. The camear lens, or the screen in our case, is all you have to populate.
I can't imagine anyone sees these things differently: give me one example of a 2D or 3D app, file format, real life, or whatever that is designed differently. A very poor design on matlab's part. You simply can't control your drawing (what you see is definitely not what you want), or otherwise it's extremely limited.
Walter Roberson
Walter Roberson el 23 de Oct. de 2021
If you look around a bit you can find some functions for creating UDF, which is interactive PDF.
Walter Roberson
Walter Roberson el 23 de Oct. de 2021
Drawing of lines and of the dot marker (specifically) are "primitives" handled by OpenGL. MATLAB did not invent this behaviour.
Zohar
Zohar el 23 de Oct. de 2021
True. And in opengl the line thickness is limited, and it's a whole can of worms. Not something I'd take an example from :)

Iniciar sesión para comentar.

 Respuesta aceptada

Matt J
Matt J el 23 de Oct. de 2021
Editada: Matt J el 23 de Oct. de 2021
First, I don't care about interactive zooming. I'd like to save a pdf.
If the zooming is happening only after the pdf conversion, I don't see why you can't just set the LineWidth and MarkerSize to your preference when the whole drawing is in view, and then convert.
If it's a problem of calculating the conversion factor from data units to points (the units that LineWidth and MarkerSize are measured in, 1 point = 1/72 inch), that can be done as follows:
set(gcf,'Units','points'); %change this back later, if needed
DU=diff(xlim); %width of figure in data units
P=hfig.Position(3); %width of figure in points
conversionFactor=P/DU; %conversion factor, data units to points

7 comentarios

Zohar
Zohar el 23 de Oct. de 2021
"One option is to scale their size according to the zoom level. However, then the large polygon wouldn't necessarily fit the screen."
Meaning, if I have a large drawing and I need to zoom in to the right scale, then not everything would fit in the screen--specifically, the figure window. For this to be applicable, I need the second way (2) that I referred to. Matlab saves to a pdf only what you see on the screen, right?
Matt J
Matt J el 23 de Oct. de 2021
Editada: Matt J el 24 de Oct. de 2021
if I have a large drawing and I need to zoom in to the right scale, then not everything would fit in the screen--specifically, the figure window
Again, you sometimes speak as if you intend to be zooming in Matlab and elsewhere say that you only plan to be zooming a pdf print of the figure. Which is it?
Matlab saves to a pdf only what you see on the screen, right?
Yes, but you would print only after zooming out so that the full figure is in view. You would also set the MarkerSize and LineWidth when the full figure is in view. I don't see how the selection of the MarkerSize and LineWidth requires any zooming. Aren't you pre-selecting them in proportion to the dimensions of your polygon?
Is the issue that you want to be able to zoom the Matlab figure to verify the proportions of the LineWidths and MarkerSizes? If so, it is not an ad hoc matter to rescale the Markers to keep them in the same proportion. The code I proposed above systematically calculates the proportionality factor that you need given the current axes limits. You could put it in a function and re-execute it every time you zoom in and zoom out. As Rik pointed out, this could be further automated with listeners or, if you have R2021a, with a LimitsChangedFcn:
Zohar
Zohar el 24 de Oct. de 2021
One of us is missing something.
For simplicity, forget about zooming in matlab, I'm not iterested in that at all, and I don't need to check anything. I'm working with a pdf instead.
When I render the figure, I'm using the default zoom, where the whole polygon is on screen. Now, it's a big polygon with a lot of tiny details which can't be captured using the screen pixel resolution: either nothing would be drawn, or elements would be scaled (out of proportion) to be the size of at least one pixel (the latter is matlab's behavior).
A pdf, unlike the screen, isn't rasterized, it's vectorized. Thus, it has infinite resolution, and it has no issue with any detail size. Therefore, I would like to render everything in a selected paper resolution (DPI)--not limiting myself to the screen resolution.
To do that, according to your method, I'll need to scale down the markers and edges of fine details below matlab's threshold (1 pixel).
Matt J
Matt J el 24 de Oct. de 2021
Editada: Matt J el 24 de Oct. de 2021
Now, it's a big polygon with a lot of tiny details which can't be captured using the screen pixel resolution: either nothing would be drawn, or elements would be scaled (out of proportion) to be the size of at least one pixel (the latter is matlab's behavior).
That may be true of how Matlab renders line objects on the screen, but I think internally, they are vectorized and, when exporting to PDF, are also sent in vectorized format by default. As a simple test, I generated a plot with MarkerSize=0.1. I can't see the marker in the Matlab figure no matter how much I zoom, but when I export the same figure to PDF, I can zoom down by a factor 6400 and see a very sharp, well-defined circular marker.
Further evidence of this is in the documentation for the new exportgraphics() command, which has specific options to let you export to PDF in vectorized format.
Zohar
Zohar el 24 de Oct. de 2021
Editada: Zohar el 24 de Oct. de 2021
I also think that internally they use vectorized format. I tried to play with hgexport(), which has specific parameters for font and line only--and not for the marker (that's what I meant by I don't want ad hoc solution for each specific element type.)
I've stumbled across exportgraphics(), but I haven't tried it (I have matlab 2019b--but I'll try to upgrade if you confirm). Are you saying that this new function allows me to render off-screen and save in any resolution?
(By the way, it's not so hard to devise a specific example. Say, the screen is 1000-pixel high. Draw a straight vertical polyline of 10,000 vertices, where the radius of each vertex marker is tenth of a segment edge. You won't be able to view it on screen but a pdf could accommodate it. But sounded like you got the idea and tested it with a .1 marker).
Matt J
Matt J el 24 de Oct. de 2021
Are you saying that this new function allows me to draw in any resolution, and even though I won't be able to render it to a figure, I'll be able to save it to an offline pdf?
I think you should try it. I'm not sure you need to upgrade to a Matlab version which has exportgraphics(). I just used saveas().
Zohar
Zohar el 24 de Oct. de 2021
Damn, you are right!
Full details:
One issue is multi-line text. The only way to change the line spacing is breaking the text into single lines:
But it won't work with the post scale since need to account for a new row spacing. One solution is to first render the image, work out the scaling, then draw the image with that scaling (instead of post scaling after the image is drawn).

Iniciar sesión para comentar.

Más respuestas (1)

Matt J
Matt J el 24 de Oct. de 2021
Editada: Matt J el 24 de Oct. de 2021
You could probably use a listener to increase the MarkerSize etc as a response to zooming in or out.
The code below is an implementation of @Rik's suggestion. All line objects in the specified axis will have their MarkerSize and LineWidth properties auto-zoomed in proportion to changes in the axis x-limits.
plot(exp(1:3),'-o');
lockSizes(gca)
function updateSize(ax)
if ~nargin
ax=gca;
end
h=findobj(ax,'Type','line','-or','Type','functionline');
DU=diff(xlim);
factor=h(1).UserData.DU./DU;
for i=1:numel(h)
h(i).MarkerSize=h(i).MarkerSize*factor;
h(i).LineWidth=h(i).LineWidth*factor;
h(i).UserData.refSize=h(i).MarkerSize;
h(i).UserData.refWidth=h(i).LineWidth;
h(i).UserData.DU=DU;
end
end
function lockSizes(ax)
if ~nargin
ax=gca;
end
h=findobj(ax,'Type','line','-or','Type','functionline');
DU=diff(xlim);
for i=1:numel(h)
h(i).UserData.refSize=h(i).MarkerSize;
h(i).UserData.refWidth=h(i).LineWidth;
h(i).UserData.DU=DU;
end
addlistener(ax.XRuler,'MarkedClean',@(~,~) updateSize(ax));
end

Categorías

Más información sobre Graphics Performance en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 23 de Oct. de 2021

Comentada:

el 24 de Oct. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by