Getting hatchfill to properly display a patch legend

조회 수: 169 (최근 30일)
Leo Simon
Leo Simon 2019년 9월 5일
댓글: Ralph van Zwieten 2023년 9월 29일
I'm using hatchfill to create patterned hatches, as the above example illustrates.
However the legend shows a line rather than a patch. Is there any way to make it show a patch?
The attached image shows the output of the code below. The legend icon for the hatch patch should
look like the icon for the regular hatch
tmp.png
obj.X = 1 + [0, 0 , 1 , 1 ]
obj.Y = 1 + [0, 1 , 1 , 0 ]
obj.FaceColor = 'b';
obj.FaceAlpha = 0.4;
obj2.X = [0, 0 , 1/2 , 1/2 ]
obj2.Y = [0, 1/2 , 1/2 , 0 ]
obj2.FaceColor = 'g';
obj2.FaceAlpha = 0.4;
h = patch(obj);
k = patch(obj2);
hatchObj= hatchfill(h);
set(gca,'XLim',[0,3]);
set(gca,'YLim',[0,3]);
legend('hatch patch','patch')

채택된 답변

Leo Simon
Leo Simon 2019년 11월 28일
It turns out that the problems I described in my original question can all be resolved by using the legendflex and hatchfill2 packages.
Here's an extension of my original code, and the picture that it generates.tmp.png
clear all;close all
%parameters of the first patch object
obj(1).X = 1 + [0, 0 , 1 , 1 ];
obj(1).Y = 1 + [0, 1 , 1 , 0 ];
obj(1).FaceColor = 'b';
obj(1).FaceAlpha = 0.2;
HatchColor{1} = [0.4,0.4,0.4];
HatchAngle{1} = 20;
HatchType{1} = 'single';
HatchDensity{1} = 20;
%Parameters of the first patch object
obj(2).X = 0.5*[0, 0 , 1 , 1 ];
obj(2).Y = 0.5*[0, 1 , 1 , 0 ];
obj(2).FaceColor = 'g';
obj(2).FaceAlpha = 0.2;
HatchColor{2} = [1,0,0];
HatchAngle{2} = 20;
HatchDensity{2} = 10;
HatchType{2} = 'cross';
%make the patches
for ii=1:2;
h(ii) = patch(obj(ii));
end;
%hatch the patches
for ii=1:2;
hHatch(ii) = hatchfill2(h(ii),HatchType{ii},...
'HatchAngle',HatchAngle{ii},...
'HatchDensity',HatchDensity{ii},...
'HatchColor',HatchColor{ii});
end;
%Make the legend
Legend = {'blue square','green square'};
[legend_h,object_h,plot_h,text_str] = legendflex(h,Legend,...
'anchor',{'se','se'},...
'buffer',[-90, 60 ],...
'fontSize',20);
%object_h is the handle for the lines, patches and text objects
%hatch the legend patches to match the patches
for ii=1:2;
hHatch(ii+2) = hatchfill2(object_h(ii+2),HatchType{ii}, ...
'HatchAngle',HatchAngle{ii},...
'HatchDensity',HatchDensity{ii},...
'HatchColor',HatchColor{ii});
end;
%I couldn't use hatchfill2 to set the FaceAlpha's so I did it manually
for ii= 1:2
object_h(ii+2).FaceAlpha = obj(ii).FaceAlpha;
end;
  댓글 수: 4
Sille Petrine Vest Hansen
Sille Petrine Vest Hansen 2022년 11월 1일
Hi
I have a issue with the getpos.m function:
Unary operator '~' is not supported for operand of
type 'matlab.ui.Figure'.
Error in getpos (line 160)
if ~href % HREF is the Root object (no 'Position' property)
Error in legendflex (line 465)
legpospx = getpos(h.leg, 'px');
Error in test (line 12)
[legend_h, object_h, plot_h, text_str] = legendflex(bars, legendData, 'Padding', [2, 2, 10], 'FontSize', 18, 'Location', 'NorthEast');
I have the same issue in my own script, but I have also tested the shown script, and the same problem occurs.
Do you know, why this is an issue?
DGM
DGM 2022년 11월 2일
편집: DGM 2022년 11월 2일
What version of that file are you using? The getpos() version 1.2 that's currently included with legendflex() doesn't have that test on line 160, and the test in question isn't written that way.
You might want to check with
which getpos -all
to see if there's an older copy that may have come from somewhere else.

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

