Skip to content

Commit

Permalink
Added support for changing marker size according to #254
Browse files Browse the repository at this point in the history
  • Loading branch information
blubbafett committed Feb 4, 2014
1 parent 171e9aa commit 8f8f5a9
Showing 1 changed file with 60 additions and 15 deletions.
75 changes: 60 additions & 15 deletions src/matlab2tikz.m
Expand Up @@ -1578,7 +1578,7 @@ function matlab2tikz(varargin)

% 6pt is the default MATLAB marker size for all markers
defaultMatlabMarkerSize = 6;
isDefault = abs(matlabMarkerSize-defaultMatlabMarkerSize)<m2t.tol;
isDefault = abs(matlabMarkerSize(1)-defaultMatlabMarkerSize)<m2t.tol;

switch (matlabMarker)
case 'none'
Expand All @@ -1588,7 +1588,7 @@ function matlab2tikz(varargin)
% square (for example) (~diameter), whereas in TikZ the
% distance of an edge to the center is the measure (~radius).
% Hence divide by 2.
tikzMarkerSize = matlabMarkerSize / 2;
tikzMarkerSize = matlabMarkerSize(:) / 2;
case '.'
% as documented on the Matlab help pages:
%
Expand All @@ -1597,21 +1597,21 @@ function matlab2tikz(varargin)
% The point (.) marker type does not change size when the
% specified value is less than 5.
%
tikzMarkerSize = matlabMarkerSize / 2 / 3;
tikzMarkerSize = matlabMarkerSize(:) / 2 / 3;
case {'s','square'}
% Matlab measures the diameter, TikZ half the edge length
tikzMarkerSize = matlabMarkerSize / 2 / sqrt(2);
tikzMarkerSize = matlabMarkerSize(:) / 2 / sqrt(2);
case {'d','diamond'}
% MATLAB measures the width, TikZ the height of the diamond;
% the acute angle (at the top and the bottom of the diamond)
% is a manually measured 75 degrees (in TikZ, and MATLAB
% probably very similar); use this as a base for calculations
tikzMarkerSize = matlabMarkerSize / 2 / atan(75/2 *pi/180);
tikzMarkerSize = matlabMarkerSize(:) / 2 / atan(75/2 *pi/180);
case {'^','v','<','>'}
% for triangles, matlab takes the height
% and tikz the circumcircle radius;
% the triangles are always equiangular
tikzMarkerSize = matlabMarkerSize / 2 * (2/3);
tikzMarkerSize = matlabMarkerSize(:) / 2 * (2/3);
otherwise
error('matlab2tikz:translateMarkerSize', ...
'Unknown matlabMarker ''%s''.', matlabMarker);
Expand Down Expand Up @@ -2384,11 +2384,19 @@ function matlab2tikz(varargin)
yData = get(h, 'YData');
zData = get(h, 'ZData');
cData = get(h, 'CData');
sData = get(h, 'SizeData');

matlabMarker = get(h, 'Marker');
markerFaceColor = get(h, 'MarkerFaceColor');
hasFaceColor = ~strcmp(markerFaceColor,'none');
[tikzMarker, markOptions] = translateMarker(m2t, matlabMarker, [], hasFaceColor);

if length(sData) == 1
constMarkerkSize = true; % constant marker size
else
constMarkerkSize = false;
[sData, dummy] = translateMarkerSize(m2t, matlabMarker, sData);
end

