我已授权

注册

李洋:Matlab数据游标(dualcursor)动态展示

2013-06-06 17:23:08 和讯股票  李洋

  实现的内容是当数据展示量很大的时候,用两个游标,当拖动游标的时候可以动态展示游标所在位置的x,y值,就像某些行情软件,有一个竖线拖动可以展示竖线所在位置的日期时间和开高低收等指标,原本是想自己实现来着,后来在file exchange上找到这个比较符合我的要求的一个函数,就懒得自己弄了。这个函数还是挺NB的,不但可以动态展示游标所在位置的x,y值,而且可以产生两个游标之间的数据为一个新的图像,方便显示数据的局部。

  这个函数的作用还是挺大的,当你图形的数据展示很多,你想了解某个点,某个邻域的值的情况,用这个函数很是方便。

图
图(点击查看动态图)

  测试代码:load handel

  Ns = 2^12;

  Y = fft(y,Ns);

  Y = 2/Ns*abs(Y(1:Ns/2));

  df = Fs/Ns;

  f = (0:1:Ns/2-1)*df;

  %Plot it

  figure;

  plot(f,100*[Y sqrt(Y)])

  title('My cursor example');

  xlabel('Frequency (Hz)');

  ylabel('Amplitude');

  axis([0 1200 0 inf]);

  %Turn on cursors

  dualcursor

  dualcursor.m函数代码,要的拿去:function val = dualcursor(state,deltalabelpos,marker_color,datalabelformatfcnh,axh)

  %dualcursor Add dual vertical cursors to a plot

  %

  %Syntax

  % dualcursor

  % dualcursor('state');

  % dualcursor([X1 X2]);

  % dualcursor('state',deltalabelpos);

  % dualcursor([X1 X2],deltalabelpos);

  % dualcursor('update', ...) %Updates existing cursors when data has changed

  % dualcursor(..., ..., marker_color_spec);

  % dualcursor(..., ..., ..., fcnhandle);

  % dualcursor(..., ..., ..., ..., axh);

  % val = dualcursor %return values of the 2 cursors on the current axis

  % val = dualcursor(h) %return values of the 2 cursors on the axis or line w/handle h

  %

  %Description

  % Easy Mode:

  % dualcursor on %Turns on data cursors

  % dualcursor off %Turns off data cursors

  % dualcursor %Toggles the state of data cursors

  % val = dualcursor %Return the coordinates of the 2 cursors

  % val = [x1 y1 x2 y2]

  %

  % Interaction:

  % Click on the cursors to drag them around.

  % Click on the cursor label to reposition.

  % If multiple lines are plotted, click on a line to make it active.

  % Right click on a cursor to:

  % - Export the selected region to the workspace

  % (exports as a structure named cursors)

  % - Export the selected region to a new figure

  % - Export cursor data to workspace

  % (exports as a variable named cursordata = [x1 y1 x2 y2])

  % - Remove the cursors from the plot

  % Click on the delta calculation labels to reposition them.

  %

  % Advanced Options:

  % 1. Specify initial x-coordinates for the cursors

  % dualcursor([x1 x2]); %Adds cursors at x1, x2

  %

  % 2. Specify the location of the text label for displaying x2-x1, y2-y1 results

  % dualcursor([],deltalabelpos); %Specifies the location to display DeltaX

  % %and DeltaY calculations

  % deltalabelpos = [DeltaX_x, DeltaX_y; DeltaY_x, DeltaY_y] in normalized axis units

  % default = [.65 -.08;.9 -.08] puts them just below the lower right-hand corner.

  % If this is too hard, you can also reposition the labels with your mouse!

  %

  % 3. Specifying the color and marker for the cursors

  % dualcursor([],[],marker_color_spec);

  % %Turns on data cursor, using specified marker and color

  % %marker_color_spec is a one or two element string, specifying color and/or marker

  % %style. >>help plot for valid marker and color specifiers

  % ex 'go' - red circles

  % 's' - squares, with default color (red)

  %

  % 4. Update the existing cursors when the data in the plot has changed.

  % dualcursor('update');

  % This mode is useful when using the cursors on a live data stream.

  %

  % This simply updates the appropriate values to reflect the latest data. Here's

  % how to do this:

  % - When you initialize the graphics before taking data, make your initial call

  % to dualcursor (dualcursor on, for instance)

  % - In the code that updates the graphics display with new data, call

  % dualcursor update

  %

  % 5. Specify custom formatting for the data label showing individual cursor values

  % This is implemented with a function handle (@). You provide a handle to a

  % specifically formatted function:

  % dualcursor(..., ..., ..., fcnhandle)

  % %Specifies the text and formatting for the data label

  % %fcnhandle is a handle to the function that defines the formatting. This function

  % %must have the following argument syntax:

  % function textstring = mytextstring(xv,yv);

  % Input:

  % xv (scalar) The x cursor value

  % yv (scalar) The y cursor value

  % Output:

  % textstring (string) The formatted text string

  % {'string'} Cell array of strings for multi-line display

  %

  % Example

  % Create the following function. save as frequencystring.m

  % function textstring = frequencystring(xv,yv);

  % textstring = {['Amp: ' num2str(yv,'%2g') ' dB']

  % ['f: ' num2str(xv,'%2g') ' Hz'];};

  % %Use this code when you are ready to call dualcursor

  % fcnhandle = @frequencystring; %Create handle to your function

  % dualcursor(..., ..., ..., fcnhandle)

  %

  % 6. Add cursors to a specific axis (not necessarily current axis).

  % dualcursor(..., ..., ..., ..., axh);

  % Adds the cursors to the axis with handle axh

  % This mode is useful when axis handles might be hidden

  %

  %

  % Example

  % %Set up some interesting data

  % load handel

  % Ns = 2^12;

  % Y = fft(y,Ns);

  % Y = 2/Ns*abs(Y(1:Ns/2));

  % df = Fs/Ns;

  % f = (0:1:Ns/2-1)*df;

  % %Plot it

  % figure;

  % plot(f,100*[Y sqrt(Y)])

  % title('My cursor example');

  % xlabel('Frequency (Hz)');

  % ylabel('Amplitude');

  % axis([0 1200 0 inf]);

  %

  % %Turn on cursors

  % dualcursor

  %

  % %Turn off cursors

  % dualcursor off

  %

  % %Place cursors at x=300 and x=400, place DeltaX/DeltaY display in the upper left

  % % hand corner, and use a green square for the cursor.

  % dualcursor([300 400],[.05 1.05; .25 1.05],'gs');

  %

  % %Move the cursors around. Try moving the data label, too

  %

  % %Now, wasn't that fun? Finally, get the current cursor positions

  % val = dualcursor;

  % %val = [x1 y1 x2 y2]

  %

  %

  % NOTE: HandleVisibility of axis must be set to 'on' or 'callback'

  %

  % see also: DATALABEL, LINELABEL

  % This function is provided as an example only. It has not been

  % tested, and therefore, it is not officially supported by The

  % MathWorks, Inc.

  % Written by Scott Hirsch

  % shirsch@mathworks.com

  % Copyright 2002-2009 The MathWorks, Inc.

  % This is a (major) modfication of datalabel, available at MATLAB Central

  %Parse input arguments

  %If output argument, return the cursor values

  %See if the user specified a formatting function for the datalabel

  

  if nargin<4 || isempty(datalabelformatfcnh) %Nope. Use the default one included here.

  datalabelformatfcnh = @local_maketextstring;

  end;

  if nargout

  if nargin==0 %Use current axis

  h = gca;

  else

  h = state;

  if strcmp(get(h,'Type'),'line');

  h = get(h,'Parent');

  end;

  end;

  cursors = findobj(h,'Tag','Cursor');

  if length(cursors)==2 %Should be empty (no cursors), or length=2

  for ii=1:2

  cn = getappdata(cursors(ii),'CursorNumber');

  ind = (cn-1)*2+1:cn*2; %Index into val

  val(ind) = getappdata(cursors(ii),'Coordinates');

  end;

  else

  val = [];

  warning('I could not find any cursors');

  end;

  return

  elseif nargin<5 || isempty(axh) %Did the user specify a handle?

  axh = gca;

  end;

  

  %If no input arguments, switch state (turn off/on)

  if (nargin==0 & nargout==0) | isempty(state) %Switch state. Check current state

  dots = findobj(axh,'Type','line','Tag','Cursor'); %See if there are any cursors

  if isempty(dots) %None found. Turn cursors on

  state = 'on';

  else

  state = 'off';

  end;

  end;

  %Check if the first argument is numeric. The user is specifying

  % the initial x-coordinates of the markers

  if nargin>=1 & isnumeric(state) %First input is x coordinates of markers

  x_init = state(:);

  %error check

  if length(x_init)~=2

  error('First input must be 2 element vector of x coordinates');

  end;

  state = 'on'; %Turn on data cursors.

  else %Default position = 1/3, 2/3 x axis limits

  % xl = xlim; %X Limits. this is the letter L, not the number 1

  if strcmp(get(axh,'Type'),'figure') || strcmp(get(axh,'Type'),'uipanel') || strcmp(get(axh,'Type'),'root'); %user clicked on the axis itself; do nothing

  return

  end;

  

  xl = xlim(axh);

  lim = localObjbounds(axh); % Problem using objbounds with hggroup objects, so I have a simple version of my own

  lim = lim(1:2); %x values only

  xl(isinf(xl)) = lim(isinf(xl));

  width = diff(xl); %Axis width

  x_init = xl(1)+[1/3 2/3]*width;

  end;

  % Get handle to figure just once

  hFig = ancestor(axh,'figure');

  

  switch state

  case 'on'

  %Initialization

  % Set the WindowButtonDownFcn

  % Add the cursors.

  %If there are already some data cursors on this plot, delete them!

  dualcursor('off',[],[],[],axh);

  %Parse user inputs

  %Check for user input of position for delta labels

  if nargin<2 | isempty(deltalabelpos)

  deltalabelpos = [.65 -.08;.9 -.08]; %Use defaults

  %[x1 y1; x2 y2]

  end;

  

  %Marker and color specification

  if nargin >= 3 ,

  %Parse marker string. User might specify color, marker, or both

  colors = 'bgrcmyk';

  markers = '+o*.xsdv^>

  for ii=1:length(marker_color)

  col_ind = strfind(colors,marker_color(ii));

  if ~isempty(col_ind) %It's a color

  color = marker_color(ii);

  else %Try a marker instead

  mark_ind = strfind(markers,marker_color(ii));

  if ~isempty(mark_ind)

  marker = marker_color(ii);

  end;

  end;

  end;

  end;

  %Handle default marker and color

  if ~exist('color','var'), color = 'r'; end; %set default

  if ~exist('marker','var'), marker = '*'; end; %set default

  %Add the cursors.

  %Ideally, the user specified the 2 x coordinates.

  %If not, just put the cursors somewhere nice.

  lineh = local_findlines(axh);

  %Line data

  if isempty(lineh)

  x1 = 0;

  y1 = 0;

  % erasemode = 'normal'; %default

  else

  %if multiple lines, define callback to allow for selection

  set(lineh,'ButtonDownFcn', ...

  'setappdata(get(gco,''Parent''),''SelectedLine'',gco);dualcursor(''selectline'',[],[],[],get(gco,''Parent''))');

  %set erasemode to xor. This speeds things up a ton with large data sets

  % erasemode = get(lineh,'EraseMode');

  % set(lineh,'EraseMode','xor');

  lineh = min(lineh); %Lets just use one line. This was probably added first

  setappdata(axh,'SelectedLine',lineh); %The currently selected line.

  %Why the last line? Because it is the first one added

  xl = get(lineh,'XData');

  yl = get(lineh,'YData');

  end;

  %Find nearest value on the line

  [xv1,yv1] = local_nearest(x_init(1),xl,yl);

  [xv2,yv2] = local_nearest(x_init(2),xl,yl);

  %Build the string for the data label

  textstring1 = feval(datalabelformatfcnh,xv1,yv1);

  textstring2 = feval(datalabelformatfcnh,xv2,yv2);

  %Add the data label

  th1 = text(xv1,yv1,textstring1,'FontSize',8,'Tag','CursorText','Parent',axh);

  th2 = text(xv2,yv2,textstring2,'FontSize',8,'Tag','CursorText','Parent',axh);

  %For R13 or higher (MATLAB 6.5), use a background color on the text string

  v=ver('MATLAB');

  v=str2num(v.Version(1:3));

  if v>=6.5

  set(th1,'BackgroundColor','y');

  set(th2,'BackgroundColor','y');

  end;

  yl = ylim(axh);

  lim = localObjbounds(axh);

  lim = lim(3:4); %y values only

  yl(isinf(yl)) = lim(isinf(yl));

  %Add the cursors

  ph1 = line([xv1 xv1 xv1],[yl(1) yv1 yl(2)], ...

  'Color',color, ...

  'Marker',marker, ...

  'Tag','Cursor', ...

  'UserData',[lineh th1], ...

  'LineStyle','-', ...

  'Parent',axh);

  ph2 = line([xv2 xv2 xv2],[yl(1) yv2 yl(2)], ...

  'Color',color, ...

  'Marker',marker, ...

  'Tag','Cursor', ...

  'UserData',[lineh th2], ...

  'LineStyle','-', ...

  'Parent',axh);

  %Add context menu to the cursors

  % cmenu = uicontextmenu('Parent',get(axh,'Parent'));

  cmenu = uicontextmenu('Parent',hFig);

  set([ph1 ph2],'UIContextMenu',cmenu);

  % Define the context menu items

  item1 = uimenu(cmenu, 'Label', 'Export region to workspace', ...

  'Callback', 'dualcursor(''exportws'',[],[],[],get(gco,''Parent''))');

  item2 = uimenu(cmenu, 'Label', 'Export region to new figure', ...

  'Callback', 'dualcursor(''exportfig'',[],[],[],get(gco,''Parent''))');

  item3 = uimenu(cmenu, 'Label', 'Export cursor data to workspace', ...

  'Callback', 'dualcursor(''exportcursor'',[],[],[],get(gco,''Parent''));');

  item4 = uimenu(cmenu, 'Label', 'Turn cursors off', ...

  'Callback', 'dualcursor(''off'',[],[],[],get(gco,''Parent''))', ...

  'Separator','on');

  

  setappdata(th1,'Coordinates',[xv1 yv1]);

  setappdata(ph1,'Coordinates',[xv1 yv1]);

  setappdata(th2,'Coordinates',[xv2 yv2]);

  setappdata(ph2,'Coordinates',[xv2 yv2]);

  setappdata(th1,'CursorNumber',1);

  setappdata(ph1,'CursorNumber',1);

  setappdata(th2,'CursorNumber',2);

  setappdata(ph2,'CursorNumber',2);

  setappdata(th1,'FormatFcnH',datalabelformatfcnh);

  setappdata(th2,'FormatFcnH',datalabelformatfcnh);

  setappdata(th1,'Offset',[0 0]); %Offset for the text label from the data value

  setappdata(th2,'Offset',[0 0]); %Offset for the text label from the data value

  % mh = uicontextmenu('Tag','DeleteObject', ...

  % 'Callback','ud = get(gco,''UserData'');delete([gco ud(2)]);');

  % set([th1 th2],'UIContextMenu',mh);

  set(th1,'UserData',[lineh ph1]); %Store handle to line

  set(th2,'UserData',[lineh ph2]); %Store handle to line

  

  %Calculate Difference

  dx = xv2 - xv1;

  dy = yv2 - yv1;

  %Add display for cursor deltas

  deltah(1) = text(deltalabelpos(1,1),deltalabelpos(1,2),['({x}_{2}-{x}_{1}) = ' num2str(dx,'%+.2f')], ...

  'Units','Normalized', ...

  'HorizontalAlignment','left', ...

  'Tag','CursorDeltaText', ...

  'FontSize',8, ...

  'Interpreter','tex', ...

  'Parent',axh); %dx

  deltah(2) = text(deltalabelpos(2,1),deltalabelpos(2,2),['{y}_{2}-{y}_{1} = ' num2str(dy,'%+.2f')], ...

  'Units','Normalized', ...

  'HorizontalAlignment','left', ...

  'Tag','CursorDeltaText', ...

  'FontSize',8, ...

  'Interpreter','tex', ...

  'Parent',axh); %dy

  %Set Application Data.

  setappdata(axh,'Delta_Handle',deltah);

  setappdata(axh,'Marker',marker);

  setappdata(axh,'Color',color);

  set(hFig,'WindowButtonDownFcn','dualcursor(''down'',[],[],[],get(gco,''Parent''))')

  set(hFig,'DoubleBuffer','on'); %eliminate flicker

  case 'down' % Execute the WindowButtonDownFcn

  htype = get(gco,'Type');

  tag = get(gco,'Tag');

  marker = getappdata(axh,'Marker');

  color = getappdata(axh,'Color');

  %If it's a movable object (Cursor, CursorText label, or Cursor Delta Text

  %label), make it movable.

  if strcmp(tag,'CursorText') | strcmp(tag,'Cursor') | strcmp(tag,'CursorDeltaText')

  set(gco,'EraseMode','xor')

  set(gcf,'WindowButtonMotionFcn','dualcursor(''move'',[],[],[],get(gco,''Parent''))', ...

  'WindowButtonUpFcn','dualcursor(''up'',[],[],[],get(gco,''Parent''))');

  end;

  if strcmp(tag,'Cursor') %If clicked on a cursor

  %Label the cursor we are moving. Add a text label just above the plot

  CursorNumber = getappdata(gco,'CursorNumber');

  cnstr = num2str(CursorNumber);

  xl = xlim(axh);

  lim = localObjbounds(axh);

  lim = lim(1:2); %x values only

  xl(isinf(xl)) = lim(isinf(xl));

  % yl = lim(3:4);

  

  xv = getappdata(gco,'Coordinates');

  xv = xv(1);

  %Convert to normalized

  xn = (xv - xl(1))/(xl(2) - xl(1));

  yn = 1.05;

  CNh = text(xn,yn,cnstr, ...

  'Units','Normalized', ...

  'HorizontalAlignment','center', ...

  'Parent',axh); %dx

  %For R13 or higher (MATLAB 6.5), use a background color on the text string

  v=ver('MATLAB');

  v=str2num(v.Version);

  if v>=6.5

  set(CNh,'BackgroundColor','y');

  end;

  setappdata(gco,'CNh',CNh);

  end

  case 'move' % Execute the WindowButtonMotionFcn

  htype = get(gco,'Type');

  tag = get(gco,'Tag');

  if ~isempty(gco)

  %Special (simple) case - just repositioning the delta labels

  if strcmp(tag,'CursorDeltaText') %The cursor delta labels.

  cp = get(axh,'CurrentPoint');

  pt = cp(1,[1 2]);

  %Put into normalized units

  ax = axis;

  lim = localObjbounds(axh);

  ax(isinf(ax)) = lim(isinf(ax));

  pt(1) = (pt(1) - ax(1))/(ax(2)-ax(1));

  pt(2) = (pt(2) - ax(3))/(ax(4)-ax(3));

  set(gco,'Position', [pt 0])

  drawnow

  return

  end;

  %Is this the cursor or the text

  if strcmp(tag,'CursorText') %The text

  th = gco;

  handles = get(gco,'UserData');

  ph = handles(2);

  slide = 0; %Don't slide along line; just reposition text

  else %The marker

  ph = gco;

  handles = get(gco,'UserData');

  th = handles(2);

  slide = 1; %Slide along line to next data point

  end;

  offset = getappdata(th,'Offset'); %Offset from data value

  cp = get(axh,'CurrentPoint');

  pt = cp(1,[1 2]);

  %Constrain to Line

  lh = getappdata(get(th,'Parent'),'SelectedLine');

  % lh = handles(1); %Line

  x = cp(1,1); %first xy values

  y = cp(1,2); %first xy values

  if slide %Move to new data value

  xl = get(lh,'XData');

  yl = get(lh,'YData');

  

  %Get nearest value

  [xv,yv]=local_nearest(x,xl,yl);

  

  %If we are moving a cursor, must move the cursor number label, too

  if strcmp(tag,'Cursor')

  %Move the Cursor Number label, too

  CNh = getappdata(gco,'CNh');

  pos = get(CNh,'Position');

  xlm = xlim(axh);

  lim = localObjbounds(axh);

  lim = lim(1:2); %x values only

  xlm(isinf(xlm)) = lim(isinf(xlm));

  xn = (xv - xlm(1))/(xlm(2)-xlm(1));

  set(CNh,'Position',[xn pos(2:3)])

  end;

  yl = ylim(axh);

  lim = localObjbounds(get(lh,'Parent'));

  lim = lim(3:4); %y values only

  yl(isinf(yl)) = lim(isinf(yl));

  datalabelformatfcnh = getappdata(th,'FormatFcnH');

  textstring = feval(datalabelformatfcnh,xv,yv);

  set(th,'Position', [xv yv 0] + [offset 0],'String',textstring)

  set(ph,'XData',[xv xv xv],'YData',[yl(1) yv yl(2)]);

  setappdata(ph,'Coordinates',[xv yv]);

  setappdata(th,'Coordinates',[xv yv]);

  %Update delta calculation

  cursors = findobj(axh,'Tag','Cursor');

  cn1 = getappdata(cursors(1),'CursorNumber');

  if cn1==2 %Switch order

  temp = cursors(1);

  cursors(1) = cursors(2);

  cursors(2) = temp;

  end;

  

  deltah = getappdata(axh,'Delta_Handle'); %Handle to cursors

  %Positions of two dualcursors

  xy1 = getappdata(cursors(1),'Coordinates');

  xy2 = getappdata(cursors(2),'Coordinates');

  

  %Calculate Difference

  dx = xy2(1) - xy1(1);

  dy = xy2(2) - xy1(2);

  set(deltah(1),'String',['({x}_{2}-{x}_{1}) = ' num2str(dx,'%+.2f')]);

  set(deltah(2),'String',['({y}_{2}-{y}_{1}) = ' num2str(dy,'%+.2f')]);

  else %Just move text around.

  set(th,'Position', [x y 0])

  end;

  drawnow

  end;

  case 'up' % Execute the WindowButtonUpFcn

  htype = get(gco,'Type');

  tag = get(gco,'Tag');

  if strcmp(tag,'CursorText') | strcmp(tag,'Cursor') | strcmp(tag,'CursorDeltaText');

  set(gco,'EraseMode','Normal')

  set(gcf,'WindowButtonMotionFcn','')

  if strcmp(tag,'CursorText') %If the text label, record it's relative position

  cp = get(axh,'CurrentPoint');

  pt = cp(1,[1 2]);

  coords = getappdata(gco,'Coordinates');

  offset(1) = pt(1) - coords(1);

  offset = pt - coords;

  setappdata(gco,'Offset',offset);

  end;

  

  if strcmp(tag,'Cursor') %Delete the temporary cursor number label

  CNh = getappdata(gco,'CNh');

  delete(CNh);

  end;

  end;

  case 'selectline' % User selected a new line to be active

  %Make the selected line bold

  lh = getappdata(axh,'SelectedLine');

  lw = get(lh,'LineWidth');

  set(lh,'LineWidth',5*lw);

  drawnow

  %Update the cursors

  dualcursor('update',deltalabelpos,marker_color,datalabelformatfcnh,axh);

  %Put the line back the way you found it!

  set(lh,'LineWidth',lw);

  case 'update' %Update the cursor value

  %Find the position of the existing cursors

  cursors = findobj(axh,'Tag','Cursor');

  cd1 = getappdata(cursors(1),'Coordinates');

  cd2 = getappdata(cursors(2),'Coordinates');

  cn1 = getappdata(cursors(1),'CursorNumber');

  cn2 = getappdata(cursors(2),'CursorNumber');

  clear x

  x(cn1) = cd1(1); %x value of cursor number cn1

  x(cn2) = cd2(1); %x value of cursor number cn2

  lh = getappdata(axh,'SelectedLine');

  handles = get(cursors(cn1),'UserData');

  th1 = handles(2);

  handles = get(cursors(cn2),'UserData');

  th2 = handles(2);

  offset1 = getappdata(th1,'Offset'); %Offset from data value

  offset2 = getappdata(th2,'Offset'); %Offset from data value

  

  ylm = ylim(axh);

  lim = localObjbounds(get(lh,'Parent'));

  lim = lim(3:4); %y values only

  ylm(isinf(ylm)) = lim(isinf(ylm));

  

  xl = get(lh,'XData');

  yl = get(lh,'YData');

  

  %Get nearest value

  [xv1,yv1]=local_nearest(x(1),xl,yl);

  [xv2,yv2]=local_nearest(x(2),xl,yl);

  datalabelformatfcnh = getappdata(th1,'FormatFcnH');

  % textstring1 = {['x=' num2str(xv1)];['y=' num2str(yv1)]};

  % textstring2 = {['x=' num2str(xv2)];['y=' num2str(yv2)]};

  textstring1 = feval(datalabelformatfcnh,xv1,yv1);

  textstring2 = feval(datalabelformatfcnh,xv2,yv2);

  set(th1,'Position', [xv1 yv1 0] + [offset1 0],'String',textstring1)

  set(th2,'Position', [xv2 yv2 0] + [offset2 0],'String',textstring2)

  set(cursors(cn1),'XData',[xv1 xv1 xv1],'YData',[ylm(1) yv1 ylm(2)]);

  set(cursors(cn2),'XData',[xv2 xv2 xv2],'YData',[ylm(1) yv2 ylm(2)]);

  %Update delta calculation

  deltah = getappdata(axh,'Delta_Handle'); %Handle to delta calculation

  % %Positions of two dualcursors

  xy1 = getappdata(cursors(1),'Coordinates');

  xy2 = getappdata(cursors(2),'Coordinates');

  %Calculate Difference

  dx = xv2 - xv1;

  dy = yv2 - yv1;

  set(deltah(1),'String',['{x}_{2}-{x}_{1} ' num2str(dx,'%+.2f')]);

  set(deltah(2),'String',['{y}_{2}-{y}_{1} ' num2str(dy,'%+.2f')]);

  case 'exportws' %Export selected region to workspace

  [xd,yd] = local_extractregion(axh);

  %If there's only one line, don't make the user hassle with cell arrays

  if length(xd)==1

  xd = xd{1};

  yd = yd{1};

  end;

  cursors.xd = xd;

  cursors.yd = yd;

  assignin('base','cursors',cursors);

  disp('Variable: cursors created in workspace');

  case 'exportfig' %Export selected region to a new figure

  % [xd,yd,proplist,props] = local_extractregion;

  [xd,yd,hgS] = local_extractregion(axh);

  %Create new plot

  fh = figure;

  ax = axes;

  struct2handle(hgS,ax);

  %Get labels from axes, too

  %Clunky, but it seems to work

  %First, create empty title, xlabel, ylabel

  newhandles(1) = title('');

  newhandles(2) = xlabel('');

  newhandles(3) = ylabel('');

  %Get strings from original plot

  props = {'Title','xlabel','ylabel'};

  vals = get(axh,props);

  handles = [vals{:}];

  str = get(handles,'String');

  %Set the new strings to match

  set(newhandles,{'String'},str)

  case 'exportcursor'

  % Get cursor coordinates

  cursordata = dualcursor(axh);

  % Push the data into the base workspace.

  assignin('base','cursordata',cursordata);

  disp('Variable: cursordata created in workspace');

  case 'off' % Unset the WindowButton...Fcns

  % set(get(axh,'Parent'),'WindowButtonDownFcn','','WindowButtonUpFcn','')

  set(hFig,'WindowButtonDownFcn','','WindowButtonUpFcn','')

  h1 = findobj(axh,'Tag','CursorText'); %All text

  h2 = findobj(axh,'Tag','Cursor'); %The cursors

  h3 = findobj(axh,'Tag','CursorDeltaText'); %The cursors

  lineh = local_findlines(axh);

  set(lineh,'ButtonDownFcn','');

  % erasemode = getappdata(axh,'OriginalEraseMode');

  % if isempty(erasemode), erasemode = 'normal'; end; %handles first time

  % set(local_findlines(axh),'EraseMode',erasemode);

  delete([h1;h2;h3]);

  end %switch/case on action

  end

  % function hFig = figHandle(axh)

  % % Get the handle to the parent figure

  % hFig = ancestor(axh,'figure');

  % end

  function [xv,yv]=local_nearest(x,xl,yl)

  %Inputs:

  % x Selected x value

  % xl Line Data (x)

  %Find nearest value of [xl] to (x)

  %Special Case: Line has a single non-singleton value

  if sum(isfinite(xl))==1

  fin = find(isfinite(xl));

  xv = xl(fin);

  yv = yl(fin);

  else

  %Normalize axes

  xlmin = min(xl);

  xlmax = max(xl);

  xln = (xl - xlmin)./(xlmax - xlmin);

  xn = (x - xlmin)./(xlmax - xlmin);

  

  %Find nearest x value only.

  c = abs(xln - xn);

  [junk,ind] = min(c);

  %Nearest value on the line

  xv = xl(ind);

  yv = yl(ind);

  end;

  end

  function textstring = local_maketextstring(xv,yv)

  textstring = {['x = ' num2str(xv,'%2g')];

  ['y = ' num2str(yv,'%2.2g')]};

  end

  function [xd,yd,hgS] = local_extractregion(axh)

  val = dualcursor(axh);

  %Find all lines

  lineh = local_findlines(axh);

  Nl = length(lineh);

  %Get all line properties, so we can reproduce the appearance

  hgS = handle2struct(lineh); %Get properties

  xd = get(lineh,'XData');

  yd = get(lineh,'YData');

  %Figure out the index into these lines that val corresponds to

  x1ind = zeros(Nl,1);

  x2ind = zeros(Nl,1);

  %Special handling for single line case

  if Nl==1

  xd= {xd};

  yd = {yd};

  end;

  for ii = 1:Nl

  x1ind(ii) = max(find(xd{ii}<=val(1)));

  x2ind(ii) = max(find(xd{ii}<=val(3)));

  %Keep data from this region only

  xd{ii} = xd{ii}(x1ind(ii):x2ind(ii));

  yd{ii} = yd{ii}(x1ind(ii):x2ind(ii));

  %Update handle structure, to make plotting really easy

  hgS(ii).properties.XData = xd{ii};

  hgS(ii).properties.YData = yd{ii};

  end;

  end

  function lineh = local_findlines(axh);

  lineh = findobj(axh,'Type','line'); %Find a line to add cursor to

  dots = findobj(axh,'Type','line','Tag','Cursor'); %Ignore existing cursors

  lineh = setdiff(lineh,dots);

  %Ignore lines with only one or two values - these are probably annotations of some

  %sort

  xdtemp = get(lineh,'XData');

  linehtemp = lineh;

  lineh=[];

  if ~iscell(xdtemp) %If there's only one line, force data into a cell array

  xdtemp = {xdtemp};

  end;

  for ii=1:length(xdtemp);

  if length(xdtemp{ii})>2

  lineh = [lineh; linehtemp(ii)];

  end;

  end;

  end

  function lim = localObjbounds(axh);

  % Get x limits of all data in axes axh

  kids = get(axh,'Children');

  xmin = Inf; xmax = -Inf;

  ymin = Inf; ymax = -Inf;

  for ii=1:length(kids)

  try % Pass through if can't get data. hopefully we hit at least one

  xd = get(kids(ii),'XData');

  xmin = min([xmin min(xd(:))]);

  xmax = max([xmax max(xd(:))]);

  yd = get(kids(ii),'YData');

  ymin = min([ymin min(yd(:))]);

  ymax = max([ymax max(yd(:))]);

  end

  end

  % Nuclear option, in case things went really bad

  xmin(xmin==Inf) = 0; xmax(xmax==-Inf) = 1;

  ymin(ymin==Inf) = 0; ymax(ymax==-Inf) = 1;

  lim = [xmin xmax ymin ymax];

  end(李洋 安期货

(责任编辑:金明正 HF023)
看全文
写评论已有条评论跟帖用户自律公约
提 交还可输入500

最新评论

查看剩下100条评论

热门新闻排行榜

和讯热销金融证券产品

【免责声明】本文仅代表作者本人观点,与和讯网无关。和讯网站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。