attaching customized colormap to geoshow in matlab - matlab

I am trying to plot a world map in mollweide projection using geoshow command. However, I am not able to modify the colors in the plot based on cutomized colormap values. Most likely this is an issue with how axesm and geoshow commands are used together, Please help me on this. See the ref. code below:
G = rand(180,360);
G(1:90,:)=-1*G(1:90,:);
R = georasterref('RasterSize',size(G),...
'Latlim',[-90 90], 'Lonlim', [-180 180],'ColumnsStartFrom','north');
% ref this link: http://stackoverflow.com/questions/34727526/matlab-plot-raster-map-with-custom-colormap/34740112#34740112
%setting up graphics parameters
my_colormap = [254 204 92
253 141 60
240 59 32
189 0 38]/255 ;
startval=min(min(G));
endval=max(max(G));
nElements =size(my_colormap,1);
stepSize=(endval-startval)/(nElements-1);
breaks = startval:stepSize:endval;
labels = textscan(num2str(round((breaks*100))/100),'%s') ;
labels = labels{1};
[~,indices] = histc(G,breaks);
%actual graphics
figure
hm=axesm ('mollweid', 'Frame', 'on', 'Grid', 'off');
geoshow(G,R);%geoshow(indices,R);
colormap(my_colormap);
set(gca,'color','none');
set(gca,'box','off','xtick',[],'xcolor','none')
set(gca,'box','off','ytick',[],'ycolor','none')
hc=colorbar('location','southoutside');
caxis([breaks(1) breaks(length(breaks))])%caxis([0 length(breaks)-1])
hcP = [.7 .28 .2 .02];
set(hc,'position',hcP);
h.YTickLabel = labels ;

one of my colleague pointed me to the solution and am posting it here for other's reference:
geoshow(G,R,'DisplayType','texturemap')

Related

How to minimize the white space from boxchart in MATLAB?

I would like to minimize the whitespace of the figure (boxchart). I have tried to get a transparent background using built-in function exportgraphics():
https://it.mathworks.com/help/matlab/creating_plots/save-figure-with-minimal-white-space.html
But it doesn't work. Instead, it gives the following error:
Warning: Background transparency is not supported; using white instead.
I wonder if someone help me to remove the white space from the figure?
Thank you in advance.
clc; clear; close;
% data
D1= [0.944790802 0.557698361 0.373906779 2.046704837 2.301581619 1.527444403 1.209060357 0.255009648 0.006522648 1.391635043 0.020485623 3.06E-05 2.219570211 0.031292703 1.4617617 0.709825512 0.140968679 0.39152202 0.118959281 0.604265713 0.108340057 1.254792134 0.187867762 0.391214936 0.527749647 0.284452271 0.137486525 1.50698204 0.398872235 1.09E-05 6.030073741 0.343347524 2.66E-05 0.244522229 1.828567513 0.384888011 0.150066426 0.458832813 0.039189943 1.356957639 0.162054596 0.547751882 3.835735492 0.038394762 0.661566595 0.13553248 0.270139424 1.451613168 0.044339379 0.413170264 1.795609121 0.109564539 0.201333355 1.207746569 0.812164457 0.003902586 3.508953738 0.024859534 1.193314027 ]';
D2= [0.523944609 1.423099939 1.869691969 0.920446948 1.977619794 0.781737256 0.95977679 1.100075857 0.017899515 4.533151907 0.03790224 2.80E-05 3.432894823 0.120809324 2.359138901 1.530822669 0.24903375 3.017043435 0.357091919 1.775763839 0.067044341 2.383827733 0.496209584 1.016302313 2.17366118 0.718760335 0.316183758 1.662342228 0.658886019 1.57E-05 1.798207987 2.194711665 3.12E-05 0.777365181 1.31022147 1.803898883 0.142538755 1.633823624 0.095730818 1.917168272 1.066430117 1.570445025 0.67080804 0.028328869 0.265164055 1.313050736 0.988211581 1.355540089 0.180799139 1.559261863 2.765900536 0.275343017 0.828076679 1.749404233 1.276678701 0.003919396 4.740058349 0.059366823 1.978131529 ]';
D3 = [7.503974554 2.43552972 8.907981809 10.82563814 11.09197623 18.18846472 6.084768631 5.464296776 4.067161596 14.26678079 2.792424541 0.572435047 2.733751731 3.559015982 2.505767574 5.449188972 2.786168085 12.06056623 9.470572167 3.116171421 0.458594772 0.434307287 3.447147643 5.200432201 6.18563517 19.19753749 3.656691267 4.967834173 10.29317107 2.121656326 1.394653476 2.790630109 3.152455521 2.082149563 5.232312376 1.259368399 6.269558563 3.251263155 3.898594351 10.54554845 10.20258999 6.661139665 4.464739104 1.665067753 8.608715167 8.084037724 2.402608378 7.60967001 7.554079841 6.05757598 3.768961429 3.502224334 1.027846476 1.537041705 17.67476646 1.538015623 15.93866248 6.015687282 6.338130064 ]';
data = [D1 D2 D3];
% Requires R2019b or later
t = tiledlayout(2,2, 'Padding', 'none', 'TileSpacing', 'compact');
%box chart
b=boxchart(data);
b.BoxFaceColor = [0 0.4470 0.7410];
b.WhiskerLineColor = [0.17 0.17 0.17];
b.MarkerColor = [0 0.4470 0.7410];%black
b.JitterOutliers = 'on';
b.MarkerStyle = '.';
xlabel('x')
ylabel('y ')
title('Transparent background')
% Requires R2020a or later
exportgraphics(t,'boxPlot.jpg','BackgroundColor','none')
If you wish to maximize chart space, you may manipulate the axis location, as seen in the following code. If exporting transparency is also required, use the PDF format.
figure()
b=boxchart(data);
b.BoxFaceColor = [0 0.4470 0.7410];
b.WhiskerLineColor = [0.17 0.17 0.17];
b.MarkerColor = [0 0.4470 0.7410];%black
b.JitterOutliers = 'on';
b.MarkerStyle = '.';
xlabel('x')
ylabel('y ')
ax.Position=[0.07,0.1,0.92,0.9];

