How to set a scale in a figure (similiar to Google Maps)

4 visualizzazioni (ultimi 30 giorni)
Hi all,
I have the following set of data, time versus Intensity. When I plot them want to draw a scale that changes accordingly with the zoom. I want to start with a default scale of 10 second. At the moment I zoom-in the figure, I want the scale to be shorter (something like Google Maps), for example, from 10 seconds to 1 second, and 0.05 second. Also, I want the scale be fixed to the figure. Therefore, I can pan the data and match the scale to the spikes you see in the figure. I have been using a line to check the baseline drift. The line is fixed to the figure, so I can pan the data and match the line to the beggining of the spike. I want to do the same with the scale (again, something similar to Google Mpas scale).
  1 Commento
Jose Rego Terol
Jose Rego Terol il 16 Feb 2020
I cannot set this scalebar in my code
f1=figure(1);
set(f1,'units','normalized','position',[0 0 1 1],'NumberTitle','on','ToolBar', 'None');
f1.WindowState = 'maximized';
hold on;box on; grid on;
plot(x,y,'b');%axis tight;
ylabel('Amplitud (pA)');
xlabel({'Time (s)'; ['foot-Spike:' num2str(fs) ' Flicker:' num2str(fl)...
' Kiss and Run:' num2str(KnR) ' Null:' num2str(null)]})
axis([x(1) x(length(x)) min(abs(y)) max(y)]); % Update plot
title(['Select two points around a ROI Event(s) so far: ' num2str(mNum)]);
ylim([-100 200]);

Accedi per commentare.

Risposta accettata

Joseph Cheng
Joseph Cheng il 16 Feb 2020
Modificato: Joseph Cheng il 16 Feb 2020
I don't understand what you're doing with that line to check baseline. I'll continue to read that however here is a quick scale bar that i'll let you adjust to stay locked to one of your scale bar sizes. This should get you going and you can adjust the scale plot color, shape etc, to get it how you'd like to see it. Especially adjusting the position within the frame
function Matlabanswer()
%gen dummy data
t=0:.001:10;
intensity = rand(size(t)).^2.*rand(size(t)).^10+rand(size(t)).^100;
hfig = figure(1);clf
hax(1) = axes(hfig);
plot(hax(1),t,intensity),xlabel('time'),ylabel('instensity');
ylim([0 20])
hax(2) = axes(hfig); %create the floating box where the scaler bar will be located
scalePos = [hax(1).Position(1)...
hax(1).Position(2)+hax(1).Position(4)-.1...
.1*hax(1).Position(3)...
.1*hax(1).Position(4)]; %designate upper left corner
%and scale secondary axes to be
%1/10 the size
hax(2).Position = scalePos; %scale the 2nd axes to the first.
plot(hax(2),t,zeros(size(t))) %plot data
xlim(hax(2),hax(1).XLim) %plot line the same length as data but in the 1/10 axes
set(hax(2),'XColor', 'none','YColor','none','color','none') %make scale axes invisible
%here is the section for annotation of what the scale line is
hanno = annotation('textbox', scalePos-[0 .05 0 0], 'String', ...
['scale ' num2str(.1*(diff(hax(1).XLim))) 'x']);
hanno.LineStyle='none';
%initiate the function for what happens when zooming
hzoom = zoom(hfig);
set(hzoom,'ActionPostCallback',{@myzoomfunction,hax,hanno});
function myzoomfunction(obj,event,AX,AnnoText)
xlim(AX(2),AX(1).XLim); %update the scale axes to match up with zoomed data
AnnoText.String=['scale ' num2str(.1*(diff(AX(1).XLim))) 'x']; %update the scale annotation
  4 Commenti
Joseph Cheng
Joseph Cheng il 18 Feb 2020
Modificato: Joseph Cheng il 18 Feb 2020
How about this. sorry i was busy with my day job.
I simplified it instead of using an additional axis plotted into the window you can use annotations and know how it scales with the plot.
This will lock it to the center of the screen. if you don't want the text to be in that location. Just move the arrow annotation text into a new annotation text box in the location where you want it to be. As these annotation is locked to the figure it will not change when panned around. I only did the X axis however if you read up on the annotation() function you can just as easily make it for a Y scale bar too
function Matlabanswer()
%gen dummy data
t=0:.001:100;
intensity = rand(size(t)).^2.*rand(size(t)).^10+rand(size(t)).^100;
hfig = figure(1);clf
hax = axes(hfig);
plot(hax,t,intensity),xlabel('time'),ylabel('instensity');
grid minor
%here is the section for annotation of what the scale line is
initScaleLengthsec = 10;%in seconds
initScaleLengthNorm = initScaleLengthsec/diff(hax.XLim); % ratio of the scale length
%against the span of the plot limits as we'll be dealing with normalized
% % to the figure window
%generate the X and Y locations here. since these are in normalized space of the figure
%example here is scalePosX start and stop of the arrow is half the plot window size
% and half the plot window size + the ratio of the window size.
%this is then offset by Position(1) since the position(1) is the lower left corner of the
%plot in relation to the window.
%read up on the position attribute since this is the best i can describe right now.
%position attribute [lowerleftX lowerleftY width height];
scalePosX = [hax(1).Position(3)*1/2,...
hax(1).Position(3)*1/2+initScaleLengthNorm*hax(1).Position(3)]+...
hax(1).Position(1);
%set Y position of the arrow as half way up the height (position(4)) and offset by
%position of the plot axes.
scalePosY = [hax(1).Position(2)+hax(1).Position(4)/2,...
hax(1).Position(2)+hax(1).Position(4)/2];
%generate text arrow.
hanno = annotation('textarrow',scalePosX,scalePosY, 'String', ...
[num2str(initScaleLengthsec) 'seconds']);
%initiate the function for what happens when zooming
hzoom = zoom(hfig);
set(hzoom,'ActionPostCallback',{@myzoomfunction,hax,hanno});
%edit these callbacks should be in there as you can zoom with scroll mouse
%and double click which will reset the view but not trigger the update in scale
hfig.WindowButtonUpFcn={@myzoomfunction,hax,hanno};
hfig.WindowScrollWheelFcn={@myzoomfunction,hax,hanno};
function myzoomfunction(obj,event,AX,AnnoText)
%find the span of the plot
plotSpan = diff(AX.XLim);
%my attempt to set the limits of when to update annotation.
switch true
case plotSpan>50
span=10;
case plotSpan<=50 && plotSpan>25
span=5;
case plotSpan<=25 && plotSpan>10
span=2;
case plotSpan<=10 && plotSpan>2
span=.5;
case plotSpan<=2 && plotSpan>.1
span=0.05;
otherwise
span=0.01;
end
%again find the new ratio of width of plot to desired scale span
ScaleLengthNorm = span/diff(AX.XLim);
%generate again how long the arrow is
scalePosX = [AX(1).Position(3)*1/2,...
AX(1).Position(3)*1/2+ScaleLengthNorm*AX(1).Position(3)]+...
AX(1).Position(1);
scalePosY = [AX(1).Position(2)+AX(1).Position(4)/2,...
AX(1).Position(2)+AX(1).Position(4)/2];
%update the annotation's X start stop
AnnoText.X=scalePosX;
%update the annotation's Y start stop
AnnoText.Y=scalePosY;
%update the text to new span.
AnnoText.String=[num2str(span) 'seconds'];
Jose Rego Terol
Jose Rego Terol il 8 Mar 2020
I am so sorry Joseph. I could not respond until now.
Your code is working good. Thi is what I wanted to have. Thanks a lot.

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Graphics Object Properties in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by