Skip to content

Commit

Permalink
refactoring some plotting
Browse files Browse the repository at this point in the history
Changes based around experimentMultiPanelFigure() method. Aims to make
it easier to extend and compose a different series of experiment
related plots based on the model type. For example, plotting subjective
time functions (see #147).
Has involved moving some methods to superclasses
  • Loading branch information
Ben Vincent committed May 20, 2017
1 parent 3dc70a4 commit 9ea4806
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 95 deletions.
23 changes: 23 additions & 0 deletions ddToolbox/models/Model.m
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ function export(obj)
% predicted_subjective_values.A_full_posterior =
% predicted_subjective_values.B_full_posterior =
end

function discountFunctionVariables = getGiscountFunctionVariables(obj)
discountFunctionVariables = {obj.varList.discountFunctionParams.name};
end

function responseErrorVariables = getResponseErrorVariables(obj)
responseErrorVariables = {obj.varList.responseErrorParams.name};
end

end

Expand Down Expand Up @@ -386,6 +394,21 @@ function plot_discount_functions_in_one(obj)
% set(gca,'FontSize',10)
drawnow
end

function plot_density_alpha_epsilon(obj, subplot_handle, ind)
responseErrorVariables = obj.getResponseErrorVariables();

% TODO: remove duplication of "opts" in mulitple places, but also should perhaps be a single coherent structure in the first place.
opts.pointEstimateType = obj.plotOptions.pointEstimateType;
opts.timeUnits = obj.timeUnits;
opts.dataPlotType = obj.plotOptions.dataPlotType;

obj.coda.plot_bivariate_distribution(subplot_handle,...
responseErrorVariables(1),...
responseErrorVariables(2),...
ind,...
opts)
end

end

Expand Down
15 changes: 5 additions & 10 deletions ddToolbox/models/nonparametric_models/NonParametric.m
Original file line number Diff line number Diff line change
Expand Up @@ -173,25 +173,20 @@ function experimentMultiPanelFigure(obj, ind)
latex_fig(12, 14, 3)
h = layout([1 2 3]);

opts.pointEstimateType = obj.plotOptions.pointEstimateType;
opts.timeUnits = obj.timeUnits;
% opts.pointEstimateType = obj.plotOptions.pointEstimateType;
% opts.timeUnits = obj.timeUnits;

% create cell arrays of relevant variables
discountFunctionVariables = {obj.varList.discountFunctionParams.name};
responseErrorVariables = {obj.varList.responseErrorParams.name};

obj.plot_density_alpha_epsilon(h(1), ind)

%% Set up psychometric function
%psycho = PsychometricFunction('samples', obj.coda.getSamplesAtIndex_asStruct(ind,responseErrorVariables));
% TODO: This doesn't do any plotting as it stands
psycho = PsychometricFunction('samples', obj.coda.getSamplesAtIndex_asStochastic(ind,responseErrorVariables));

%% PLOT: density plot of (alpha, epsilon)
obj.coda.plot_bivariate_distribution(h(1),...
responseErrorVariables(1),...
responseErrorVariables(2),...
ind,...
opts)



%---- TEMP COMMENTED OUT WHILE I FIX THINGS ----
%% Set up discount function
Expand Down
81 changes: 38 additions & 43 deletions ddToolbox/models/parametric_models/Parametric.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,61 +84,22 @@ function export_it(savename)


function experimentMultiPanelFigure(obj, ind)

latex_fig(12, 14, 3)
h = layout([1 2 3 4]);
opts.pointEstimateType = obj.plotOptions.pointEstimateType;
opts.timeUnits = obj.timeUnits;
opts.dataPlotType = obj.plotOptions.dataPlotType;

% create cell arrays of relevant variables
discountFunctionVariables = {obj.varList.discountFunctionParams.name};
responseErrorVariables = {obj.varList.responseErrorParams.name};

plot_density_alpha_epsilon(h(1))
plot_psychometric_function(h(2))
plot_discount_function_parameters(h(3))
obj.plot_density_alpha_epsilon(h(1), ind)
obj.plot_psychometric_function(h(2), ind)
obj.plot_discount_function_parameters(h(3), ind)
obj.plot_discount_function(h(4), ind)

function plot_density_alpha_epsilon(subplot_handle)
obj.coda.plot_bivariate_distribution(subplot_handle,...
responseErrorVariables(1),...
responseErrorVariables(2),...
ind,...
opts)
end

function plot_psychometric_function(subplot_handle)
subplot(subplot_handle)
psycho = PsychometricFunction('samples',...
obj.coda.getSamplesAtIndex_asStochastic(ind, responseErrorVariables));
psycho.plot(obj.plotOptions.pointEstimateType)
end

function plot_discount_function_parameters(subplot_handle)
switch numel(discountFunctionVariables)
case{1}
obj.coda.plot_univariate_distribution(subplot_handle,...
discountFunctionVariables(1),...
ind,...
opts)
case{2}
obj.coda.plot_bivariate_distribution(subplot_handle,...
discountFunctionVariables(1),...
discountFunctionVariables(2),...
ind,...
opts)
otherwise
error('Currently only set up to plot univariate or bivariate distributions, ie discount functions 1 or 2 params.')
end
end

end

end


methods (Access = private)
methods (Access = protected)

% TODO: this should be moved to CODA
function plotAllTriPlots(obj, plotOptions, modelFilename)
Expand Down Expand Up @@ -168,6 +129,40 @@ function plotAllTriPlots(obj, plotOptions, modelFilename)
end
end


function plot_psychometric_function(obj, subplot_handle, ind)
responseErrorVariables = obj.getResponseErrorVariables();
subplot(subplot_handle)
psycho = PsychometricFunction('samples',...
obj.coda.getSamplesAtIndex_asStochastic(ind, responseErrorVariables));
psycho.plot(obj.plotOptions.pointEstimateType)
end

function plot_discount_function_parameters(obj, subplot_handle, ind)

% TODO: remove duplication of "opts" in mulitple places, but also should perhaps be a single coherent structure in the first place.
opts.pointEstimateType = obj.plotOptions.pointEstimateType;
opts.timeUnits = obj.timeUnits;
opts.dataPlotType = obj.plotOptions.dataPlotType;

discountFunctionVariables = obj.getGiscountFunctionVariables();
switch numel(discountFunctionVariables)
case{1}
obj.coda.plot_univariate_distribution(subplot_handle,...
discountFunctionVariables(1),...
ind,...
opts)
case{2}
obj.coda.plot_bivariate_distribution(subplot_handle,...
discountFunctionVariables(1),...
discountFunctionVariables(2),...
ind,...
opts)
otherwise
error('Currently only set up to plot univariate or bivariate distributions, ie discount functions 1 or 2 params.')
end
end

end

end
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@

obj.plotOptions.dataPlotType = '2D';
end

% Override this function from superclass
function experimentMultiPanelFigure(obj, ind)
latex_fig(12, 14, 3)
h = layout([1 2 3 4 5]);
opts.pointEstimateType = obj.plotOptions.pointEstimateType;
opts.timeUnits = obj.timeUnits;
opts.dataPlotType = obj.plotOptions.dataPlotType;

obj.plot_density_alpha_epsilon(h(1), ind)
obj.plot_psychometric_function(h(2), ind)
obj.plot_discount_function_parameters(h(3), ind)
% TODO: PLOT OF SUBJECTIVE TIME FUNCTION HERE
obj.plot_discount_function(h(5), ind)
end


end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,56 +50,62 @@ function experimentMultiPanelFigure(obj, ind)
latex_fig(12, 14, 3);
h = layout([1 2 3 4 5 6]);
opts.pointEstimateType = obj.plotOptions.pointEstimateType;
% create cell array
discountFunctionVariables = {obj.varList.discountFunctionParams.name};
responseErrorVariables = {obj.varList.responseErrorParams.name};

% a list of reward values we are interested in
rewards = [10, 100, 500]; % <---- TODO: inject this
% create colours for colour coding of conditional k plotStyle
col = linspace(0.1, 0.9, numel(rewards));
% % create cell array
% discountFunctionVariables = {obj.varList.discountFunctionParams.name};
% responseErrorVariables = {obj.varList.responseErrorParams.name};


% %% Plot 1: density plot of (alpha, epsilon)
% obj.coda.plot_bivariate_distribution(h(1),...
% responseErrorVariables(1),...
% responseErrorVariables(2),...
% ind,...
% opts);
obj.plot_density_alpha_epsilon(h(1), ind)

% % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% % TODO #166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% %% Set up psychometric function
% respErrSamples = obj.coda.getSamplesAtIndex_asStochastic(ind, responseErrorVariables);
% psycho = PsychometricFunction('samples', respErrSamples);
% %% Plot the psychometric function ------------------------------
% subplot(h(2))
% psycho.plot(obj.plotOptions.pointEstimateType);
% %% Set up discount function
% dfSamples = obj.coda.getSamplesAtIndex_asStochastic(ind, discountFunctionVariables);
% discountFunction = obj.dfClass('samples', dfSamples);
% % inject a DataFile object into the discount function
% discountFunction.data = obj.data.getExperimentObject(ind);
% % TODO #166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj.plot_psychometric_function(h(2), ind)


%% Plot 1: density plot of (alpha, epsilon)
obj.coda.plot_bivariate_distribution(h(1),...
responseErrorVariables(1),...
responseErrorVariables(2),...
ind,...
opts);

% % TODO: this checking needs to be implemented in a smoother, more robust way
% if ~isempty(dfSamples) || ~any(isnan(dfSamples))
% %% Bivariate density plot of discounting parameters
% obj.coda.plot_bivariate_distribution(h(3),...
% discountFunctionVariables(1),...
% discountFunctionVariables(2),...
% ind,...
% opts);
% end
obj.plot_discount_function_parameters(h(3), ind)


% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% TODO #166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%% Set up psychometric function
respErrSamples = obj.coda.getSamplesAtIndex_asStochastic(ind, responseErrorVariables);
psycho = PsychometricFunction('samples', respErrSamples);
%% Plot the psychometric function ------------------------------
subplot(h(2))
psycho.plot(obj.plotOptions.pointEstimateType);
%% Set up discount function

% a list of reward values we are interested in
rewards = [10, 100, 500]; % <---- TODO: inject this
% create colours for colour coding of conditional k plotStyle
col = linspace(0.1, 0.9, numel(rewards));

%% Set up magnitude effect function -----------------------
discountFunctionVariables = obj.getGiscountFunctionVariables();
dfSamples = obj.coda.getSamplesAtIndex_asStochastic(ind, discountFunctionVariables);
discountFunction = obj.dfClass('samples', dfSamples);
% inject a DataFile object into the discount function
discountFunction.data = obj.data.getExperimentObject(ind);
% TODO #166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



% TODO: this checking needs to be implemented in a smoother, more robust way
if ~isempty(dfSamples) || ~any(isnan(dfSamples))
%% Bivariate density plot of discounting parameters
obj.coda.plot_bivariate_distribution(h(3),...
discountFunctionVariables(1),...
discountFunctionVariables(2),...
ind,...
opts);
end


% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% TODO #166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%% Set up magnitude effect function -----------------------
me = MagnitudeEffectFunction('samples', dfSamples);
me.maxRewardValue = obj.data.getMaxRewardValue(ind);
% plot magnitude effect
Expand All @@ -110,8 +116,12 @@ function experimentMultiPanelFigure(obj, ind)
for n=1:numel(rewards)
vline(rewards(n), 'Color', [col(n) col(n) col(n)], 'LineWidth', 2);
end


subplot(h(5)) % -----------------------------------------------
%title('P(log(k) | reward)')
discountFunction = obj.dfClass('samples', dfSamples);

discountFunction.getLogDiscountRate(rewards, ind ,...
'plot', true,...
'plot_mode', 'conditional_only');
Expand Down

0 comments on commit 9ea4806

Please sign in to comment.