Interacting with graphs with keypresses
December 08, 2011 at 02:22 AM | categories: plotting | View Comments
Contents
Interacting with graphs with keypresses
John Kitchin
In Post 1489 we saw how to interact with a contour plot using mouse clicks. That is helpful, but limited to a small number of click types, e.g. left or right clicks, double clicks, etc... And it is not entirely intuitive which one to use if you don't know in advance. Today we examine how to make key presses while the mouse is over the graph do something useful. We will examine an enthalpy-pressure diagram for steam, and setup functions so you can press u, s, p, h, or t to display the relevant thermodynamic property under the mouse cursor.
Watch the video here: http://screencast.com/t/nxAiiBXr
function main
The XSteam module makes it pretty easy to generate figures of the steam tables. Here we make the enthalpy-pressure graph.
clear all; close all P = logspace(-2,3,500); %bar temps = [1 50 100 150 200 300 400 500 600 700 800]; % degC figure; hold all for Ti=temps Hh = @(p) XSteam('h_PT',p,Ti); H = arrayfun(Hh,P); plot(H,P,'k-') % add a text label to each isotherm of the temperature text(H(end),P(end),sprintf(' %d ^{\\circ}C',Ti),'rotation',90); end % add the saturated liquid line hsat_l = arrayfun(@(p) XSteam('hL_p',p),P); plot(hsat_l,P) % add the saturated vapor line hsat_v = arrayfun(@(p) XSteam('hV_p',p),P); plot(hsat_v,P) xlabel('Enthalpy (kJ/kg)') ylabel('Pressure (bar)') set(gca,'YScale','log') % this is the traditional view % adjust axes position so the temperature labels aren't cutoff. set(gca,'Position',[0.13 0.11 0.775 0.7])
Now we add a textbox to the graph where we will eventually print the thermodynamic properties. We also put a tooltip on the box, which will provide some help if you hold your mouse over it long enough.
textbox_handle = uicontrol('Style','text',... 'String','',... % start out empty 'Position', [0 0 200 25],... 'TooltipString','Press u,s,p,h or t to get the thermodynamic property under the mouse cursor. Ctrl-q to close the figure.'); % we will create a simple cursor to show us what point the printed property % corresponds too cursor_handle = plot(0,0,'r+');
Call back functions
we need to define two callback functions that will get called when the mouse moves over the figure, and when a key is pressed.
function mouse_motion(~,~) % since we don't use (gcbo,event) the input arguments, we % replace them by ~ current_point = get(gca,'Currentpoint'); H = current_point(1,1); P = current_point(1,2); if (P > 0.01 && P < 1000) && (H > 0.01 && H < 4500) set(cursor_handle,'XData',H,'YData',P) end end function keypress_callback(gcbo,event) % We get the point under the cursor. H = get(cursor_handle,'XData'); P = get(cursor_handle,'YData'); % solve for T T = fzero(@(T) H - XSteam('h_PT',P,T),[1 800]); % now define a string for each type of key press. str = ''; % default string to display switch event.Key case 'u' % compute internal energy for the P,T under cursor str = sprintf('U = %1.4g kJ/kg', XSteam('u_PT',P,T)); case 's' % compute entropy for the P,T under cursor str = sprintf('S = %1.4g kJ/kg/K',XSteam('s_PT',P,T)); case 'p' str = sprintf('P = %1.4g bar',P); case 'h' str = sprintf('H = %1.4g kJ/kg', H); case 't' str = sprintf('T = %1.4g C', T); case 'uparrow' if strcmp(event.Modifier,'control') set(cursor_handle,'YData', P + 10) else set(cursor_handle,'YData', P + 100) end case 'downarrow' if strcmp(event.Modifier,'control') set(cursor_handle,'YData', P - 10) else set(cursor_handle,'YData', P - 100) end case 'leftarrow' if strcmp(event.Modifier,'control') set(cursor_handle,'XData', H - 10) else set(cursor_handle,'XData', H - 100) end case 'rightarrow' if strcmp(event.Modifier,'control') set(cursor_handle,'XData', H + 10) else set(cursor_handle,'XData', H + 100) end case 'q' % quit. We use a dialog box to make sure we really % want to quit, in case q was accidentally pressed. choice = questdlg('Are you sure you want to quit?','','yes','no','no'); switch choice case 'yes' close return case 'no' str = ''; end otherwise str = ''; end % and put the string in our text box set(textbox_handle, 'String',str,... 'FontWeight','bold','FontSize',12) end
finally, attach the callback functions to the current figure.
set(gcf,'KeyPressFcn',@keypress_callback) set(gcf,'WindowButtonMotionFcn',@mouse_motion)
end % categories: plotting % tags: interactive, thermodynamics % post_id = 1513; %delete this line to force new post; % permaLink = http://matlab.cheme.cmu.edu/2011/12/07/interacting-with-graphs-with-keypresses/;