How to plot a "moving" graph for real time values along the x-axis (using psychtoolbox)?

I am writing a code for a real time experiment using psychtoolbox to present the stimulus. In my experiment, I need to show the subject a graph that indicates his performance. I have plotted the graph using this simple code:
% Draw the graph
figure('visible','off','color',[0 0 0]);
pcolor([0 Num_timepoint+2],[-10 0],ones(2,2));
hold on;
pcolor([0 Num_timepoint+2],[0 10],2*ones(2,2));
colormap([79 167 255;255 187 221]/256);
plot(1:subloop,value0,'*-',...
'color',[0,0,0],...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5]);
axis([0,Num_timepoint+2,-10,10]);
saveas(gcf,'line_chart.png'); %save it
close(figure);
line_chart=imread('line_chart.png'); %read it
resized_plot=imresize(line_chart,0.5);
imageSize = size(resized_plot);
[imageHeight,imageWidth,colorChannels]=size(resized_plot);
bottomRect = [xCenter-imageWidth/1.5, yCenter+gapdown, xCenter+imageWidth/1.5, yCenter+gapdown+imageHeight];
imageDisplay=Screen('MakeTexture', win0, resized_plot);
Screen('DrawTexture', win0, imageDisplay, [], bottomRect);
Unfortunately, this simple code is very slow. In addition, I couldn't make the graph moving along x axis, as soon as the new value comes.
Any help would be Awesome. Thanks in advance for your efforts.
Why are you saving the figure and redisplaying as an image? Maybe I'm missing something but you should be able to accomplish what you need by updating the existing plot with the fresh data using the handles properties of the plot:
.... First time through we need the initial plot ....
% Set up figure with colormaps and such but leave as 'visible','on'
hPlot = plot(plot(1:subloop,value0,'*-',...
'color',[0,0,0],...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5]);
hAxes = gca;
.... Loop over your real time updates ....
% Assuming value0 has subject's results from t=0 to t=now
hPlot.XData = value0; hPlot.YData = [1:subloop];
hAxes.XLim = [0 numTimePoints+2];
hAxes.YLim = [-10 10]
.... Continue test and update value0 ....
I think that should keep your plots current without having to save the figure as image to file then reopen the image to display to subject.
If you want to move your data one sample, you can use the circshift function. For example, if you want your new values to appear on the left hand side, you can shift all values 1 sample rightward, then add your new value in the first position.
For converting a MATLAB figure to a Psychtoolbox texture, you don't need to save, then load the temporary images. You can instead use the getframe function to capture the MATLAB figure data, which can then be given to MakeTexture to turn it into a Psychtoolbox texture.
I'm not sure what values you're actually using for subloop, value0, etc. but there is an example that I think might be close to what you want. In this example, 30 frames of figures are plotted, with each figure being on screen for 1 second. New data points are generated randomly and appear from the left hand side of the figure.
Depending on the details of your experiment, you may find that this approach is still too slow. You could also create the figure directly via Psychtoolbox drawing methods like DrawLines, etc. though that would require more effort.
try
win0 = Screen('OpenWindow', 0, 0);
Num_timepoint = 100;
subloop = 100;
value0 = zeros(1,100);
num_demo_frames = 30;
% Draw the graph
fig_h = figure('visible','off','color',[0 0 0]);
pcolor([0 Num_timepoint+2],[-10 0],ones(2,2));
hold on;
pcolor([0 Num_timepoint+2],[0 10],2*ones(2,2));
colormap([79 167 255;255 187 221]/256);
plot_h = plot(1:subloop,value0,'*-',...
'color',[0,0,0],...
'LineWidth',1,...
'MarkerSize',5,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.5,0.5]);
axis([0,Num_timepoint+2,-10,10]);
for f = 1:num_demo_frames
new_value = randn(1,1);
data_values = plot_h.YData;
data_values = circshift(data_values, 1);
data_values(1) = new_value;
plot_h.YData = data_values;
plot_values = getframe(fig_h);
imageDisplay=Screen('MakeTexture', win0, plot_values.cdata);
Screen('DrawTexture', win0, imageDisplay);
Screen('Flip', win0);
WaitSecs(1);
end
sca;
catch e
sca;
rethrow(e);
end

