how to create legend from neighboring column in 3d plot
5 次查看(过去 30 天)
显示 更早的评论
Hi, I have a question, I'm wondering how I'd be able to create a legend based on a neighboring column
right now I have this code
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1369029/image.png)
And the pulled table doesn't necessarily extract the element names (i assume because it's not integer?)
but I'm wondering how I can make my scatter legend based on my column 1 in the excel sheet?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1369034/image.png)
7 个评论
dpb
2023-4-28
"...but his code does not determine how many cells you selected..."
Au contraire, good buddy! <VBG> I did get that far before the phone rang...it's in
C=jet(nnz(ix));
although not at that point a separate variable...not sure if going to need that or not, yet, but is good possibility.
Will return to the field of battle; may need to look more at the structure of the spreadsheet; I didn't look at it specifically, to know what details may look like...
采纳的回答
dpb
2023-4-28
编辑:dpb
2023-4-29
Why folks continue to beat head against wall with deprecated xlsread is beyond ken...
fn='https://www.mathworks.com/matlabcentral/answers/uploaded_files/1369019/PIP2.xlsx';
opt=detectImportOptions(fn,'ReadVariableNames',1,'VariableNamesRange','A1','DataRange','A2');
opt.SelectedVariableNames=opt.VariableNames(~startsWith(opt.VariableNames,'Var'));
tT=readtable(fn,opt);
head(tT)
There's something really funky about the content of this spreadsheet that dreadfully screws up the MATLAB detection process in trying to find out where the data are and creating an appropriate internal import object.
Without all the help given above, it can't figure out the first row are variable names and that the real data begins in the second row -- it skips down to row 7 -- I've noticed in the past that having some odds 'n ends over to the side out of the way of the main data can confuse things; it seems to have done so royally here.
I'd be tempted to suggest this one be sent to TMW as a sample that their 'bot ought to do a much better job on and as a template to figure out what caused it to lose its way so badly....that's a sidelight; it should NOT be that much grief to read the table -- generally detectimportOptions does do a pretty good job; but "not so much!" on this one. That's frustrating to the newcomer who doesn't yet know about all the innards that one can play with...
Anyways, now on to the problem at hand...
ix=(tT.AtomicNumber>=21)&(tT.AtomicNumber<=30);
hSc3=scatter3(tT.CED(ix),tT.R(ix),tT.E0(ix),'o','filled');
NNZ=nnz(ix);
C=jet(NNZ);
hSc3.CData=C;
xlabel(tT.Properties.VariableNames(5))
ylabel(tT.Properties.VariableNames(4))
zlabel(tT.Properties.VariableNames(3))
OK, now we're back to where was before got so rudely interrupted before, but with the actual full table and names...
scatter3 handle hSc3 is still just one object; so now we'll fix things up to be able to make a legend object to match. This again is a pretty common "hack" one has to do with handle graphics when the base objects don't match what one really wants to do...
%tT(ix,:)
hold on % don't let added stuff wipe out what we've already got drawn
hL=plot(nan(2,NNZ),'o'); % create an array of NNZ columns to force NNZ line handles
set(hL,{'MarkerFaceColor'},num2cell(C,2),{'MarkerEdgeColor'},num2cell(C,2)) % force the same color map
hLg=legend(hL,tT.Element(ix)); % and add the legend on those
8 个评论
dpb
2023-4-29
编辑:dpb
2023-4-29
"...what do I need to do If I want to select at# 21-23,49-52 and 82-83 at the same time?"
The higher level comes in very handy there to reduce clutter...
ix=iswithin(tT.AtomicNumber,21,30)|iswithin(tT.AtomicNumber,49,52)|iswithin(tT.AtomicNumber,82,83);
Nota Bene the "or" operator, not "and". And, of course, you shouldn't write such code burying "magic numbers" inside the code itself, but use a set of low/high range arrays and set those instead. Then you can prompt the user for values desired and not change the code at all. Separate the logic from the data.
The problem with the above solution, however, is that it requires explicit code for the number of disparate selections. That's awfully inconvenient to code around; that solution works well only if the number of groups to be selected from is known a priori and doesn't change.
Alternatively, for disparate sets such as this, you can use some of the other MATLAB set operation functions or ismember
R=[21,30; 49,52; 82,83]; % set ranges desired in array by row, start-stop
rnge=cell2mat(arrayfun(@(i1,i2)i1:i2,R(:,1),R(:,2),'uni',0).'); % convert to a list of wanted values
ix=ismember(tT.AtomicNumber,rnge); % look 'em up in your table.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Calendar 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!