Are `Children` generally in the reversed order? Matlab - matlab

I have a figure as shown here, with each color indicating the value of a third variable. I attempted to create a colorbar with the corresponding colors and values. For this purpose first I get the Color of the 'Children' of the axes as follows:
curves = get(gca, 'Children');
mycolorset = cat(1, curves(:).Color);
Then I realized that the order of the colors (same as the order of the Children) is reversed compared to the order of plotting. So I had to apply flipud to the colors to make the correct colormap:
set(gcf, 'Colormap', flipud(mycolorset));
Interesting fact is that Plot Browser shows the curves in the correct order.
Now I want to know, is this a universal feature of all Children in Matlab to be reversed? Do you know a case that this becomes useful at all?

The Children of an axes are ordered such that the children near the beginning are displayed on top of children near the end of the list of children (if the SortMethod is set to 'childorder' or if you have just a 2D plot).
If you're dynamically adding multiple 2D plots to an axes, the default behavior of MATLAB is to place new plot objects on top of old plot objects, therefore they need to be appended to the beginning of the Children list.
figure;
hold on
plot1 = plot(1:10, 'LineWidth', 10, 'DisplayName', 'plot1');
plot2 = plot(10:-1:1, 'LineWidth', 10, 'DisplayName', 'plot2');
legend([plot1, plot2])
get(gca, 'Children')
% 2x1 Line array:
%
% Line (plot2)
% Line (plot1)
If you want to alter which plot is displayed on top of which, you can modify the ordering of the Children or you can just use the handy uistack command to do this for you.
set(gca, 'Children', flipud(get(gca, 'Children'))) % Or uistack(plot1, 'top')
get(gca, 'Children')
% 2x1 Line array:
%
% Line (plot1)
% Line (plot2)
This stacking behavior isn't just limited to plot objects in axes. You can alter the Children ordering on most UI elements (including uipanels, figures, etc.) to determine the visual stacking of the elements.

Related

Change existing plot lines according to colormap

I have a plot with a few lines in Matlab and I want to control the line colors post-hoc:
figure; hold on;
for ind=1:4
plot(rand(1,10))
end
I know I can use
set(0,'DefaultAxesColorOrder',summer(4))
before plotting, to change the plot line colors, but (how) can I achieve the same thing after looking at the plot? Possibly try-out a few different colorschemata?
Each plot by default takes its color from the property 'ColorOrder' of their axis, which in turn is taken by default from the 'DefaultAxesColorOrder' of the groot object.
Once the plots have been created, you need to modify their colors individually; changing the above mentioned properties will not affect them:
g = findobj(gca, 'Type', 'line'); % children of current axis that are lines
c = summer(numel(g)); % desired color scheme, with that many colors
for k = 1:numel(g)
set(g(k), 'color', c(k,:));
end

Plot multiple columns with different colors in MATLAB

