Plot elements of specific size

6 ビュー (過去 30 日間)
Zohar
Zohar 2021 年 10 月 23 日
コメント済み: Zohar 2021 年 10 月 24 日
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 件のコメント
Zohar
Zohar 2021 年 10 月 23 日
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 :)

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

採用された回答

Matt J
Matt J 2021 年 10 月 23 日
編集済み: Matt J 2021 年 10 月 23 日
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 件のコメント
Zohar
Zohar 2021 年 10 月 24 日
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).

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

その他の回答 (1 件)

Matt J
Matt J 2021 年 10 月 24 日
編集済み: Matt J 2021 年 10 月 24 日
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

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by