How to calculate how many plot tick would exist if the axis completely filled the figure

4 次查看(过去 30 天)
Hi,
Thank you in advance for your help.
I'm creating a plot in MATLAB which is then saved and loaded as a background image in other software. The other software then places overlays on top of the background image to create a user output. This other software needs to scale the overlayes to align with the background image, which creates the fairly unique problem I'm struggling with.
Say I have a plot that goes from 0 to 15 in the X axis and 0 to 7 on the Y axis. I need to calculate, if those axis were extended to the full size of the saved figure, what would the axis limits be?
So far I've written code to get the pixel size of the axis and the number of ticks. Then I calculate the number of ticks per pixel, them multiple that by the number of pixles in the figure. This gets me close but not perfect. I'm a little out. So I expect there is something else in the figure rather than just the axis which is taking up pixels.
For example.
If run spy I get this image:
...which is in a figure that's much larger than the axis. If I were to extend the axis to the edge of the figure, then what would be the min and max of each axis?
Its roughly this: (Which i did in paint)
In heindsite spy is perhaps a bad example image as the Y counts down but hopefully it gets my point across.
Thank you!
  3 个评论
Gregory Smith
Gregory Smith 2021-1-14
Hey,
Here is what I have so far.
Figure 2 above I think shows is best. I did that in MS paint and annotated it. If the axis were extended to the endges of the figure, then what would the axis go up to? In the example above I wrote in on X for example, -70 ish and 155 ish. If you extended the X axis to fill the figure, that would be the min and max X.
I hope this helps.
% Set resolution
rez = 300; %resolution (dpi) of final graphic
figpos=getpixelposition(fighandle);
resolution=get(0,'ScreenPixelsPerInch');
set(fighandle,'paperunits','inches','papersize',figpos(3:4)/resolution,'paperposition',[0 0 figpos(3:4)/resolution]);
% Make the axis as large as possible within the figure
%Set axis to the correct size
ax = gca;
outerpos = ax.OuterPosition;
ti = ax.TightInset;
left = outerpos(1) + ti(1);
bottom = outerpos(2) + ti(2);
ax_width = outerpos(3) - ti(1) - ti(3);
%ax_height = outerpos(4) - ti(2) - ti(4); % the "- ti(4)" is the gap between the top of the axis and the menu bars (top of figure)
ax_height = outerpos(4) - ti(2);
ax.Position = [left bottom ax_width ax_height];
axis equal
% Get the figure and axis size in pixels
%Determine CDTire axis size, slightly larger than the image due to y and x axis labels
FigureXPixels = getpixelposition(fighandle);
FigureXPixels = FigureXPixels(3); %outer figure width in pixels
AxisXPixels = getpixelposition(ax);
AxisXPixels = AxisXPixels(3); %inner axis width in pixels
FigureYPixels = getpixelposition(fighandle);
FigureYPixels = FigureYPixels(4); %outer figure height in pixels
AxisYPixels = getpixelposition(ax);
AxisYPixels = AxisYPixels(4)+9; %inner axis height in pixels
% get the axis size in ticks
AxisPlotXRange = (abs(ax.XLim(1)) + abs(ax.XLim(2))); %Plot range in ticks
%AxisPlotYRange = (abs(ax.YLim(1)) + abs(ax.YLim(2))); %Plot range in ticks
AxisPlotYRange = ax.YLim(2) - ax.YLim(1);
% This should give me the size of the whole figure in ticks, but it doesn quite work
WindowPlotXRange = (AxisPlotXRange/AxisXPixels)*FigureXPixels; %New plot range in ticks (size of whole window in tick markers)
WindowPlotYRange = (AxisPlotYRange/AxisYPixels)*FigureYPixels; %New plot range in ticks
% This is what I'm trying to get to.
% the min and max of X and T axis, if they axis were extended to fill the figure window.
%Calculate CDTire axis entries
CDTire_SetXLimits_1 = ax.XLim(1)-(WindowPlotXRange-AxisPlotXRange); %tick makers if they went to the end of the window, not just the end of the axis
CDTire_SetXLimits_2 = ax.XLim(2);
CDTire_SetYLimits_1 = ax.YLim(1)-(WindowPlotYRange-AxisPlotYRange);
CDTire_SetYLimits_2 = ax.YLim(2);
Adam Danz
Adam Danz 2021-1-15
编辑:Adam Danz 2021-1-18
I still am not certain I understand but I added an answer that addresses my interpretation of your question.