추가 답변 (3개)

Simeon
Simeon 2022년 3월 18일
편집: Simeon 2022년 3월 18일
Here's an example.
With its corresponding code.
% Requirements to get this working:
% hatchfill2.m: https://github.com/hokiedsp/matlab-hatchfill2/blob/master/hatchfill2.m
% legendflex.m: https://github.com/kakearney/legendflex-pkg/blob/master/legendflex/legendflex.m
% getpos.m: https://github.com/kakearney/legendflex-pkg/blob/master/setgetpos_V1.2/getpos.m
hold on;
bar1 = bar(1, 100, 'FaceColor', 'white');
bar2 = bar(2, 50, 'FaceColor', 'white');
% Keep an array of the plots so that none of the hatchfill2 lines appear in the legend
bars = [bar1, bar2];
% Hatch the two bars with a texture
hatchfill2(bar1(1), 'cross', 'HatchAngle', 45, 'HatchDensity', 60, 'HatchColor', 'black');
hatchfill2(bar2(1), 'single', 'HatchAngle', 45, 'HatchDensity', 40, 'HatchColor', 'black');
% Draw the legend
legendData = {'Bar #1', 'Bar #2'};
[legend_h, object_h, plot_h, text_str] = legendflex(bars, legendData, 'Padding', [2, 2, 10], 'FontSize', 18, 'Location', 'NorthEast');
% object_h(1) is the first bar's text
% object_h(2) is the second bar's text
% object_h(3) is the first bar's patch
% object_h(4) is the second bar's patch
%
% Set the two patches within the legend
hatchfill2(object_h(3), 'cross', 'HatchAngle', 45, 'HatchDensity', 60/4, 'HatchColor', 'black');
hatchfill2(object_h(4), 'single', 'HatchAngle', 45, 'HatchDensity', 40/4, 'HatchColor', 'black');
% Some extra formatting to make it pretty :)
set(gca, 'FontSize', 18);
set(gca, 'XMinorTick','on', 'XMinorGrid','on', 'YMinorTick','on', 'YMinorGrid','on');
xlim([0, 3]);
ylim([0, 110]);
I hope this helps someone out there!
  댓글 수: 2
Zafimandimby Mampiandra
Zafimandimby Mampiandra 2022년 4월 28일
I cannot use the function "hatchfill2" it shows that it is not defined.
Can you please help me o solve this problem?
Thanks
Simeon
Simeon 2022년 4월 28일
Hi Zafimandimby, Try running the hatchfill.m file so that Matlab recognizes its functions, then run your plotting script to use those functions.

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


kailin gong
kailin gong 2023년 5월 9일
편집: kailin gong 2023년 5월 9일
Hi, I use hatchfill2 to plot a mixed graph, but I feel confused about how to display a patch legend with other style legend, such as line.
Based on the previous mentioned code.
I add a line:
line=plot([1,2],[5,10]);
I changed the legend:
legendData = {'Bar #1', 'Bar #2', 'Line'};
Then I changed:
[legend_h, object_h, plot_h, text_str] = legendflex([bars, line], legendData, 'Padding', [2, 2, 10], 'FontSize', 18, 'Location', 'NorthEast');
It turns out an error:
Error using hatchfill2>parse_input (line 856)
Unsupported graphics handle type.
Error in hatchfill2 (line 98)
[A,opts,props] = parse_input(A,varargin);
Please help, thanks in advance.
  댓글 수: 4