if length(cData) == 3
% No special treatment for the colors or markers are needed.
Expand All @@ -2398,9 +2406,26 @@ function matlab2tikz(varargin)
else
[m2t, xcolor] = getColor(m2t, h, cData, 'patch');
end
drawOptions = { 'only marks', ...
['mark=' tikzMarker], ...
['color=' xcolor] };
if constMarkerkSize % if constant marker size, do nothing special
drawOptions = { 'only marks', ...
['mark=' tikzMarker], ...
['color=' xcolor] };
else % if changing marker size but same color on all marks
markerOptions = { ['mark=', tikzMarker], ...
sprintf(['draw=' xcolor]) };
if hasFaceColor
markerOptions{end+1} = ['fill=' xcolor];
end
% for changing marker size, the 'scatter' option has to be added
drawOptions = { 'scatter', ...
'only marks', ...
['mark=' tikzMarker] };
if ~hasFaceColor
drawOptions{end+1} = { ['scatter/use mapped color=' xcolor] };
else
drawOptions{end+1} = { ['scatter/use mapped color={', join(m2t, markerOptions,','), '}'] };
end
end
elseif size(cData,2) == 3
drawOptions = { 'only marks' ...
% TODO Get this in order as soon as Pgfplots can do "scatter rgb".
Expand All @@ -2423,23 +2448,43 @@ function matlab2tikz(varargin)
end
% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% plot the thing
drawOpts = join(m2t, drawOptions, ',');
if isempty(zData)
env = 'addplot';
nColumns = 2;
data = [xData(:), yData(:)];
if length(sData) == 1
nColumns = 2;
data = [xData(:), yData(:)];
else
nColumns = 3;
sColumn = 2;
data = [xData(:), yData(:), sData(:)/9];
end
else
env = 'addplot3';
m2t.currentAxesContain3dData = true;
nColumns = 3;
data = applyHgTransform(m2t, [xData(:),yData(:),zData(:)]);
if length(sData) == 1
nColumns = 3;
data = applyHgTransform(m2t, [xData(:),yData(:),zData(:)]);
else
nColumns = 4;
sColumn = 3;
data = applyHgTransform(m2t, [xData(:),yData(:),zData(:),sData(:)/9]);
end
end
% NOTE: Relationship between sizeData entries and marker size is 9:1,
% thus we divide by 9 above in order to get the size of the markers in
% the scatter plot to the same scale as when using markers in a regular
% line plot.
if ~constMarkerkSize %
drawOptions{end+1} = { ['visualization depends on={\thisrowno{', num2str(sColumn), '} \as \perpointmarksize}'], ...
'scatter/@pre marker code/.append style={/tikz/mark size=\perpointmarksize}' };
end
drawOpts = join(m2t, drawOptions, ',');

metaPart = '';
if length(cData) == 3
% If size(cData,1)==1, then all the colors are the same and have
% already been accounted for above.

elseif size(cData,2) == 3
%TODO Hm, can't deal with this?
%[m2t, col] = rgb2colorliteral(m2t, cData(k,:));
Expand Down

5 comments on commit 8f8f5a9

@nschloe
Copy link
Member

@nschloe nschloe commented on 8f8f5a9 Feb 4, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This factor 9 is somewhat debatable. Check out matlab2tikz_acidtest(60):

test60

@blubbafett
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woa; how did I miss that? All the other tests were just fine (or at least with no visual difference as the one in your example).

But I see now running more tests with larger entries of SizeData that the relationship doesn't seem to be as linear as it first seemed like.

The documentation states that the default size of the markers for the scatter plots is 36, whereas for markers in "regular" line plots it is 6 (it's obviously not 6:1, and not 9:1 either, so....). Can try to send an e-mail to Matlab and see if they care to share the relationship between the two.

@egeerardyn
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drgz: If we apply an predictable size progression, I think it should be quite straightforward to identify the scaling, e.g. sizes 1 through 20. But probably the scaling is dependent on the actual marker used, as TikZ and MATLAB use slightly different definitions of the marker size.

@blubbafett
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MarkerSize: [6 7 8 9 10 .... ]
SizeData: [36 54 72 90 108 ...]

P=scatter(n, n, 54*ones(size(n)), n.^8);hold on;Q=plot(n,n,'o','MarkerSize',7)
P=scatter(n, n, 90*ones(size(n)), n.^8);hold on;Q=plot(n,n,'o','MarkerSize',9)
P=scatter(n, n, 108*ones(size(n)), n.^8);hold on;Q=plot(n,n,'o','MarkerSize',10)

As for between Matlab and TikZ I think that should be taken care of by
[sData, dummy] = translateMarkerSize(m2t, matlabMarker, sData);

Relation is 18*(n+1)/(n+5) : 1,or the other way around depending on how you see it, starting with n=1.

What if we scale with a function f(x)=18*x-72?

@blubbafett
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it;

[sData, dummy] = translateMarkerSize(m2t, matlabMarker, 18*sData./(sData+72));

https://dl.dropboxusercontent.com/u/13366636/acid.pdf

Please sign in to comment.