请先登录,再进行评论。

采纳的回答

Adam Danz
Adam Danz 2021-1-15
编辑:Adam Danz 2021-1-15
Given an axis within a figure, compute what the x and y axis limits would be if the axis extended to the edges of the figure.
Demo: See inline comments that explain each step. The variables newXLim and newYLim contain the extended axis limits.
It uses randomly placed axes with randomly set axis limits. After computing the expanded axis limits a second axis is created set to fill the figure and contains the extended axis limits. This axis is used to plot lines that should align with the original axis limits to confirm successful conversion. The axis limits to the exapanded axes are shown in the upper, left corner.
% Create figure with randomly placed axes
% and random data spans (axis limits) to
% test for maximum flexibility
fig = clf();
ax = axes(fig,'Units','Normalize',...
'Position', [rand(1,2)*.4+.05, rand(1,2)*.2+.35], ...
'LineWidth',3);
xlim(ax,sort(rand(1,2)*100))
ylim(ax,sort(rand(1,2)*100))
box(ax,'on')
% Set units to pixels
ax.Units = 'pixels';
fig.Units = 'pixels';
% Get locations and sizes
axPos = ax.InnerPosition; % inner positions!
figPos = fig.Position; % we only need width and height
% Compute margins between fig and ax edges
% in pixels
axMarg = [axPos(1:2),figPos(3:4) - (axPos(1:2)+axPos(3:4))]; %[left, bottom, right, top]
% Now we know how far to extend the axes to each edge
% of the figure in pixel units.
% Convert from pixel units to data units.
xl = xlim(ax);
yl = ylim(ax);
xyFactor(1) = range(xl) / axPos(3);
xyFactor(2) = range(yl) / axPos(4);
xyMargDataUnits = axMarg.*xyFactor([1,2,1,2]);
% Now we know the distance between each axis edge
% and figure edge in data units. We just need to
% extrapolate from the axis limits
newXLim = [xl(1)-xyMargDataUnits(1), xl(2)+xyMargDataUnits(3)];
newYLim = [yl(1)-xyMargDataUnits(2), yl(2)+xyMargDataUnits(4)];
% Set axis units back to normalized so if the figure
% is resized, the results will not change (important!).
ax.Units = 'normalize';
% Now let's test it by adding an underlying axis with these limits
ax2 = axes('Units','Normalize','InnerPosition',[0 0 1 1]);
box(ax2,'on') % added after creating GIF image.
ax2.LineWidth = 1.5; % added after creating GIF image.
uistack(ax2,'bottom')
xlim(ax2, newXLim)
ylim(ax2, newYLim)
% Use reference lines to confirm that the axis limits of
% th original axes align with those values on the expanded axis.
xline(xl(1),'b--', 'LineWidth', 1.5)
xline(xl(2),'b--', 'LineWidth', 1.5)
yline(yl(1),'b--', 'LineWidth',1.5)
yline(yl(2),'b--', 'LineWidth',1.5)
% Show expanded axis limits
text(ax2,min(xlim(ax2)),max(ylim(ax2)),...
sprintf('xlim: [%.1f, %.1f]\nylim: [%.1f, %.1f]', ...
newXLim(1),newXLim(2),newYLim(1),newYLim(2)), ...
'VerticalAlignment','Top','HorizontalAlignment','Left',...
'FontSize', 12, 'FontWeight','bold','fontName','fixedwidth',...
'BackgroundColor', 'w')
The image below shows several iterations of this demo.

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Annotations 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by