Plot elements of specific size
6 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Zohar
el 23 de Oct. de 2021
Comentada: Zohar
el 24 de Oct. de 2021
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:
- Define the size properties wrt the canvas and not the screen.
- 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?
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
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.
Respuesta aceptada
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
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().
Más respuestas (1)
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)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/776603/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/776608/image.png)
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
0 comentarios
Ver también
Categorías
Más información sobre Environment and Settings en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!