How to plot subset of X-axis names on bar plot?

조회 수: 9 (최근 30일)
Andrew Gemer
Andrew Gemer 2022년 1월 11일
댓글: Andrew Gemer 2022년 1월 14일
Hello, I've run up against a problem that I can't seem to solve and need some help. Basically, I pull in 20 beer names (text strings) from an XLS, and want to create a bar plot of the first 10 of them. I can get it to plot the bars (plotData) for a subset, but every time, the bar plot contains all 20 beer names (plotNames), rather than the subset (10). I've even created a new array (plotNamesD), which contains only 10 beer name strings, but when I use 'bar' to plot it all 20 beer name strings are still plotted on the X-axis. Note that the reason that I loop through keywords is that I eventually want to apply this to other categories as well. Here is my example code:
clc
clear all
close all
rawData = {'Beer1','Draft Beer',NaN,NaN,NaN,928;...
'Beer2','Draft Beer',NaN,NaN,NaN,112;...
'Beer3','Draft Beer',NaN,NaN,NaN,55;...
'Beer4','Draft Beer',NaN,NaN,NaN,697;...
'Beer5','Draft Beer',NaN,NaN,NaN,256;...
'Beer6','Draft Beer',NaN,NaN,NaN,8;...
'Beer7','Draft Beer',NaN,NaN,NaN,430;...
'Beer8','Draft Beer',NaN,NaN,NaN,72;...
'Beer9','Draft Beer',NaN,NaN,NaN,76;...
'Beer10','Draft Beer',NaN,NaN,NaN,346;...
'Beer11','Draft Beer',NaN,NaN,NaN,86;...
'Beer12','Draft Beer',NaN,NaN,NaN,345;...
'Beer13','Draft Beer',NaN,NaN,NaN,4;...
'Beer14','Draft Beer',NaN,NaN,NaN,28;...
'Beer15','Draft Beer',NaN,NaN,NaN,98;...
'Beer16','Draft Beer',NaN,NaN,NaN,92;...
'Beer17','Draft Beer',NaN,NaN,NaN,94;...
'Beer18','Draft Beer',NaN,NaN,NaN,154;...
'Beer19','Draft Beer',NaN,NaN,NaN,367;...
'Beer20','Draft Beer',NaN,NaN,NaN,637};
% Determine number of rows
nRows = size( rawData, 1 );
% - Define category keywords
keywords = {'Appetizers',...
'Bottled Beer',...
'Draft Beer',...
'Lunch Specials',...
'Wine'} ;
% - Prealloc cell arrays for storing the output of find in column.
nKeyword = numel( keywords ) ;
keywordPos = cell( nRows, nKeyword ) ;
% - Iterate through elements of keywords and find in all data rows.
for kId = 1 : nKeyword
keywordPos(:,kId) = strfind( rawData(:,2), keywords{kId} ).' ;
end
% - Convert to arrays of logicals flagging "found at least one", which
% translates into "check not empty".
hasKeyword = ~cellfun( @isempty, keywordPos ) ;
numBeers = 10; % Number of top selling beers to plot
for kId = 1 : nKeyword
if strcmp(keywords{kId}, 'Draft Beer')
f=figure('WindowState','maximized');
plotData = cell2mat(rawData(hasKeyword(:,kId)==1,6));
% Sort from highest seller to lowest - may not be necessary
% bar(sort(plotData(:,1),'descend'));
plotNames = categorical(rawData(hasKeyword(:,kId)==1,1));
plotNames = reordercats(plotNames,rawData(hasKeyword(:,kId)==1,1));
% Attempt to reduce the size of the plotNames array to
% address why 'bar' can only plot the full array of names
plotNamesD = plotNames(1:numBeers);
plotDataD = plotData(1:numBeers);
bar(plotNamesD,plotDataD);
% Plot numbers at top of bar
text(1:length(plotData),plotData,num2str(plotData),'vert','bottom','horiz','center');
box off
% Plot categorgy name as the title of the plot
title(keywords(kId));
grid on;
end
end
And here is the current output:
I want to truncate this bar plot after "Beer10", but I'm struggling to do so even though the lengths of both plotDataD and plotNamesD is 10. As a side note, I also want to sort in descending order and make sure the beer names are correct and stay with their counts, but I haven't tackled that yet. Any help you can offer would be greatly appreciated!

채택된 답변

VBBV
VBBV 2022년 1월 12일
편집: VBBV 2022년 1월 12일
plotNamesD = plotNames(1:kId);% use the for loop index
plotDataD = plotData(1:kId);
bar(plotNamesD,plotDataD);
hold on
Use the for loop index if you want to truncate the bar plot.
  댓글 수: 6
VBBV
VBBV 2022년 1월 12일
also change the categorical plotNamesD to double when you are using bar plot
Andrew Gemer
Andrew Gemer 2022년 1월 14일
Ok awesome! So you definitely caught at least one problem with my code (using plotData instead of plotDataD in the text line), so I'm going to mark this questions "solved" so that you get credit for it!
However, the second comment, changing the categorical plotNamesD to double doesn't meet my needs - in practice, there are like 500+ beer names, so I want the actual beer name (for example, the string 'Coors Light') to be displayed rather than just a number as in your example. So if I do not change the names to doubles, I still have the problem where all 20 beer names are plotted, rather than just the 10 I wanted. See below screenshot for an example:

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Line Plots에 대해 자세히 알아보기

제품


릴리스

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by