PCA with colorbar

I have this data of which I want to make a principal component analysis.
In particular for each data point I want to associate a color.
This is my code:
for ii=1:size(SBF_ens,1)
SBF(ii) = SBF_ens(ii, max(find(SBF_ens(ii,:)~=0)) ); %value at the moment of the measurement
end
%matrix of data
toPCA =[
wind_trend_72h_ens-nanmean(wind_trend_72h_ens);
wind_trend_24h_ens-nanmean(wind_trend_24h_ens);
wind_trend_12to18h_ens-nanmean(wind_trend_12to18h_ens);
wind_trend_0to12h_ens-nanmean(wind_trend_0to12h_ens);
wind_trend_last6h_ens-nanmean(wind_trend_last6h_ens);
Mwind12h_ens-nanmean(Mwind12h_ens);
Mwind24h_ens-nanmean(Mwind24h_ens);
SBF-nanmean(SBF)]';
variables = { 'wt72h','wt24h','wt12to18h','wt0to12h','wtLast6h','Mw12h', 'Mw24h', 'SBF'}; %labels
%PCA algorithm
C = corr(toPCA,toPCA);
w = 1./var(toPCA);
[wcoeff,score,latent,tsquared,explained] = pca(toPCA,'VariableWeights',w);
coefforth = diag(sqrt(w))*wcoeff;
metric=decstd_ens; %metric for colorbar
hbi=biplot(coefforth(:,1:2),'scores',score(:,1:2),'varlabels',...
variables,'ObsLabels', num2str([1:length(toPCA)]'),...
'markersize', 15);
%plotting
cm = autumn;
colormap(cm);
for ii = length(hbi)-length(toPCA):length(hbi)
userdata = get(hbi(ii), 'UserData');
if ~isempty(userdata)
indCol = ceil( size(cm,1) * abs(metric(userdata))/max(abs(metric)) );%maps decstd between 0 and 1 and find the colormap index
if indCol==0 %just avoid 0
indCol=1;
end
col = cm(indCol,:); %color corresponding to the index
set(hbi(ii), 'Color', col); %modify the dot's color
end
end
for ii = 1:length(hbi)-length(toPCA)-1 %dots corresponding to the original dimensions are in black
set(hbi(ii), 'Color', 'k');
end
c=colorbar;
ylabel(c,'decstd') %is this true?
xlabel(['1^{st} PCA component ', num2str(explained(1)), ' of variance explained'])
ylabel(['2^{nd} PCA component ', num2str(explained(2)), ' of variance explained'])
The resulting figure is the following:
Everything is fine except for the colorbar range. In fact decstd has values between 0 and 2. Actually I do not understand at all what the values on the colorbar are.
Does anyone understand it?
Is it possible to rethrive the data in the colorbar? So to understand what they are?
size(autumn)
shows you that the default length of the autumn colourmap (actually of all the colourmaps) is 64. When you call colorbar, by default it will use tick labels from 1 to n where n is the length of your colourmap, in this case 64.
If you want the mapping of the colourbar ticklabels to match the mapping that you used to get your data to fit between 1 and 64 (i.e. this line of yours indCol = ceil( size(cm,1) * abs(metric(userdata))/max(abs(metric)) );), then you will need to set that yourself like this
numTicks = 6;
cAxisTicks = linspace(min(metric), max(metric), numTicks); % or whatever the correct limits are for your data
caxis([min(metric), max(metric)]);
set(c,'YTick', cAxisTicks );

Box plot with Line in Matlab

I want to merge a line plot with 12 box plot. I can plot both of them in a figure. But the line plot position is not matching with Box plot. Please suggest. Figure is attached
Code:
clc
clear
[data header]=xlsread('Dry and Wet Spell Length.xlsx');
RCP26_JHT=(mean(data(1:4:16,:),1));
RCP26_QIN=mean(data(2:4:16,:),1);
RCP26_SCA=mean(data(3:4:16,:),1);
RCP26_WOL=mean(data(4:4:16,:),1);
RCP45_JHT=mean(data(18:4:33,:),1);
RCP45_QIN=mean(data(19:4:33,:),1);
RCP45_SCA=mean(data(20:4:33,:),1);
RCP45_WOL=mean(data(21:4:33,:),1);
RCP85_JHT=mean(data(35:4:50,:),1);
RCP85_QIN=mean(data(36:4:50,:),1);
RCP85_SCA=mean(data(37:4:50,:),1);
RCP85_WOL=mean(data(38:4:50,:),1);
ANUSPLIN_JHT=mean(data(52,1:23));
ANUSPLIN_QIN=mean(data(53,1:23));
ANUSPLIN_SCA=mean(data(54,1:23));
ANUSPLIN_WOL=mean(data(55,1:23));
AN_Data=repmat([ANUSPLIN_JHT,ANUSPLIN_QIN,ANUSPLIN_SCA,ANUSPLIN_WOL]',1,3);
B=reshape(AN_Data',1,12);
y=1:12;
p=plot(B,'k-s', 'MarkerFaceColor','k');
legend(p,'Obs','Location','north');
hold on
xlim = get(gca,'XLim');
positions=[1,1.25,1.5, 2,2.25,2.5 3 3.25 3.5, 4 4.25,4.5];
boxplot([RCP26_JHT',RCP45_JHT',RCP85_JHT',RCP26_QIN',RCP45_QIN',RCP85_QIN',RCP26_SCA',RCP45_SCA',RCP85_SCA', RCP26_WOL', RCP45_WOL',RCP85_WOL'],'positions', positions);
color = ['b','c','y','b','c','y','b','c','y','b','c','y'];
h = findobj(gca,'Tag','Box');
for j=1:length(h)
patch(get(h(j),'XData'),get(h(j),'YData'),color(j),'FaceAlpha',.5);
end
legend('Obs','RCP 8.5', 'RCP 4.5', 'RCP 2.6');
h1=findobj(gca,'tag','Outliers');
delete (h1);
set(gca,'xtick',[mean(positions(1:3)) mean(positions(4:6)) mean(positions(7:9)) mean(positions(10:12)) ]);
set(gca,'xticklabel',{'JHT','QIN','SCA','WOL'});
set(gca,'XLim',xlim);
hold off

Add legend to graph created iteratively

I am creating a graph iteratively from various data sets, and I try to add legend to it, but it fails.
colors = {'g','b','m','k','c'};
subplot(2,3,iii);
hold all;
for jjj=1:length(aggregation_methods),
aggregate = all_aggregate{jjj};
std_agg = all_std_agg{jjj};
plot(coverages, aggregate, colors{jjj});
h1 = errorbar(coverages,aggregate,std_agg,colors{jjj});
set(h1,'linestyle','none')
end
plot(coverages, regular, 'r');
h1 = errorbar(coverages,regular,std_reg,'r');
set(h1,'linestyle','none')
title(datasets{iii});
xlabel('coverage');
ylabel('MSE');
legend('enhanced with clustering(k=4)','enhanced random split', 'regular we');
The graph seems to be generated just fine, it's just the legend that is failing.
I expect the colors of the legend to be (top-down): green, blue, red.
P.S. I also tried (and it didn't work):
legend({'enhanced with clustering(k=4)','enhanced random split', 'regular we'});
EDIT:
Inspired by this thread, I changed the code to use the 'DisplayName' property for each plot:
colors = {'g','b','m','k','c'};
names = {'enhanced with clustering(k=4)','enhanced random split', 'regular we'};
subplot(2,3,iii);
hold all;
for jjj=1:length(aggregation_methods),
aggregate = all_aggregate{jjj};
std_agg = all_std_agg{jjj};
plot(coverages, aggregate, colors{jjj}, 'DisplayName', names{jjj});
h1 = errorbar(coverages,aggregate,std_agg,colors{jjj});
set(h1,'linestyle','none')
end
%plot(coverages,aggregate,'g',coverages ,regular,'r');
%h1 = errorbar(coverages,aggregate,std_agg,'g');
%set(h1,'linestyle','none')
plot(coverages, regular, 'r', 'DisplayName', names{length(aggregation_methods) + 1});
h1 = errorbar(coverages,regular,std_reg,'r');
set(h1,'linestyle','none')
%axis([0 1 0 max(mean(rc{iii}))]);
title(datasets{iii});
xlabel('coverage');
ylabel('MSE');
legend('show');
However, it yields the following legend, but I'd like to get rid of these 'dataX' strings.
a=[
1 2 3
4 5 6
7 8 9
];
clist={'g','b','m'};
for i=1:3
pt(i)=plot(a(i,:),'Color',clist{i});
hold on;
end
b=[5 6 7];
pt(4)=plot(b,'Color','r');
legend([pt(1:2) pt(4)],{'line1','line2','line4'});