diff --git a/@gramm/draw.m b/@gramm/draw.m index 77dd1aa..207c925 100644 --- a/@gramm/draw.m +++ b/@gramm/draw.m @@ -36,7 +36,13 @@ maxh=0.94; tmp=axes('Position',[0.1 0.965 0.8 0.01],'Parent',obj(1).parent); set(tmp,'Visible','off','XLim',[-1 1],'YLim',[-1 1]); - tmp=text(0,0,obj(1).bigtitle,'FontWeight','bold','Interpreter','none','fontSize',14,'HorizontalAlignment','center'); + tmp=text(0,0,obj(1).bigtitle,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj(1).text_options.font,... + 'FontSize',obj(1).text_options.base_size*obj(1).text_options.big_title_scaling,... + 'HorizontalAlignment','center'); + if ~isempty(obj(1).bigtitle_options) set(tmp,obj(1).bigtitle_options{:}); end @@ -113,7 +119,7 @@ end -%Remove empty cells +%Remove empty cells (SKIPS TRIALS WITH NO SPIKES IN RASTER PLOT !) temp_aes=select_aes(temp_aes,nonempty); %Compute x limits @@ -246,19 +252,6 @@ end obj.results.draw_data=cell(n_groups,1); -%Store different line styles -line_styles={'-' '--' ':' '-.'}; -%Store different sizes -markers={'o' 's' 'd' '^' 'v' '>' '<' 'p' 'h' '*' '+' 'x'}; -if length(uni_size)>1 - sizes=linspace(4,12,length(uni_size)); -else - if uni_size{1}==1 - sizes=6; - else - sizes=uni_size{1}; - end -end obj.firstrun=ones(n_rows,n_columns); %Index in the loops @@ -365,7 +358,7 @@ end %Make axes current - axes(obj.facet_axes_handles(ind_row,ind_column)); + axes(obj.facet_axes_handles(ind_row,ind_column)); hold on @@ -474,9 +467,18 @@ end draw_data.continuous_color=temp_aes.color(sel); draw_data.color=cmap((ind_color-1)*length(uni_lightness)+ind_lightness,:); - draw_data.marker=markers{1+mod(ind_marker-1,length(markers))}; - draw_data.line_style=line_styles{1+mod(ind_linestyle-1,length(line_styles))}; - draw_data.size=sizes(ind_size); + draw_data.marker=obj.point_options.markers{1+mod(ind_marker-1,length(obj.point_options.markers))}; + draw_data.line_style=obj.line_options.styles{1+mod(ind_linestyle-1,length(obj.line_options.styles))}; + if obj.line_options.use_input + draw_data.line_size=obj.line_options.input_fun(uni_size{ind_size}) + else + draw_data.line_size=obj.line_options.base_size+(ind_size-1)*obj.line_options.step_size; + end + if obj.point_options.use_input + draw_data.point_size=obj.point_options.input_fun(uni_size{ind_size}); + else + draw_data.point_size=obj.point_options.base_size+(ind_size-1)*obj.point_options.step_size; + end draw_data.color_index=(ind_color-1)*length(uni_lightness)+ind_lightness; draw_data.n_colors=length(uni_color)*length(uni_lightness); @@ -529,7 +531,8 @@ 'HorizontalAlignment','Center',... 'VerticalAlignment','bottom',... 'FontWeight','bold',... - 'fontSize',12,... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.facet_scaling,... 'Parent',obj.facet_axes_handles(ind_row,ind_column))]; end end @@ -549,7 +552,8 @@ 'HorizontalAlignment','Center',... 'VerticalAlignment','bottom',... 'FontWeight','bold',... - 'fontSize',12,... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.facet_scaling,... 'Parent',obj.facet_axes_handles(ind_row,ind_column))]; end end @@ -566,7 +570,13 @@ 'Parent',obj.parent); set(obj.title_axe_handle,'Visible','off','XLim',[-1 1],'YLim',[-1 1]); - obj.title_text_handle=text(0,0,obj.title,'FontWeight','bold','Interpreter','none','fontSize',14,'HorizontalAlignment','center','Parent',obj.title_axe_handle); + obj.title_text_handle=text(0,0,obj.title,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.title_scaling,... + 'HorizontalAlignment','center',... + 'Parent',obj.title_axe_handle); if ~isempty(obj.title_options) set(obj.title_text_handle,obj.title_options{:}); end @@ -597,14 +607,23 @@ color_legend_map=get_colormap(length(uni_color),1,obj.color_options); obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.color,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.color,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; obj.legend_y=obj.legend_y-legend_y_step; for ind_color=1:length(uni_color) plot([1 2],[obj.legend_y obj.legend_y],'-','Color',color_legend_map(ind_color,:),'lineWidth',3,'Parent',obj.legend_axe_handle) %line(1.5,obj.legend_y,'lineStyle','none','Marker','s','MarkerSize',12,'MarkerFaceColor',color_legend_map(ind_color,:),'MarkerEdgeColor','none') %rectangle('Position',[1.25 obj.legend_y-0.25 0.5 0.5],'EdgeColor','none','FaceColor',color_legend_map(ind_color,:)); obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(uni_color{ind_color}),'Interpreter','none','Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(uni_color{ind_color}),... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Interpreter','none',... + 'Parent',obj.legend_axe_handle)]; obj.legend_y=obj.legend_y-legend_y_step; end end @@ -618,13 +637,25 @@ zeros(length(uni_lightness),1)... zeros(length(uni_lightness),1)]); obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.lightness,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.lightness,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; for ind_lightness=1:length(uni_lightness) plot([1 2],[obj.legend_y obj.legend_y],'-','Color',lightness_legend_map(ind_lightness,:),'lineWidth',3,'Parent',obj.legend_axe_handle) %line(1.5,obj.legend_y,'lineStyle','none','Marker','s','MarkerSize',12,'MarkerFaceColor',lightness_legend_map(ind_lightness,:),'MarkerEdgeColor','none') + obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(uni_lightness{ind_lightness}),'Interpreter','none','Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(uni_lightness{ind_lightness}),... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Interpreter','none',... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; end end @@ -634,7 +665,12 @@ obj.legend_y=obj.legend_y-legend_y_additional_step; obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.color,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.color,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; obj.legend_y=obj.legend_y-legend_y_step; %HACK here, we have to multiply by 2 ?? @@ -651,13 +687,22 @@ caxis([min(min(obj.plot_lim.minc)) max(max(obj.plot_lim.maxc))]); obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(max(max(obj.plot_lim.maxc))),'Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(max(max(obj.plot_lim.maxc))),... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y-legend_y_step,num2str((max(max(obj.plot_lim.maxc))+min(min(obj.plot_lim.minc)))/2),'Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y-legend_y_step,num2str((max(max(obj.plot_lim.maxc))+min(min(obj.plot_lim.minc)))/2),... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y-legend_y_step*2,num2str(min(min(obj.plot_lim.minc))),'Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y-legend_y_step*2,num2str(min(min(obj.plot_lim.minc))),... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; obj.legend_y=obj.legend_y-legend_y_step*3; end @@ -667,12 +712,24 @@ obj.legend_y=obj.legend_y-legend_y_additional_step; obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.marker,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.marker,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; for ind_marker=1:length(uni_marker) - plot(1.5,obj.legend_y,markers{ind_marker},'MarkerEdgeColor','none','MarkerFaceColor',[0 0 0],'Parent',obj.legend_axe_handle) + plot(1.5,obj.legend_y,obj.point_options.markers{ind_marker},'MarkerEdgeColor','none','MarkerFaceColor',[0 0 0],'Parent',obj.legend_axe_handle) + obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(uni_marker{ind_marker}),'Interpreter','none','Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(uni_marker{ind_marker}),... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; end end @@ -682,12 +739,24 @@ obj.legend_y=obj.legend_y-legend_y_additional_step; obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.linestyle,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.linestyle,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; for ind_linestyle=1:length(uni_linestyle) - plot([1 2],[obj.legend_y obj.legend_y],line_styles{ind_linestyle},'Color',[0 0 0],'Parent',obj.legend_axe_handle) + plot([1 2],[obj.legend_y obj.legend_y],obj.line_options.styles{ind_linestyle},'Color',[0 0 0],'Parent',obj.legend_axe_handle) + obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(uni_linestyle{ind_linestyle}),'Interpreter','none','Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(uni_linestyle{ind_linestyle}),... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; end end @@ -697,13 +766,40 @@ obj.legend_y=obj.legend_y-legend_y_additional_step; obj.legend_text_handles=[obj.legend_text_handles... - text(1,obj.legend_y,obj.aes_names.size,'FontWeight','bold','Interpreter','none','fontSize',12,'Parent',obj.legend_axe_handle)]; + text(1,obj.legend_y,obj.aes_names.size,... + 'FontWeight','bold',... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_title_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; for ind_size=1:length(uni_size) - plot([1 2],[obj.legend_y obj.legend_y],'lineWidth',sizes(ind_size)/4,'Color',[0 0 0],'Parent',obj.legend_axe_handle) - plot(1.5,obj.legend_y,'o','markerSize',sizes(ind_size),'MarkerEdgeColor','none','MarkerFaceColor',[0 0 0],'Parent',obj.legend_axe_handle) + + if obj.line_options.use_input + temp_lw=obj.line_options.input_fun(uni_size{ind_size}); + else + temp_lw=obj.line_options.base_size+(ind_size-1)*obj.line_options.step_size; + end + + plot([1 2],[obj.legend_y obj.legend_y],'lineWidth',temp_lw,... + 'Color',[0 0 0],'Parent',obj.legend_axe_handle) + + if obj.point_options.use_input + temp_ps=obj.point_options.input_fun(uni_size{ind_size}); + else + temp_ps=obj.point_options.base_size+(ind_size-1)*obj.point_options.step_size; + end + plot(1,obj.legend_y,'o','markerSize',temp_ps,... + 'MarkerEdgeColor','none','MarkerFaceColor',[0 0 0],'Parent',obj.legend_axe_handle) + obj.legend_text_handles=[obj.legend_text_handles... - text(2.5,obj.legend_y,num2str(uni_size{ind_size}),'Interpreter','none','Parent',obj.legend_axe_handle)]; + text(2.5,obj.legend_y,num2str(uni_size{ind_size}),... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.legend_scaling,... + 'Parent',obj.legend_axe_handle)]; + obj.legend_y=obj.legend_y-legend_y_step; end end @@ -741,6 +837,8 @@ %Set current axes ca = obj.facet_axes_handles(ind_row,ind_column); + set(ca,'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size) if obj.continuous_color @@ -924,6 +1022,7 @@ set(ca,'YTickLabel',''); end + %Set appropriate x ticks if labeled if obj.x_factor @@ -940,14 +1039,23 @@ %Add axes labels on right and botttom graphs only if ind_column==1 || (obj.wrap_ncols>0 && mod(ind_column,obj.wrap_ncols)==1) || ~isempty(temp_aes.z) - ylabel(ca,obj.aes_names.y,'Interpreter','none'); %,'Units','normalized','position',[-0.2 0.5 1] + ylabel(ca,obj.aes_names.y,... + 'Interpreter','none',... + 'FontName',obj.text_options.font,... + 'FontSize',obj.text_options.base_size*obj.text_options.label_scaling); %,'Units','normalized','position',[-0.2 0.5 1] end if (ind_row==length(uni_row) && obj.wrap_ncols<=0) || (obj.wrap_ncols>0 && (length(uni_column)-ind_column)0 %Ignore empty ones - if aes_length==-1 && numel(out.(fields{k}))~=1 + if aes_length==-1 %First aesthetic aes_length=numel(out.(fields{k})); else - if aes_length~=numel(out.(fields{k})) && numel(out.(fields{k}))~=1 %Handle special case of size + if aes_length~=numel(out.(fields{k})) error('Aesthetics have fields of different lengths !') end end %Convert categorical data to cellstr. - if iscategorical(aes.(fields{k})) + if ~old_matlab && iscategorical(aes.(fields{k})) out.(fields{k})=cellstr(out.(fields{k})); end @@ -54,12 +59,6 @@ end - -%Special case for size: -if numel(aes.size)==1 - out.size=ones(size(aes.x))*aes.size; -end - %Missing fields are replaced with arrays of ones for k=1:length(fields) if isempty(aes.(fields{k})) && sum(strcmp(fields{k},{'z' 'ymin' 'ymax'}))==0 %If z, ymin, ymax are empty we leave them empty diff --git a/@gramm/set_line_options.m b/@gramm/set_line_options.m new file mode 100644 index 0000000..53c199e --- /dev/null +++ b/@gramm/set_line_options.m @@ -0,0 +1,29 @@ +function obj = set_line_options( obj , varargin ) +% set_line_options Set line size and style options +% +% 'name',value pairs: +% 'base_size': Default/starting line width for geoms that take in account size +% aesthetics. Default is 1.5 +% 'step_size': Increment in line width for 'size' categories. Default is 1 +% 'use_input': Set to true if a size aesthetic is given as numbers in order +% to use the given size values as line width values. Default is false +% 'input_fun': Provide a function handle to transform the 'size' aesthetic +% values in actual sizes when 'use_input' is set to true. Default is +% identity +% 'styles': Provide order for line style categories. Default is {'-' '--' ':' '-.'} + + +p=inputParser; +my_addParameter(p, 'base_size', 1.5 ); +my_addParameter(p, 'step_size', 1 ); +my_addParameter(p, 'use_input', false ); +my_addParameter(p, 'input_fun', @(v)v ); +my_addParameter(p, 'styles', {'-' '--' ':' '-.'} ); +parse(p,varargin{:}); + +for obj_ind=1:numel(obj) + obj(obj_ind).line_options=p.Results; +end + +end + diff --git a/@gramm/set_point_options.m b/@gramm/set_point_options.m new file mode 100644 index 0000000..86c57ce --- /dev/null +++ b/@gramm/set_point_options.m @@ -0,0 +1,29 @@ +function obj = set_point_options( obj , varargin ) +% set_point_options Set point size and marker options +% +% 'name',value pairs: +% 'base_size': Default/starting point size for geoms that take in account size +% aesthetics. Default is 5 +% 'step_size': Increment in point size for 'size' categories. Default is 2 +% 'use_input': Set to true if a size aesthetic is given as numbers in order +% to use the given size values as point size values. Default is false +% 'input_fun': Provide a function handle to transform the 'size' aesthetic +% values in actual sizes when 'use_input' is set to true. Default is +% identity +% 'styles': Provide order for marker style categories. Default is {'o' 's' 'd' '^' 'v' '>' '<' 'p' 'h' '*' '+' 'x'} + + +p=inputParser; +my_addParameter(p, 'base_size', 5 ); +my_addParameter(p, 'step_size', 2 ); +my_addParameter(p, 'use_input', false ); +my_addParameter(p, 'input_fun', @(v)v ); +my_addParameter(p, 'markers', {'o' 's' 'd' '^' 'v' '>' '<' 'p' 'h' '*' '+' 'x'} ); +parse(p,varargin{:}); + +for obj_ind=1:numel(obj) + obj(obj_ind).point_options=p.Results; +end + +end + diff --git a/@gramm/set_text_options.m b/@gramm/set_text_options.m new file mode 100644 index 0000000..e360140 --- /dev/null +++ b/@gramm/set_text_options.m @@ -0,0 +1,31 @@ +function obj = set_text_options( obj , varargin ) +% set_text_options Provide text size and font options +% +% 'name',value pairs: +% 'base_size': Base text size, corresponds to axis ticks text size (default is 10) +% 'label_scaling': Scaling of axis label sizes relative to base (default is 1) +% 'legend_scaling': Scaling of legend label sizes relative to base (default is 1) +% 'legend_title_scaling': Scaling of legend title sizes relative to base (default is 1.2) +% 'facet_scaling': Scaling of facet title sizes relative to base (default is 1.2) +% 'title_scaling': Scaling of figure title sizes relative to base (default is 1.4) +% 'big_title_scaling': Scaling of overarching figure title size relative to base (default is 1.4) +% 'font': Font to use for text (Default is 'Helvetica') + + +p=inputParser; +my_addParameter(p,'base_size' , 10 ); +my_addParameter(p,'label_scaling', 1 ); +my_addParameter(p,'legend_scaling', 1 ); +my_addParameter(p,'legend_title_scaling', 1.2 ); +my_addParameter(p,'facet_scaling', 1.2 ); +my_addParameter(p,'title_scaling', 1.4 ); +my_addParameter(p,'big_title_scaling', 1.4 ); +my_addParameter(p,'font','Helvetica'); +parse(p,varargin{:}); + +for obj_ind=1:numel(obj) + obj(obj_ind).text_options=p.Results; +end + +end + diff --git a/@gramm/stat_density.m b/@gramm/stat_density.m index ebbf39e..4cbe5d1 100644 --- a/@gramm/stat_density.m +++ b/@gramm/stat_density.m @@ -63,7 +63,7 @@ obj.results.stat_density{obj.result_ind,1}.y=f; [xi,f]=to_polar(obj,xi,f); -hndl=plot(xi,f,'LineStyle',draw_data.line_style,'Color',draw_data.color,'lineWidth',draw_data.size/4); +hndl=plot(xi,f,'LineStyle',draw_data.line_style,'Color',draw_data.color,'lineWidth',draw_data.line_size); obj.results.stat_density{obj.result_ind,1}.handle=hndl; end \ No newline at end of file diff --git a/@gramm/stat_qq.m b/@gramm/stat_qq.m index e6b8ab8..c58eca9 100644 --- a/@gramm/stat_qq.m +++ b/@gramm/stat_qq.m @@ -53,7 +53,7 @@ obj.results.stat_qq{obj.result_ind,1}.x=xdist; obj.results.stat_qq{obj.result_ind,1}.y=y; -hndl=plot(xdist,y,draw_data.marker,'MarkerEdgeColor','none','markerSize',draw_data.size,'MarkerFaceColor',draw_data.color); +hndl=plot(xdist,y,draw_data.marker,'MarkerEdgeColor','none','markerSize',draw_data.point_size,'MarkerFaceColor',draw_data.color); obj.results.stat_qq{obj.result_ind,1}.point_handle=hndl; diff --git a/@gramm/stat_smooth.m b/@gramm/stat_smooth.m index 53d8391..d5ecdac 100644 --- a/@gramm/stat_smooth.m +++ b/@gramm/stat_smooth.m @@ -37,7 +37,7 @@ %[new_draw_data.y{k},new_draw_data.x{k}, ~] = turbotrend(draw_data.x{k}, draw_data.y{k}, params.lambda, 100); [tempy(k,:),tempx(k,:), ~] = turbotrend(draw_data.x{k}, draw_data.y{k}, params.lambda, params.npoints); end - hndl=plot(tempx',tempy','LineStyle',draw_data.line_style,'lineWidth',draw_data.size/4,'Color',draw_data.color); + hndl=plot(tempx',tempy','LineStyle',draw_data.line_style,'lineWidth',draw_data.line_size,'Color',draw_data.color); % %Create fake params for call to stat_summary % summ_params.type='ci'; diff --git a/README.md b/README.md index afa2e41..ee46fe1 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,9 @@ Type doc gramm to find links to the documentation of each method. - Polar coordinates (set_polar()) - Color data can also be displayed as a continous variable, not as a grouping factor (set_continuous_color()) - Possibility to customize color generations in the LCH color space, chose alternative colormaps (Matlab's default, [colorbrewer2](http://colorbrewer2.org)), or provide a custom colormap (set_color_options()) +- Possibility to customize marker shapes and sizes with (set_point_options()) +- Possibility to customize line styles and width with (set_line_options()) +- Possibility to customize text elements with (set_text_options()) - Possibility to change ordering of grouping variables between native, sorted, or custom (set_order_options) - Confidence intervals as shaded areas, error bars or thin lines - Set the width and dodging of graphical elements in geom_ functions, stat_bin(), stat_summary(), and stat_boxplot(), with 'width' and 'dodge' arguments diff --git a/examples.m b/examples.m index 71fe163..5d3d702 100644 --- a/examples.m +++ b/examples.m @@ -92,6 +92,7 @@ g(3,2).set_names('x','Horsepower','y','MPG','column','# Cyl'); g(3,2).set_title('subplot columns'); + figure('Position',[100 100 800 800]); g.draw(); @@ -913,6 +914,43 @@ figure('Position',[100 100 800 600]); g.draw(); +%% Customize the size and style of graphic elements with set_line_options() and set_point_options() + +clear g +x=repmat(1:10,1,5); +y=reshape(bsxfun(@times,1:5,(1:10)'),1,50); +sz=reshape(repmat(1:5,10,1),1,50); + +g(1,1)=gramm('x',x,'y',y,'size',sz); +g(1,1).geom_point(); +g(1,1).geom_line(); +g(1,1).set_title('Default'); + +g(1,2)=gramm('x',x,'y',y,'size',sz); +g(1,2).geom_point(); +g(1,2).geom_line(); +g(1,2).set_line_options('base_size',1,'step_size',0.2,'style',{':' '-' '--' '-.'}); +g(1,2).set_point_options('base_size',4,'step_size',1); +g(1,2).set_title('Modified point and line base and step size + line style'); + +g(2,1)=gramm('x',x,'y',y,'size',sz,'subset',sz~=3 & sz~=4); +g(2,1).geom_line(); +g(2,1).geom_point(); +g(2,1).set_title('Default (size according to category)'); + +g(2,2)=gramm('x',x,'y',y,'size',sz,'subset',sz~=3 & sz~=4); +g(2,2).geom_line(); +g(2,2).geom_point(); +g(2,2).set_line_options('use_input',true,'input_fun',@(s)1.5+s); +g(2,2).set_point_options('use_input',true,'input_fun',@(s)5+s*2); +g(2,2).set_title('Size according to value'); + +g.set_title('Customization of line and point options'); + +figure('Position',[100 100 800 600]); +g.draw(); + + %% Advanced customization of gramm figures % The options for the geom_ and stat_ methods, as well as the % |axe_property()| method allow for high-level customization of gramm figures. Since @@ -920,6 +958,7 @@ % also possible to do more precise customizations and modifications of a % gramm figure once it's drawn. In this figure: % +% * Text sizes and fonts are changed with |set_text_options()| % * Y grid is turned on on all facets with |axe_property('YGrid','on')| % * A vertical line and text is added to only one of the facets by using % the |facet_axes_handles| public property of gramm objects @@ -949,11 +988,20 @@ g.set_title('Fuel economy of new cars between 1970 and 1982'); g.axe_property('YGrid','on'); g.set_parent(p); + +g.set_text_options('font','Courier',... + 'base_size',12,... + 'label_scaling',0.8,... + 'legend_scaling',1.5,... + 'legend_title_scaling',1.5,... + 'facet_scaling',1,... + 'title_scaling',1.5); + g.draw(); %It's possible to use the axes handles to add elements to single axes line([75 75],[0 50],'Color','k','LineStyle','--','Parent',g.facet_axes_handles(1)); -text(75.3,47,'Important event','Parent',g.facet_axes_handles(1)); +text(75.3,47,{'Important' 'event'},'Parent',g.facet_axes_handles(1),'FontName','Courier'); %It's also possible to change properties of graphical elements %Either all at once diff --git a/gramm cheat sheet.pdf b/gramm cheat sheet.pdf index 7b475df..32533b1 100644 Binary files a/gramm cheat sheet.pdf and b/gramm cheat sheet.pdf differ diff --git a/html/examples.html b/html/examples.html index 61a2e68..1fa5b2a 100644 --- a/html/examples.html +++ b/html/examples.html @@ -6,7 +6,7 @@ gramm examples

gramm examples

Examples and how-tos for gramm

Contents

Example from the readme

Here we plot the evolution of fuel economy of new cars bewteen 1970 and 1980 (carbig dataset). Gramm is used to easily separate groups on the basis of the number of cylinders of the cars (color), and on the basis of the region of origin of the cars (subplot columns). Both the raw data (points) and a glm fit with 95% confidence interval (line+shaded area) are plotted.

We stat by loading the sample data (structure created from the carbig dataset)

load example_data;
+  

gramm examples

Examples and how-tos for gramm

Contents

Example from the readme

Here we plot the evolution of fuel economy of new cars bewteen 1970 and 1980 (carbig dataset). Gramm is used to easily separate groups on the basis of the number of cylinders of the cars (color), and on the basis of the region of origin of the cars (subplot columns). Both the raw data (points) and a glm fit with 95% confidence interval (line+shaded area) are plotted.

We stat by loading the sample data (structure created from the carbig dataset)

load example_data;
 

Create a gramm object, provide x (year of production) and y (fuel economy) data, color grouping data (number of cylinders) and select a subset of the data

g=gramm('x',cars.Model_Year,'y',cars.MPG,'color',cars.Cylinders,'subset',cars.Cylinders~=3 & cars.Cylinders~=5);
 

Subdivide the data in subplots horizontally by region of origin using facet_grid()

g.facet_grid([],cars.Origin_Region);
 

Plot raw data as points

g.geom_point();
@@ -120,6 +120,7 @@
 g(3,2).set_names('x','Horsepower','y','MPG','column','# Cyl');
 g(3,2).set_title('subplot columns');
 
+
 figure('Position',[100 100 800 800]);
 g.draw();
 

Methods for visualizing Y~X relationships with X as categorical variable

The following methods can be used when Y data is continuous and X data discrete/categorical.

Here we also use an array of gramm objects in order to have multiple gramm plots on the same figure. The gramm objects use the same data, so we copy them after construction using the copy() method

clear g
@@ -832,7 +833,102 @@
 g.draw();
 
ordering given as values
 ordering given as indices
-

Advanced customization of gramm figures

The options for the geom_ and stat_ methods, as well as the axe_property() method allow for high-level customization of gramm figures. Since the gramm object allows access to all handles for graphical objects, it's also possible to do more precise customizations and modifications of a gramm figure once it's drawn. In this figure:

  • Y grid is turned on on all facets with axe_property('YGrid','on')
  • A vertical line and text is added to only one of the facets by using the facet_axes_handles public property of gramm objects
  • All points are made smaller by using their handles results.grom_point_handle in the set() function
  • Similarly, all confidence areas are made grey g.results.stat_glm.area_handle
  • A subset of the glm lines are made thicker by calling set() on a subset teir handles |g.results.stat_glm(g.results.color==4).line_handle]

It is also possible to set where the gramm axes are drawn by using the set_parent(parent_handle) function, which receives the handle of a figure/uipanel/uitab object to use as parent as argument.

f=figure('Position',[100 100 800 500]);
+

Customize the size and style of graphic elements with set_line_options() and set_point_options()

clear g
+x=repmat(1:10,1,5);
+y=reshape(bsxfun(@times,1:5,(1:10)'),1,50);
+sz=reshape(repmat(1:5,10,1),1,50);
+
+g(1,1)=gramm('x',x,'y',y,'size',sz);
+g(1,1).geom_point();
+g(1,1).geom_line();
+g(1,1).set_title('Default');
+
+g(1,2)=gramm('x',x,'y',y,'size',sz);
+g(1,2).geom_point();
+g(1,2).geom_line();
+g(1,2).set_line_options('base_size',1,'step_size',0.2,'style',{':' '-' '--' '-.'});
+g(1,2).set_point_options('base_size',4,'step_size',1);
+g(1,2).set_title('Modified point and line base and step size + line style');
+
+g(2,1)=gramm('x',x,'y',y,'size',sz,'subset',sz~=3 & sz~=4);
+g(2,1).geom_line();
+g(2,1).geom_point();
+g(2,1).set_title('Default (size according to category)');
+
+g(2,2)=gramm('x',x,'y',y,'size',sz,'subset',sz~=3 & sz~=4);
+g(2,2).geom_line();
+g(2,2).geom_point();
+g(2,2).set_line_options('use_input',true,'input_fun',@(s)1.5+s);
+g(2,2).set_point_options('use_input',true,'input_fun',@(s)5+s*2);
+g(2,2).set_title('Size according to value');
+
+g.set_title('Customization of line and point options');
+
+figure('Position',[100 100 800 600]);
+g.draw();
+
+draw_data = 
+
+         dodge_avl_w: 1
+             facet_x: [30x1 double]
+      dodge_fallback: 0
+             dodge_x: [10x1 double]
+           dodge_ind: [10x1 double]
+             dodge_n: [10x1 double]
+                   x: [10x1 double]
+                   y: [10x1 double]
+                ymin: []
+                ymax: []
+                   z: []
+    continuous_color: [10x1 double]
+               color: [1 0.3673 0.4132]
+              marker: 'o'
+          line_style: '-'
+           line_size: 2.5000
+
+
+draw_data = 
+
+         dodge_avl_w: 1
+             facet_x: [30x1 double]
+      dodge_fallback: 0
+             dodge_x: [10x1 double]
+           dodge_ind: [10x1 double]
+             dodge_n: [10x1 double]
+                ymin: []
+                ymax: []
+               color: [1 0.3673 0.4132]
+              marker: 'o'
+          line_style: '-'
+           line_size: 3.5000
+          point_size: 7
+                   x: [10x1 double]
+                   y: [10x1 double]
+                   z: []
+    continuous_color: [10x1 double]
+
+
+draw_data = 
+
+         dodge_avl_w: 1
+             facet_x: [30x1 double]
+      dodge_fallback: 0
+             dodge_x: [10x1 double]
+           dodge_ind: [10x1 double]
+             dodge_n: [10x1 double]
+                ymin: []
+                ymax: []
+               color: [1 0.3673 0.4132]
+              marker: 'o'
+          line_style: '-'
+           line_size: 6.5000
+          point_size: 9
+                   x: [10x1 double]
+                   y: [10x1 double]
+                   z: []
+    continuous_color: [10x1 double]
+
+

Advanced customization of gramm figures

The options for the geom_ and stat_ methods, as well as the axe_property() method allow for high-level customization of gramm figures. Since the gramm object allows access to all handles for graphical objects, it's also possible to do more precise customizations and modifications of a gramm figure once it's drawn. In this figure:

  • Text sizes and fonts are changed with set_text_options()
  • Y grid is turned on on all facets with axe_property('YGrid','on')
  • A vertical line and text is added to only one of the facets by using the facet_axes_handles public property of gramm objects
  • All points are made smaller by using their handles results.grom_point_handle in the set() function
  • Similarly, all confidence areas are made grey g.results.stat_glm.area_handle
  • A subset of the glm lines are made thicker by calling set() on a subset teir handles |g.results.stat_glm(g.results.color==4).line_handle]

It is also possible to set where the gramm axes are drawn by using the set_parent(parent_handle) function, which receives the handle of a figure/uipanel/uitab object to use as parent as argument.

f=figure('Position',[100 100 800 500]);
 %Create fake button
 c=uicontrol('Style','pushbutton','String','Dummy','Units','normalized','Position',[0.8 0.45 0.15 0.1]);
 %Create uipanel to put our gramm plots
@@ -848,11 +944,20 @@
 g.set_title('Fuel economy of new cars between 1970 and 1982');
 g.axe_property('YGrid','on');
 g.set_parent(p);
+
+g.set_text_options('font','Courier',...
+    'base_size',12,...
+    'label_scaling',0.8,...
+    'legend_scaling',1.5,...
+    'legend_title_scaling',1.5,...
+    'facet_scaling',1,...
+    'title_scaling',1.5);
+
 g.draw();
 
 %It's possible to use the axes handles to add elements to single axes
 line([75 75],[0 50],'Color','k','LineStyle','--','Parent',g.facet_axes_handles(1));
-text(75.3,47,'Important event','Parent',g.facet_axes_handles(1));
+text(75.3,47,{'Important' 'event'},'Parent',g.facet_axes_handles(1),'FontName','Courier');
 
 %It's also possible to change properties of graphical elements
 %Either all at once
@@ -860,31 +965,31 @@
 set([g.results.stat_glm.area_handle],'FaceColor',[0.4 0.4 0.4]);
 %Or on a subset of them (here only for the lines of glms of 4-cylinder cars)
 set([g.results.stat_glm(g.results.color==4).line_handle],'LineWidth',3);
-

Using different input formats for x and y (1D arrays, cells of arrays, 2D arrays)

Standard ggplot-like input (arrays for everything) Note the continuous line connecting all blue data points, gramm can't know when to start a new line in this case

Y=[1 2 3 4 5 2 3 4 5 6 3 4 5 6 7];
+

Using different input formats for x and y (1D arrays, cells of arrays, 2D arrays)

Standard ggplot-like input (arrays for everything) Note the continuous line connecting all blue data points, gramm can't know when to start a new line in this case

Y=[1 2 3 4 5 2 3 4 5 6 3 4 5 6 7];
 X=[1 2 3 4 5 0 1 2 3 4 -1 0 1 2 3];
 C=[1 1 1 1 1 2 2 2 2 2 2 2 2 2 2];
 figure
 g11=gramm('x',X,'y',Y,'color',C);
 g11.geom_line();
 g11.draw();
-

Adding a group variable solves the problem in a ggplot-like way

G=[1 1 1 1 1 2 2 2 2 2 3 3 3 3 3];
+

Adding a group variable solves the problem in a ggplot-like way

G=[1 1 1 1 1 2 2 2 2 2 3 3 3 3 3];
 figure
 g12=gramm('x',X,'y',Y,'color',C,'group',G);
 g12.geom_line();
 g12.draw();
-

For a more matlab-like solution, Y and X can be 2D arrays, rows will automatically be considered as groups. as a consequence grouping data (color, etc...) are provided for the rows !

Y=[1 2 3 4 5;2 3 4 5 6; 3 4 5 6 7];
+

For a more matlab-like solution, Y and X can be 2D arrays, rows will automatically be considered as groups. as a consequence grouping data (color, etc...) are provided for the rows !

Y=[1 2 3 4 5;2 3 4 5 6; 3 4 5 6 7];
 X=[1 2 3 4 5; 0 1 2 3 4; -1 0 1 2 3];
 C=[1 2 2];
 figure
 g13=gramm('x',X,'y',Y,'color',C);
 g13.geom_line();
 g13.draw();
-

If all X values are the same, it's possible to provide X as a single row

X=[1 2 3 4 5];
+

If all X values are the same, it's possible to provide X as a single row

X=[1 2 3 4 5];
 figure
 g14=gramm('x',X,'y',Y,'color',C);
 g14.geom_line();
 g14.draw();
-

Similar results can be obtained with cells of arrays

Y={[1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7]};
+

Similar results can be obtained with cells of arrays

Y={[1 2 3 4 5] [2 3 4 5 6] [3 4 5 6 7]};
 X={[1 2 3 4 5] [0 1 2 3 4] [-1 0 1 2 3]};
 figure
 g15=gramm('x',X,'y',Y,'color',C);
@@ -897,13 +1002,13 @@
 g16=gramm('x',X,'y',Y,'color',C);
 g16.geom_line();
 g16.draw();
-

With cells of arrays, there is the opportunity to have different lengths for different groups

Y={[1 2 3 4 5] [3 4 5] [3 4 5 6 7]};
+

With cells of arrays, there is the opportunity to have different lengths for different groups

Y={[1 2 3 4 5] [3 4 5] [3 4 5 6 7]};
 X={[1 2 3 4 5] [1 2 3] [-1 0 1 2 3]};
 figure
 g17=gramm('x',X,'y',Y,'color',C);
 g17.geom_line();
 g17.draw();
-