Full screen figure with xticklabels multiline problem
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Hi,
Short decription of what I need:
- full screean figure of some bars
- xticklabels multiline
What is wrong?
- the text of xtickslabels is not fully displaying (down part is cut, not depends on the xtickangle)
- no space between the text of xticklabels and the axis
figure('units','normalized','outerposition',[0 0 1 1]);
set(gcf,'Visible', 'off');
bar(1,CO2_o(1),'FaceColor','#572280');
hold on
bar(2,CO2_o(2),'FaceColor','#953FBA')
hold on
bar(3,CO2_o(3),'FaceColor','#A279CB');
hold on
bar(4,CO2_o(4),'FaceColor','#D7B3FA')
hold on
bar(5,CO2_o(5),'FaceColor','#DA5900')
hold on
bar(6,CO2_o(6),'FaceColor','#FF7C01');
hold on
bar(7,CO2_o(7),'FaceColor','#FFAB02')
hold on
bar(8,CO2_o(9),'FaceColor','#EDD263')
hold on
bar(9,CO2_o(9),'FaceColor','#AB0909')
hold on
bar(10,CO2_o(10),'FaceColor','#C04655');
hold on
bar(11,CO2_o(11),'FaceColor','#F17A89')
hold on
bar(12,CO2_o(12),'FaceColor','#F6AFAF');
hold on
bar(13,CO2_o(13),'FaceColor','#2865CA');
hold on
bar(14,CO2_o(14),'FaceColor','#B1CCF9')
hold off
title('EMISJA CO_{2} - JAZDA OSZCZĘDNA','fontSize',18)
ylabel(['$[\frac{kg}{1000 \hspace{1mm}paskm}]$'], 'Interpreter', 'latex','fontweight','bold','fontSize',14)
h=[];
ax=gca;
ax.XTickLabel = '';
myLabels={'Alstom EMU250 ED250', 'Alstom EMU250 ED250',...
'Alstom EMU250 ED250', 'Alstom EMU250 ED250',...
'Pesa Elf', 'Pesa Elf',...
'Pesa Elf', 'Pesa Elf',...
'ADtranz 113E EU11', 'ADtranz 113E EU11',...
'ADtranz 113E EU11', 'ADtranz 113E EU11',...
'Pafawag 104E EP09', 'Pafawag 104E EP09';
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', 'Opole-Koniecpol';
'','REKU','','REKU',...
'','REKU','','REKU',...
'','REKU','','REKU',...
'',''};
for i = 1:length(myLabels)
h(i)= text(sprintf('%s\n%s\n%s', myLabels{:,i}), ...
'horizontalalignment', 'right', 'verticalalignment', 'middle');
set(h,'Rotation',60,'fontsize',10);
end
2 comentarios
Paul
el 29 de Sept. de 2024
Instead of using multiple text boxes, it might be worthwhile exploring using the actual XTickLabels to (hopefully) let Matlab do the heavy lifting on the placement,etc. See this link for a discussion that may be helpful (as long as your tick labels won't get messes up by the tex interpreter).
Also, if the only reason you're creating 14 different bar objects is to control the color of each, it might be tidier to create a single bar object and then use FaceColor and CData properties to control the color of each bar in the plot.
dpb
el 29 de Sept. de 2024
"... it might be tidier to create a single bar object and then use FaceColor and CData properties to control the color of each bar in the plot."
Indeed. While I hate writing LaTeX; it's the correct solution as you note and as @Shivam Gothi showed in his Answer, but I'll note that mine does reduce the clutter quite a bit in using the single call to bar and setting the colors in the CData() array by individual bar as illustrated in one of the examples.
I'll in that regards, it's another apparent wart in bar() that you can't set 'FaceColor' except globally and it doesn't appear that it will accept anything except RGB triplets for CData(). And, the hex2rgb function was not supplied until R2024a so with a version prior to that one will have to decode the hex strings with your own code to be able to change CData.
All in all, bar() still is terribly difficult to use with many of these idiosyncracies and hard to adjust properties inherent in the original design that was flawed in some fundamental concepts...
Respuestas (2)
Shivam Gothi
el 29 de Sept. de 2024
Based on my understanding, it seems you're attempting to systematically label the bars on the bar graph, but you're encountering some challenges with their alignment and appearance.
I have made some modifications in the code and tried to address both the issues faced by you. I am attaching it below for your reference.
Note : As the values of the vector "CO2_o" are unknown, I have taken any random values to demonstrate the working.
fig=figure('units','normalized','outerposition',[0 0 1 1]);
bar(1,1,'FaceColor','#572280');
hold on
hold on
bar(2,2,'FaceColor','#953FBA')
hold on
bar(3,3,'FaceColor','#A279CB');
hold on
bar(4,4,'FaceColor','#D7B3FA')
hold on
bar(5,6,'FaceColor','#DA5900')
hold on
bar(6,8,'FaceColor','#FF7C01');
hold on
bar(7,6,'FaceColor','#FFAB02')
hold on
bar(8,5,'FaceColor','#EDD263')
hold on
bar(9,4,'FaceColor','#AB0909')
hold on
bar(10,3,'FaceColor','#C04655');
hold on
bar(11,9,'FaceColor','#F17A89')
hold on
bar(12,12,'FaceColor','#F6AFAF');
hold on
bar(13,13,'FaceColor','#2865CA');
hold on
bar(14,14,'FaceColor','#B1CCF9');
hold off
title('EMISJA CO_{2} - JAZDA OSZCZĘDNA','fontSize',18)
ylabel(['$[\frac{kg}{1000 \hspace{1mm}paskm}]$'], 'Interpreter', 'latex','fontweight','bold','fontSize',14)
%h=[];
ax=gca;
ax.XTickLabel = '';
myLabels={'Alstom EMU250 ED250', 'Alstom EMU250 ED250',...
'Alstom EMU250 ED250', 'Alstom EMU250 ED250',...
'Pesa Elf', 'Pesa Elf',...
'Pesa Elf', 'Pesa Elf',...
'ADtranz 113E EU11', 'ADtranz 113E EU11',...
'ADtranz 113E EU11', 'ADtranz 113E EU11',...
'Pafawag 104E EP09', 'Pafawag 104E EP09';
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', ' Koniecpol-Opole', 'Opole-Koniecpol' ,'Opole-Koniecpol',...
'Koniecpol-Opole', 'Opole-Koniecpol';
'','REKU','','REKU',...
'','REKU','','REKU',...
'','REKU','','REKU',...
'',''};
set(ax, 'XTick', [1,2,3,4,5,6,7,8,9,10,11,12,13,14]);
iTick = get(ax, 'xtick');
length(iTick)
for iXTick = 1:length(iTick)
XTickString{iXTick} = '$$\begin{array}{c}'+string(myLabels{1,iXTick})+ '\\'+string(myLabels{2,iXTick})+'\\'+string(myLabels{3,iXTick})+'\end{array}$$';
end
set(ax,'TickLabelInterpreter','latex');
ax.XTickLabel=XTickString;
xtickangle(ax,60);
ax.FontSize=24;
NOTE : If you run this code in MATLAB editor and find that the font of the labels are too big, then change the last line of code as shown below
ax.FontSize=10;
Below given is the screenshot of the bar-graph generated by running the above code in MATLAB editor ( by using : ax.FontSize=10; )
I hope this meets your expectations !
0 comentarios
dpb
el 29 de Sept. de 2024
Editada: dpb
el 29 de Sept. de 2024
labels=string([ ...
[repmat({'Alstom EMU250 ED250'},1,4), repmat({'Pesa Elf'},1,4), repmat({'ADtranz 113E EU11'},1,4), repmat({'Pafawag 104E EP09'},1,2)]; ...
[repmat([repmat({'Koniecpol-Opole'},1,2), repmat({'Opole-Koniecpol'},1,2)],1,3) repmat({'Koniecpol-Opole'},1,2)]; ...
[repmat({'','REKU'},1,6) {'',''}];]);
fmt1='$$\\begin{array}{c}'; fmt2='%s\\\\'; fmt3='%s\\end{array}$$';
fmt=[fmt1 repmat(fmt2,1,2) fmt3]; % build the formatting string for tick labels
xtklabels=compose([fmt1 repmat(fmt2,1,2) fmt3],labels.'); % and the multistring label string array
colors={'#572280','#953FBA','#A279CB', '#D7B3FA','#DA5900','#FF7C01', ...
'#FFAB02','#EDD263','#AB0909', '#C04655','#F17A89','#F6AFAF', ...
'#2865CA','#B1CCF9'};
CO2=randi([15 27],14,1); % some dummy data
hB=bar(CO2); % the chart; all data in one
hB.FaceColor='flat'; % to use the CData() colors array
hB.CData=hex2rgb(colors); % set custom colors in rgb equivalents (R2024a needed)
hAx=gca;
title('EMISJA CO_{2} - JAZDA OSZCZĘDNA','fontSize',18)
ylabel(['$[\frac{kg}{1000 \hspace{1mm}paskm}]$'], 'Interpreter', 'latex','fontweight','bold','fontSize',14)
%%% FIRST PASS KEEPING TEXT() BUT MAKING ROOM -- REPLACED WITH BUILTIN
%%% TICKLABELS WITH @SG's LEAD ON LaTeX SYNTAX...dpb
% pos=hAx.Position % illustrative of position manipulation to provide room for x tick labels...
% top=pos(2)+pos(4) % see what the top position is
% heightFactor=0.25; % how much to reduce height by
% height=pos(4); % save initial height as room for figure title
% pos(4)=height*(1-heightFactor); % reduce height by factor
% pos(2)=top-pos(4); % set bottom to keep top in same place
% hAx.Position=pos; % set the new positions
% hAx.Position % just show what they are now...
% xticklabels([]) % don't show x tick labels
% xtk=xticks; % but need positions for text()
% xlim(xlim+0.5*[1 -1]) % reduce x axis whitespace at ends
% for i = 1:length(myLabels) % write the labels..
% cats{i}=sprintf('%s\n%s\n%s', myLabels{:,i});
% hT(i)= text(xtk(i),-1,cats{:,i}, ...
% 'horizontalalignment', 'right', 'verticalalignment', 'middle', ...
% 'Rotation',60,'fontsize',8);
% end
hAx.XAxis.FontSize=8; % smaller font for tick labels
hAx.TickLabelInterpreter='latex'; % interpreter TeX by default
hAx.XTickLabelRotation=60; % orientation angle
xticklabels(xtklabels) % and writee the labels
xlim(xlim+0.5*[1 -1]) % reduce x axis whitespace at ends
pos=hAx.Position; pos(1)=0.75*pos(1); pos(3)=1.15*pos(3); hAx.Position=pos; % make wider for more room
The problem is axis boundaries do not automagically resize to account for text added outside the axis limits. You placed the middle line of the RH end of the text at the boundary, but when you rotated the mulitline labels, that rotates the bounding rectangle containing the text and leaves the top corner above the origin as you noted. And, there simply is not sufficient room to put the long text labels in the default space left for tick labels unless you make the font size very small. I set the text y position is at -1 in the above; remember those positions are in data units; that's enough to clear the axis for most although some are still pretty close owing to variations in last characters in top line and font....adjust to suit if do keep using text() but I'd recommend---
ADDENDUM
My initial attempt commented out in the above shrinks the size of the bar axis height to provide room, but that is not the elegant solution; @Shivam Gothi had the ambition to write the LaTeX encoding to use it with which MATLAB will then automagically resize the chart size to make room for the tick label content. I simply took his lead and also vectorized it using some of the newer features with compose; writing the format strings in pieces is one trick to make the complicated keeping track easier to deal with; even then, it took me a number of tries to get it completely correct to handle the missing elements correctly; why TMW couldn't have kept the Fortran FORMAT syntax is a real bother...
The above is basically your original code just made a little more "in the MATLAB style" using the vectorized features to
2 comentarios
Paul
el 29 de Sept. de 2024
Is the latex formatting overkill here? Is it better than ordinary tex formating that just need the "\newline" in the label strings?
labels=string([ ...
[repmat({'Alstom EMU250 ED250'},1,4), repmat({'Pesa Elf'},1,4), repmat({'ADtranz 113E EU11'},1,4), repmat({'Pafawag 104E EP09'},1,2)]; ...
[repmat([repmat({'Koniecpol-Opole'},1,2), repmat({'Opole-Koniecpol'},1,2)],1,3) repmat({'Koniecpol-Opole'},1,2)]; ...
[repmat({'','REKU'},1,6) {'',''}];]);
%fmt1='$$\\begin{array}{c}'; fmt2='%s\\\\'; fmt3='%s\\end{array}$$';
%fmt=[fmt1 repmat(fmt2,1,2) fmt3]; % build the formatting string for tick labels
%xtklabels=compose([fmt1 repmat(fmt2,1,2) fmt3],labels.') % and the multistring label string array
xtklabels = "$$\begin{array}{c}" + join(labels.',"\\") + "\end{array}$$"
colors={'#572280','#953FBA','#A279CB', '#D7B3FA','#DA5900','#FF7C01', ...
'#FFAB02','#EDD263','#AB0909', '#C04655','#F17A89','#F6AFAF', ...
'#2865CA','#B1CCF9'};
CO2=randi([15 27],14,1); % some dummy data
hB=bar(CO2); % the chart; all data in one
hB.FaceColor='flat'; % to use the CData() colors array
hB.CData=hex2rgb(colors); % set custom colors in rgb equivalents (R2024a needed)
hAx=gca;
title('EMISJA CO_{2} - JAZDA OSZCZĘDNA','fontSize',18)
ylabel(['$[\frac{kg}{1000 \hspace{1mm}paskm}]$'], 'Interpreter', 'latex','fontweight','bold','fontSize',14)
hAx.XAxis.FontSize=8; % smaller font for tick labels
hAx.TickLabelInterpreter='latex'; % interpreter TeX by default
hAx.XTickLabelRotation=60; % orientation angle
xticklabels(xtklabels) % and writee the labels
xlim(xlim+0.5*[1 -1]) % reduce x axis whitespace at ends
pos=hAx.Position; pos(1)=0.75*pos(1); pos(3)=1.15*pos(3); hAx.Position=pos; % make wider for more room
dpb
el 29 de Sept. de 2024
In the eye of the beholder, methinks. I just used the three pieces while working through because I don't know LaTeX syntax well enough to know a prior what it needed and I could test the pieces that way. I then left that way instead of joining into the one because felt it a worthwhile pedagogical exercise to illustrate that one doesn't need to try to create complicated patterns in one go--nor repeat the multiple fields for more than one output that the ill-designed C formatting requires because it won't allow for repeat specifiers as does the Fortran FORMAT--a real weak point/flaw.
Ver también
Categorías
Más información sobre Line Plots en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!