I have a 372x15 matrix. I'm trying to graph this in such a way that columns 1-14 will be on the x-axis with different colors for each column, whereas the 15th column will be treated as the y-axis. For example, the plot with follow (x1, y), (x2, y) so on so forth, where x1 is all the data points in column 1. This is a simple scatterplot. How can I do this on MATLAB?
A simple way to do that is just use plot(A(:,1:end-1), A(:,end), '.'). Here's an example:
A = [(1:14)-.6*rand(372,14) ((1:372).'+rand(372,1))]; % example A. Uses implicit expansion
plot(A(:,1:end-1), A(:,end), '.') % do the plot
axis tight % optionally make axis limits tight
The above cycles through the 7 predefined colors. If you prefer to customize the colors, set the 'ColorOrder' property of the axes before calling plot, and use hold on to prevent Matlab from resetting it:
clf % clear figure
cmap = autumn(size(A,2)); % example colormap
set(gca, 'ColorOrder', cmap); % set that colormap
hold on % needed so that the colormap is not automatically reset
plot(A(:,1:end-1), A(:,end), '.')
axis tight
You can specify different markers or marker sizes; see plot's documentation.

Multiple axis: using plot vs. line

I have 2 sets of data I want to plot on the same graph.
First an histogram:
hist(data1);
ax1 = gca;
I set the next set of axis, y on the other side
ax2 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','bottom',...
'YAxisLocation','right',...
'Color','none',...
'XColor','k');
If I use line() to plot my data it works:
line(data2a, data2b, 'Color', 'r', 'LineStyle', '-', 'Marker', '.', 'Parent', ax2);
But if I use plot(), the histogram is erased and both axis appear on the left.
plot(ax2, data2a, data2b);
Can somebody figure out why the second axis is not valid for plot()?
You should check out doc hold.
Axes in MATLAB have the 'NextPlot' property, specifying what to do when a new plot-function is issued on this axis.
The default for 'nextplot' is replace, meaning that before anything new is drawn, existing plots are erased.
Using hold(ax, 'on') or set(ax, 'nextplot', 'add') you can specify that new plots are added to the existing ones, instead of replacing them.
The reason that line and plot behave differently is, that high level functions (like plot) respect this axis property, while low-level functions like line, patch and others do not. They are added to axis in any case and do not remove existing children.
EDIT:
Now I'm noticing that ax2 should be empty in your case - maybe just try the above nevertheless ;)

MATLAB - How to zoom subplots together?

I have multiple subplots in one figure. The X axis of each plot is the same variable (time). The Y axis on each plot is different (both in what it represents and the magnitude of the data).
I would like a way to zoom in on the time scale on all plots simultaneously. Ideally by using the rectangle zoom tool on one of the plots, and having the other plots change their X limits accordingly. The Y limits should remained unchanged for all of this. Auto fitting the data to fill the plot in the Y direction is acceptable.
(This question is almost identical to Stack Overflow question one Matplotlib/Pyplot: How to zoom subplots together? (except for MATLAB))
Use the built-in linkaxes function as follows:
linkaxes([hAxes1,hAxes2,hAxes3], 'x');
For more advanced linking (not just the x or y axes), use the built-in linkprop function
Use linkaxes as Yair and Amro already suggested. Following is a quick example for your case
ha(1) = subplot(2,1,1); % get the axes handle when you create the subplot
plot([1:10]); % Plot random stuff here as an example
ha(2) = subplot(2,1,2); % get the axes handle when you create the subplot
plot([1:10]+10); % Plot random stuff here as an example
linkaxes(ha, 'x'); % Link all axes in x
You should be able to zoom in all the subplots simultaneously
If there are many subplots, and collecting their axes handle one by one does not seem a clever way to do the job, you can find all the axes handle in the given figure handle by the following commands
figure_handle = figure;
subplot(2,1,1);
plot([1:10]);
subplot(2,1,2);
plot([1:10]+10);
% find all axes handle of type 'axes' and empty tag
all_ha = findobj( figure_handle, 'type', 'axes', 'tag', '' );
linkaxes( all_ha, 'x' );
The first line finds all the objects under figure_handle of type "axes" and empty tag (''). The condition of the empty tag is to exclude the axe handles of legends, whose tag will be legend.
There might be other axes objects in your figure if it's more than just a simple plot. In such case, you need to add more conditions to identify the axes handles of the plots you are interested in.
To link a pair of figures with linkaxes use:
figure;imagesc(data1);
f1h=findobj(gcf,,’type’,’axes’)
figure;imagesc(data2);
f2h=findobj(gcf,,’type’,’axes’)
linkaxes([f1h,f2h],’xy’)

MATLAB: Assign multiple colors to text in legend

I'm trying to color code text in a legend. (Since I'm trying to sort several plots into different categories, I can't just rely on the line colors in the legend.) I've managed to set the text color for the entire legend, but I can't manage to assign it line by line. Is this possible?
Code so far:
list={'Label 1','Label 2','Label 3'};
leg=legend(list);
set(leg,'Textcolor',[1 0 0])
sets the text color for the entire legend as red. I'd like to be able to make some red, and some black. I tried assigning the color array as an n x 3 matrix, but MATLAB doesn't like that very much. I also poked around the legend properties using get(leg), but I couldn't find anything else that seemed useful. Any suggestions?
While the answers by yuk and gnovice are correct, I would like to point out a little-known and yet fully-documented fact that the legend function returns additional handles that correspond to the legend components. From the documentation of the legend function:
[legend_h, object_h, plot_h, text_strings] = legend(...) returns
legend_h — Handle of the legend axes
object_h — Handles of the line, patch, and text graphics objects used in the legend
plot_h — Handles of the lines and other objects used in the plot
text_strings — Cell array of the text strings used in the legend
These handles enable you to modify the properties of the respective objects.
Here is the code:
legtxt=findobj(leg,'type','text');
set(legtxt(1),'color','k')
Just find out which legends correspond to which index.
To change the legend text colors individually, you have to first get the handles to the text objects, which are children of the legend object. Then you can change their text colors separately. Here's an example of how you can do it:
plot(1:10, rand(1, 10), 'r'); % Plot a random line in red
hold on;
plot(1:10, rand(1, 10), 'b'); % Plot a random line in blue
hLegend = legend('a', 'b'); % Create the legend
hKids = get(hLegend, 'Children'); % Get the legend children
hText = hKids(strcmp(get(hKids, 'Type'), 'text')); % Select the legend children
% of type 'text'
set(hText, {'Color'}, {'b'; 'r'}); % Set the colors
Note that the color order in the last line is blue then red, in reverse order of the way the labels are passed to the legend function. The above will give you the following plot: