Question

I'm plotting a figure that is a grid of colors/shades, based on the values from a 4x5 matrix.

The x-axis and y-axis tick labels are set using text from a cell array.

The y-axis tick labels exist at 2 levels,

% y ticks, 2 levels
ylabelnames = {'team1','set1';'team1','set2';'team2','set1';'team2','set2'}; 

I'd like the y-axis tick labels to either

1) span 2 lines, so that they match the 2 lines of text being overlaid in the squares of the plot, i.e. 'team#' on the first line and 'set#' on the second line of each row of the imagesc grid, or

2) rotate the label 'team1' to span across the first 2 rows and rotate label 'team2' to span across the last 2 rows, to not repeat the use of 'team1' 'team2' in the labeling.

My entire code:

%% Plot
Matrix = rand(4,5);
Matrix2 = rand(4,5);
% y ticks, 2 levels
ylabelnames = {'team1','set1';'team1','set2';'team2','set1';'team2','set2'}; 
xlabelnames = {'group1','group2','group3','group4','group5'};

sigfig = 2;
spacer = '\n';
% Font sizes
plotFontSize = 8;    labelFontSize = 8;    plotWidth = 500;    plotLength = 300;

imagesc(abs(Matrix))
colormap('gray')
colormap(flipud(colormap))
caxis([0 2])

for rows = 1:size(Matrix,1)
    for columns = 1:size(Matrix,2)
        if abs(Matrix2(rows,columns))<= 0.5 % Show 2nd values less than 0.5
            num = Matrix2(rows,columns);
            num = vpa(num,sigfig);
            num = ['= ' char(num)];
            rval = sprintf('%0.2g', Matrix(rows,columns));
            message = sprintf([ 'val= ' rval spacer 'val2' num '' ]);
            text(columns,rows, message,'HorizontalAlignment','center',...
                'FontSize',plotFontSize,'FontName','Times New Roman'); 
        end
    end
end
% Put on tick labels
set(gca,'Ticklength', [0 0],'YTick',1:size(Matrix),'XTick',1:length(xlabelnames),...
    'YTickLabel',ylabelnames,'XTickLabel',xlabelnames,...
    'FontSize',labelFontSize,'FontName','Times New Roman')

If you run this, you'll see that only the first column of the y-labels are used, even though there's plenty of space to fit 2 rows of text per imagesc row.

I did think of a terrible hack way, which is to use

ylabel('team1                                         team2')

with the huge spaces between labels to spread them out evenly between the y rows, but that's not convenient if I were to increase the size of my matrix, so I'd prefer not doing it that way.

Is there any way to achieve the multi-leveled y tick labeling that I require?

Thanks!

Was it helpful?

Solution

In your example I'd use the text function. For example you can just add:

text(-0.05,1.5,'team1','HorizontalAlignment','center','Rotation',90 );
text(-0.05,3.5,'team2','HorizontalAlignment','center','Rotation',90 );

and see the outcome. The trick is to understand that each "pixel" (or imagesc cell element) is also a unit of the function's 'text' x and y inputs (and also of the ticks if you don't have different scaling), so to go between the first and second blocks use y=1.5 or y=3.5 etc... to go outside the image on the left use a negative x value (x=-0.05) etc. Read more on text properties here...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top