Simeon
Simeon 2023년 5월 12일
Right, the positioning for legendflex is strange also, if you look here:
You'll see that:
  • North --> 'anchor', [2 2], 'buffer', [0 -10]
  • South --> 'anchor', [6 6], 'buffer', [0 10]
  • East --> 'anchor', [4 4], 'buffer', [-10 0]
  • West --> 'anchor', [8 8], 'buffer', [10 0]
  • NorthEast --> 'anchor', [3 3], 'buffer', [-10 -10]
  • NorthWest --> 'anchor', [1 1], 'buffer', [10 -10]
  • SouthEast --> 'anchor', [5 5], 'buffer', [-10 10]
  • SouthWest --> 'anchor', [7 7], 'buffer', [10 10]
  • NorthOutside --> 'anchor', [2 6], 'buffer', [0 10]
  • SouthOutside --> 'anchor', [6 2], 'buffer', [0 -10]
  • EastOutside --> 'anchor', [3 8], 'buffer', [10 0]
  • WestOutside --> 'anchor', [8 3], 'buffer', [-10 0]
  • NorthEastOutside --> 'anchor', [3 1], 'buffer', [10 0]
  • NorthWestOutside --> 'anchor', [1 3], 'buffer', [-10 0]
  • SouthEastOutside --> 'anchor', [5 7], 'buffer', [10 0]
  • SouthWestOutside --> 'anchor', [7 5], 'buffer', [-10 0]
Also, when saving the figure use ctrl+s instead of clicking the save icon, since unlike the traditional legend, the legendflex legend is its own figure, so you gotta save both of together to have the legend show up in the resulting plot.
Ralph van Zwieten
Ralph van Zwieten 2023년 9월 29일
Hi Simeon,
I have a related question. I am trying to apply the hatchfill to a stacked bar plot that I have, where I keep on running into several errors.
Could you maybe have a look at it?:
LO = [0.1, 0.2, 0.3, 0.4];
OLO = [0.2, 0.3, 0.4, 0.1];
RGO = [0.3, 0.4, 0.1, 0.2];
SFO = [0.4, 0.1, 0.2, 0.3];
comp = [LO; OLO; RGO];% SFO];
comp = oil_comp*100; %
oi = categorical ({'Li', 'Ol', 'Ri'});%, 'Su'});
oi = reordercats(oi, {'Li', 'Ol', 'Ri'});%, 'Su'});
str = {'Li', 'Ol', 'Ri'};
Y= oil_comp;
bar(oi, Y, 'stacked');
ylim([0 102])
ax = get(gca);
cat = ax.Children;
set(cat(4),'FaceColor',[21 96 189]/255);
set(cat(3),'FaceColor',[30 144 255]/255);
set(cat(2),'FaceColor',[130,238,253]/255);
%set(cat(1),'FaceColor',[173 216 230]/255);
set(cat(1),'FaceColor',[255 204 203]/255);
% Hatch the two bars with a texture
hatchfill2(cat(1), 'single', 'HatchAngle', 45, 'HatchDensity', 60, 'HatchColor', 'black');
hatchfill2(cat(2), 'single', 'HatchAngle', 45, 'HatchDensity', 40, 'HatchColor', 'black');
Ultimately, I would like to have the bottom box of every bar with the same hatch density , and then increasing density when going to the boxes above that.
If you know how to give every box an individual color, so having 12 instead of 4 different colors), that would be great to hear as well!
Hopefully you can help me out, thank you in advance.

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


Asvin Kumar
Asvin Kumar 2019년 11월 26일
I presume you’re using the hatchfill function from File Exchange.
Internally, it calls the line function to create the hatch patterns. See lines 171 and 176 of the source code. It follows that the legend would only show line and patch. With this hatchfill function it won’t be possible to change the legend.
  댓글 수: 2
Leo Simon
Leo Simon 2019년 11월 28일
Thanks Asvin, I've switched to hatchfill2 and combined it will legendflex. This combination enables me to do pretty much whatever I need. I've answered my own question below.
Christopher Bitikofer
Christopher Bitikofer 2022년 1월 7일
checking out legendflex. Thanks Leo for posting this!!!

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

카테고리

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

Community Treasure Hunt

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

Start Hunting!

Translated by