% scatterplot_with_indexes()
% ==========================
%
% by Francesco Montorsi, 24/08/2009
%
% Usage example:
%{
channel_symbols = modulate(modem.qammod('M',16,'SymbolOrder','Gray'),floor(16*rand(1,30)));
scatterplot_with_indexes(channel_symbols,'16-QAM','b.','MarkerSize',20)
%}
function scatterplot_with_indexes(signal, titlestr, plotstring, varargin)
% argument check
% --------------
if nargin < 2
titlestr = 'Complex channel symbols';
end
if nargin < 3 || isempty(plotstring)
plotstring = 'b.';
end
% plot the scatter plot
% ---------------------
% code adapted from MATLAB's scatterplot() function:
if isreal(signal)
error('The given signal should be complex');
end
[rows,cols]=size(signal);
if rows > 1
error('The given signal should be a vector, not a matrix');
end
set(gcf, 'Name', titlestr);
% remove any subplot and reset the current figure (unless hold is on;
% in that case the caller may want to superimpose our output on a
% previous graphic)
if ishold == 0
clf;
end
% do the real plot
show_current_figure_fullscreen();
plot(real(signal).', imag(signal).', plotstring, varargin{:});
hold on;
grid on;
% Adjust the limits
limFact = 1.07;
limits = max(max(abs(axis)),max(max(abs(signal)))*limFact);
axis equal;
axis([-limits limits -limits limits]);
% Label the plot
ylabel('Quadrature');
xlabel('In-Phase');
title(titlestr);
% only add indexes if the number of points is limited;
% otherwise only a chaotic image would result
if length(signal) < 32
% to avoid that indexes of duplicated points overlap on the figure
% making it harder to read the different indexes, group duplicated
% points building an array cmplx_points of unique points and a cell
% array cmplx_points_desc of the associated descriptions
npoints = 1;
to_skip = [];
cmplx_points = zeros(1,length(signal)); % preallocation
for ii=1:length(signal)
if find(to_skip == ii)
continue; % we already grouped this point with another
% coincident point...
end
duplicates_idx = find(signal == signal(ii));
assert(length(duplicates_idx) >= 1);
assert(duplicates_idx(1) == ii);
% store this point in the final array in any case:
cmplx_points(npoints) = signal(ii);
if length(duplicates_idx) == 1
% there is no real duplicate of this point in the scatterplot
% since duplicates_idx(1) == ii!
cmplx_points_desc{npoints} = int2str(ii);
else
% create the description for all duplicated points:
cmplx_points_desc{npoints} = '';
for jj=1:length(duplicates_idx)
cmplx_points_desc{npoints} = ...
strcat(cmplx_points_desc{npoints},int2str(duplicates_idx(jj)),',');
end
% remove final comma:
cmplx_points_desc{npoints} = cmplx_points_desc{npoints}(1:end-1);
% mark all other duplicates as skippable:
to_skip = [to_skip duplicates_idx(2:end)];
end
npoints = npoints + 1;
end
% add to the plot indexes of the various channel symbols
assert(npoints-1 == length(cmplx_points_desc));
for ii=1:npoints-1
text(real(cmplx_points(ii))*1.1, imag(cmplx_points(ii))*1.1, ...
cmplx_points_desc{ii});
end
end
end