## Interacting with graphs with keypresses

| categories: plotting | View Comments

interactive_graph_keypress

## 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;