Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute a function when the colormap changes

I am working on a GUI control MATLAB (2014a) program with a plot window that shows a contour-like plot on top of a pcolor-based plot.

The users found out, that the colormap can be changed by right-clicking the colorbar. This change does however only affect the pcolor plot directly, because of the internals of my contour functions.

I already found out how to get the changed colormap from my axes object and apply it to the contour plot, but I still have to manually redo the plot.

Is there any callback that executes once the colormap of an axes / figure object is changed?

I read about PropertyChangeCallback, but the colormap does not seem to be stored as a property.

like image 855
Tim Avatar asked Nov 09 '22 07:11

Tim


1 Answers

You do not need to resort to undocumented functionalities to intercept a colormap change in Matlab pre-HG2. You can simply attach a listener to the 'PostSet' event of the property 'Colormap'.

As a quick example, if your figure is already there, just type:

lh = addlistener( h.fig , 'Colormap' , 'PostSet' , @(h,e) disp('cmap changed !') )

in the console, and you will get a message every time you change the colormap. Note that the event is triggered whether:

  • you change the colormap entirely to another one (from jet to hsv for example)
  • you change the size of the colormap (the number of division). (ex: colormap(jet(5)))
  • you use the "Interactive colormap shift" gui tool.

Note that the event will not trigger if you use caxis. This command does not change the colormap itself but the way some colors are mapped to it. So if you use this command, your pcolor will be modified (although the colormap won't). The caxis command changes the CLim property of the current axes (not figure!). So if you want to detect that, you have to attach a listener to this property on the correct axis. Something like:

lh = addlistener( gca , 'CLim' , 'PostSet' , @(h,e) disp('clim changed !') )

As a more applied example, here's a little demo which will react every time the colormap is changed. Since I don't know what you planned to do to your contour plot at every change, I just modify a couple of properties just to show that it's doing something. Adjust that to what you need to do.

function h = cmap_change_event_demo

%// SAMPLE DATA. create a sample "pcolor" and "contour" plot on a figure
nContour = 10 ;
[X,Y,Z] = peaks(32);
h.fig = figure ;
h.pcol = pcolor(X,Y,Z) ;
hold on;
[~,h.ct] = contour(X,Y,Z,nContour,'k');
h.cb = colorbar
shading interp
colormap( jet(nContour+1) ) %// assign a colormap with only 10+1 colors

%// add the listener to the "Colormap" property
h.lh = addlistener( h.fig , 'Colormap' , 'PostSet' , @cmap_changed_callback )

%// save the handle structure
guidata( h.fig , h )

function cmap_changed_callback(~,evt)
    %//  disp('cmap changed !')

    hf   = evt.AffectedObject ; %// this is the handle of the figure
    cmap = evt.NewValue ;       %// this is the new colormap. Same result than : cmap = get(hf,'Colormap') ;

    h = guidata( hf ) ;         %// to retrieve your contour handles (and all the other handles)
    nColor = size(cmap,1) ;     %// to know how many colors are in there if you want matching contours

    %// or just do something useless
    set(h.ct , 'LineColor' , rand(1,3) )      %// change line color
    set(h.ct , 'LineWidth' , randi([1 5],1) ) %// change line thickness

cmap_event_demo

like image 51
Hoki Avatar answered Nov 15 '22 09:11

Hoki