New utility plot_shock_decomposition.m
new graph_decomp_detail.m for detailed plots of shock contributions new expand_group.m for optional uimenu operation in case of grouped shocks.time-shift
parent
3ed94b2e46
commit
7733484912
|
@ -0,0 +1,47 @@
|
|||
function expand_group(use_shock_groups,var_list_, ic)
|
||||
% function expand_group(use_shock_groups,var_list_, ic)
|
||||
% Expands shocks contributions out of a group of shocks
|
||||
%
|
||||
% INPUTS
|
||||
% use_shock_groups: [char] name of the group
|
||||
% var_list_: [char] list of variables
|
||||
% ic: [int] group # to expand
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2016-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
% Dynare is free software: you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation, either version 3 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% Dynare is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
M = evalin('base','M_');
|
||||
oo = evalin('base','oo_');
|
||||
options = evalin('base','options_');
|
||||
|
||||
% define expanded group
|
||||
label=M.shock_groups.(use_shock_groups).(['group' int2str(ic)]).label;
|
||||
shocks=M.shock_groups.(use_shock_groups).(['group' int2str(ic)]).shocks;
|
||||
options.use_shock_groups = strrep(label,' ','_'); %[use_shock_groups_old int2str(ic)];
|
||||
for j=1:length(shocks)
|
||||
M.shock_groups.(options.use_shock_groups).(['group' int2str(j)]).label=shocks{j};
|
||||
M.shock_groups.(options.use_shock_groups).(['group' int2str(j)]).shocks=shocks(j);
|
||||
end
|
||||
|
||||
options.shock_decomp.fig_names = [options.shock_decomp.fig_names '_expand'];
|
||||
options.shock_decomp.interactive=0;
|
||||
plot_shock_decomposition(M,oo,options,var_list_);
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
function []=graph_decomp_detail(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions,opts_decomp)
|
||||
%function []=graph_decomp_detail(z,shock_names,endo_names,i_var,initial_date,DynareModel,DynareOptions)
|
||||
% Plots the results from the shock_decomposition command
|
||||
%
|
||||
% Inputs
|
||||
% z [n_var*(nshock+2)*nperiods] shock decomposition array, see shock_decomposition.m for details
|
||||
% shock_names [endo_nbr*string length] shock names from M_.exo_names
|
||||
% endo_names [exo_nbr*string length] variable names from M_.endo_names
|
||||
% i_var [n_var*1] vector indices of requested variables in M_.endo_names and z
|
||||
% initial_date [dseries object] first period of decomposition to plot
|
||||
% DynareModel [structure] Dynare model structure
|
||||
% DynareOptions [structure] Dynare options structure
|
||||
|
||||
% Copyright (C) 2010-2016 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
% Dynare is free software: you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation, either version 3 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% Dynare is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
% interactive = 0;
|
||||
% fig_mode='';
|
||||
fig_mode1='';
|
||||
% fig_names='';
|
||||
% screen_shocks=0;
|
||||
use_shock_groups = DynareOptions.use_shock_groups;
|
||||
if use_shock_groups
|
||||
shock_groups = DynareModel.shock_groups.(use_shock_groups);
|
||||
shock_ind = fieldnames(shock_groups);
|
||||
end
|
||||
|
||||
% number of components equals number of shocks + 1 (initial conditions)
|
||||
comp_nbr = size(z,2)-1;
|
||||
|
||||
opts_decomp = DynareOptions.shock_decomp;
|
||||
|
||||
interactive = opts_decomp.interactive;
|
||||
if ~isempty(opts_decomp.fig_mode)
|
||||
fig_mode = opts_decomp.fig_mode;
|
||||
fig_mode1 = ['_' fig_mode];
|
||||
fig_mode = [fig_mode '_'];
|
||||
end
|
||||
if DynareOptions.use_shock_groups,
|
||||
screen_shocks=0;
|
||||
elseif comp_nbr>18
|
||||
screen_shocks = opts_decomp.screen_shocks;
|
||||
end
|
||||
fig_names = opts_decomp.fig_names;
|
||||
% fig_names = ['_' fig_names];
|
||||
fig_names1 = [fig_names];
|
||||
fig_names = [fig_names '_'];
|
||||
if screen_shocks
|
||||
fig_names1 = [fig_names1 '_screen'];
|
||||
fig_names = [fig_names 'screen_'];
|
||||
end
|
||||
|
||||
|
||||
gend = size(z,3);
|
||||
if isempty(initial_date)
|
||||
x = 0:gend;
|
||||
freq = 1;
|
||||
else
|
||||
freq = initial_date.freq;
|
||||
initial_period = initial_date.time(1) + (initial_date.time(2)-1)/freq;
|
||||
x = initial_period-1/freq:(1/freq):initial_period+(gend-1)/freq;
|
||||
end
|
||||
|
||||
ind_yrs = find(floor(x)==x);
|
||||
dind_tick = 1;
|
||||
if floor(length(ind_yrs)/3);
|
||||
dind_tick = floor(length(ind_yrs)/3);
|
||||
xind_tick = x(ind_yrs(1)):dind_tick:x(ind_yrs(end))+(length(ind_yrs)-(dind_tick*3+1));
|
||||
else
|
||||
xind_tick = x(ind_yrs(1)):dind_tick:x(ind_yrs(end))+(length(ind_yrs)-(dind_tick+1));
|
||||
end
|
||||
% xind_tick = floor(x(1))-floor(dind_tick/2):dind_tick:ceil(x(end))+ceil(dind_tick/2);
|
||||
if abs(floor(x(1))-xind_tick(1))-abs(ceil(x(end))-xind_tick(end))>1
|
||||
xind_tick = xind_tick-1;
|
||||
end
|
||||
if abs(floor(x(1))-xind_tick(1))-abs(ceil(x(end))-xind_tick(end))<-1
|
||||
xind_tick = xind_tick+1;
|
||||
end
|
||||
% xind_tick = [x(ind_yrs(1))-floor(dind_tick/2):dind_tick:x(ind_yrs(end))+floor(dind_tick/2)]+1;
|
||||
% xind_tick = x(ind_yrs(1))-1:dind_tick:x(ind_yrs(end))+1;
|
||||
% xind_tick = x(ind_yrs(1))-1:dind_tick:x(ind_yrs(end))+dind_tick;
|
||||
|
||||
nvar = length(i_var);
|
||||
|
||||
%% write LaTeX-Header
|
||||
if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.graph_format)))
|
||||
fidTeX = fopen([DynareModel.fname '_shock_decomp' fig_mode1 fig_names1 '_detail.tex'],'w');
|
||||
fprintf(fidTeX,'%% TeX eps-loader file generated by Dynare''s graph_decomp_detail.m.\n');
|
||||
fprintf(fidTeX,['%% ' datestr(now,0) '\n']);
|
||||
fprintf(fidTeX,' \n');
|
||||
end
|
||||
|
||||
ncol=3;
|
||||
nrow=ceil(comp_nbr/ncol);
|
||||
ntotrow = nrow;
|
||||
nrow = min(ntotrow, 6);
|
||||
nfigs = ceil(ntotrow/nrow);
|
||||
labels = char(char(shock_names),'Initial values');
|
||||
if ~(screen_shocks && comp_nbr>18),
|
||||
screen_shocks=0;
|
||||
end
|
||||
comp_nbr0=comp_nbr;
|
||||
%%plot decomposition
|
||||
for j=1:nvar
|
||||
z1 = squeeze(z(i_var(j),:,:));
|
||||
if screen_shocks,
|
||||
[junk, isort] = sort(mean(abs(z1(1:end-2,:)')), 'descend');
|
||||
labels = char(char(shock_names(isort(1:16),:)),'Others', 'Initial values');
|
||||
zres = sum(z1(isort(17:end),:),1);
|
||||
z1 = [z1(isort(1:16),:); zres; z1(comp_nbr0:end,:)];
|
||||
comp_nbr=18;
|
||||
nfigs=1;
|
||||
end
|
||||
xmin = x(1);
|
||||
xmin = min(xmin, xind_tick(1));
|
||||
xmax = x(end)+1/freq;
|
||||
xmax = max(xmax, xind_tick(end));
|
||||
ix = z1(1:comp_nbr,:) > 0;
|
||||
ymax = max(sum(z1(1:comp_nbr,:).*ix))*1.1;
|
||||
ix = z1(1:comp_nbr,:) < 0;
|
||||
ymin = min(sum(z1(1:comp_nbr,:).*ix))*1.1;
|
||||
if ymax-ymin < 1e-6
|
||||
continue
|
||||
end
|
||||
for jf = 1:nfigs
|
||||
fhandle = dyn_figure(DynareOptions,'Name',['Shock decomposition (detail): ' endo_names(i_var(j),:) fig_mode fig_names1],'position',[200 100 650 850], 'PaperPositionMode', 'auto','PaperOrientation','portrait','renderermode','auto');
|
||||
a0=zeros(1,4);
|
||||
a0(3)=inf;
|
||||
a0(4)=-inf;
|
||||
for ic=1+nrow*ncol*(jf-1):min(nrow*ncol*jf,comp_nbr),
|
||||
i = ic-nrow*ncol*(jf-1);
|
||||
zz = z1(ic,:);
|
||||
zz(2,:)=z1(end,:)-zz;
|
||||
ipos=zz>0;
|
||||
ineg=zz<0;
|
||||
hax = subplot(nrow,ncol,i); set(gca,'box','on')
|
||||
hbar = bar(x(2:end),(zz.*ipos)','stacked');
|
||||
colormap([0.15 0.15 0.15;0.85 0.85 0.85]),
|
||||
set(hbar,'edgecolor','flat');
|
||||
hold on,
|
||||
hbar = bar(x(2:end),(zz.*ineg)','stacked');
|
||||
colormap([0.15 0.15 0.15;0.85 0.85 0.85]),
|
||||
set(hbar,'edgecolor','flat');
|
||||
title(deblank(labels(ic,:)),'Interpreter','none'),
|
||||
axis tight;
|
||||
a=axis;
|
||||
set(gca,'Xtick',xind_tick)
|
||||
set(gca,'xlim',[xmin xmax])
|
||||
a0(3)=min(a(3),a0(3));
|
||||
a0(4)=max(a(4),a0(4));
|
||||
set(gca,'ylim',a0(3:4))
|
||||
hold on, h1=plot(x(2:end),z1(end,:),'k-','LineWidth',2);
|
||||
if interactive & (~isoctave & use_shock_groups)
|
||||
mydata.use_shock_groups = DynareOptions.use_shock_groups;
|
||||
mydata.group_members = shock_groups.(shock_ind{ic}).shocks;
|
||||
set(gca,'UserData',mydata);
|
||||
if ~isempty(mydata.group_members{1})
|
||||
c = uicontextmenu;
|
||||
hax.UIContextMenu=c;
|
||||
browse_menu = uimenu(c,'Label','Browse group');
|
||||
expand_menu = uimenu(c,'Label','Expand group','Callback',['expand_group(''' mydata.use_shock_groups ''',''' deblank(endo_names(i_var(j),:)) ''',' int2str(ic) ')']);
|
||||
for jmember = mydata.group_members
|
||||
uimenu('parent',browse_menu,'Label',char(jmember))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for isub=1:i,
|
||||
subplot(nrow,ncol,isub),
|
||||
set(gca,'ylim',a0(3:4))
|
||||
end
|
||||
if nfigs>1,
|
||||
suffix = ['detail_' int2str(jf)];
|
||||
else
|
||||
suffix = ['detail'];
|
||||
end
|
||||
dyn_saveas(fhandle,[DynareModel.fname,'_shock_decomposition_',fig_mode,deblank(endo_names(i_var(j),:)),fig_names suffix],DynareOptions);
|
||||
if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.graph_format)))
|
||||
fprintf(fidTeX,'\\begin{figure}[H]\n');
|
||||
fprintf(fidTeX,'\\centering \n');
|
||||
fprintf(fidTeX,['\\includegraphics[width=0.8\\textwidth]{%s_shock_decomposition_%s}\n'],DynareModel.fname,[fig_mode deblank(endo_names(i_var(j),:)) fig_names suffix]);
|
||||
fprintf(fidTeX,'\\label{Fig:shock_decomp:%s}\n',deblank(endo_names(i_var(j),:)));
|
||||
fprintf(fidTeX,'\\caption{Historical shock decomposition: $ %s $}\n',deblank(DynareModel.endo_names_tex(i_var(j),:)));
|
||||
fprintf(fidTeX,'\\end{figure}\n');
|
||||
fprintf(fidTeX,' \n');
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%% write LaTeX-Footer
|
||||
if DynareOptions.TeX && any(strcmp('eps',cellstr(DynareOptions.graph_format)))
|
||||
fprintf(fidTeX,' \n');
|
||||
fprintf(fidTeX,'%% End of TeX file.\n');
|
||||
fclose(fidTeX);
|
||||
end
|
|
@ -0,0 +1,196 @@
|
|||
function plot_shock_decomposition(M_,oo_,options_,varlist)
|
||||
% function plot_shock_decomposition(M_,oo_,options_,varlist)
|
||||
% Computes shocks contribution to a simulated trajectory. The field set is
|
||||
% oo_.shock_decomposition. It is a n_var by nshock+2 by nperiods array. The
|
||||
% first nshock columns store the respective shock contributions, column n+1
|
||||
% stores the role of the initial conditions, while column n+2 stores the
|
||||
% value of the smoothed variables. Both the variables and shocks are stored
|
||||
% in the order of declaration, i.e. M_.endo_names and M_.exo_names, respectively.
|
||||
%
|
||||
% INPUTS
|
||||
% M_: [structure] Definition of the model
|
||||
% oo_: [structure] Storage of results
|
||||
% options_: [structure] Options
|
||||
% varlist: [char] List of variables
|
||||
%
|
||||
% SPECIAL REQUIREMENTS
|
||||
% none
|
||||
|
||||
% Copyright (C) 2016-2017 Dynare Team
|
||||
%
|
||||
% This file is part of Dynare.
|
||||
%
|
||||
% Dynare is free software: you can redistribute it and/or modify
|
||||
% it under the terms of the GNU General Public License as published by
|
||||
% the Free Software Foundation, either version 3 of the License, or
|
||||
% (at your option) any later version.
|
||||
%
|
||||
% Dynare is distributed in the hope that it will be useful,
|
||||
% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
% GNU General Public License for more details.
|
||||
%
|
||||
% You should have received a copy of the GNU General Public License
|
||||
% along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
% indices of endogenous variables
|
||||
if size(varlist,1) == 0
|
||||
varlist = M_.endo_names(1:M_.orig_endo_nbr,:);
|
||||
end
|
||||
|
||||
[i_var,nvar] = varlist_indices(varlist,M_.endo_names);
|
||||
|
||||
% number of variables
|
||||
endo_nbr = M_.endo_nbr;
|
||||
|
||||
% number of shocks
|
||||
nshocks = M_.exo_nbr;
|
||||
% type = '';
|
||||
% fig_names='';
|
||||
% detail_plot=0;
|
||||
% realtime_=0; % 0 is standard; 1 is realtime (pool/vintage); 2 is conditional (pool/vintage); 3 is forecast (pool/vintage)
|
||||
% vintage_=0; % 0 pool realtime/conditional; int: forecast/conditional shock decompositions
|
||||
% forecast_=0;
|
||||
% steadystate=0;
|
||||
% write_xls=0;
|
||||
|
||||
if ~isempty(options_.shock_decomp.fig_names)
|
||||
fig_names=['_' options_.shock_decomp.fig_names];
|
||||
end
|
||||
type=options_.shock_decomp.type;
|
||||
detail_plot=options_.shock_decomp.detail_plot;
|
||||
realtime_= options_.shock_decomp.realtime;
|
||||
vintage_ = options_.shock_decomp.vintage;
|
||||
forecast_ = options_.shock_decomp.forecast;
|
||||
steadystate = options_.shock_decomp.steadystate;
|
||||
write_xls = options_.shock_decomp.write_xls;
|
||||
|
||||
initial_date = options_.initial_date;
|
||||
|
||||
switch realtime_
|
||||
|
||||
case 0
|
||||
z = oo_.shock_decomposition;
|
||||
|
||||
case 1 % realtime
|
||||
if vintage_
|
||||
z = oo_.realtime_shock_decomposition.(['time_' int2str(vintage_)]);
|
||||
fig_names=[fig_names '_realtime_' char(initial_date+vintage_-1)];
|
||||
else
|
||||
z = oo_.realtime_shock_decomposition.pool;
|
||||
fig_names=[fig_names '_realtime_pool'];
|
||||
end
|
||||
|
||||
case 2 % conditional
|
||||
if vintage_
|
||||
z = oo_.conditional_shock_decomposition.(['time_' int2str(vintage_)]);
|
||||
initial_date = options_.initial_date+vintage_-forecast_;
|
||||
fig_names=[fig_names '_conditional_' int2str(forecast_) 'step_' char(initial_date)];
|
||||
else
|
||||
z = oo_.conditional_shock_decomposition.pool;
|
||||
fig_names=[fig_names '_conditional_pool'];
|
||||
end
|
||||
|
||||
case 3 % forecast
|
||||
if vintage_
|
||||
z = oo_.realtime_forecast_shock_decomposition.(['time_' int2str(vintage_)]);
|
||||
initial_date = options_.initial_date+vintage_-1;
|
||||
fig_names=[fig_names '_forecast_' int2str(forecast_) 'step_' char(initial_date)];
|
||||
else
|
||||
z = oo_.realtime_forecast_shock_decomposition.pool;
|
||||
fig_names=[fig_names '_forecast_1step_pool'];
|
||||
end
|
||||
end
|
||||
|
||||
gend = size(z,3);
|
||||
if options_.use_shock_groups
|
||||
shock_groups = M_.shock_groups.(options_.use_shock_groups);
|
||||
shock_ind = fieldnames(shock_groups);
|
||||
ngroups = length(shock_ind);
|
||||
fig_names=[fig_names '_group_' options_.use_shock_groups];
|
||||
shock_names = shock_ind;
|
||||
for i=1:ngroups,
|
||||
shock_names{i} = (shock_groups.(shock_ind{i}).label);
|
||||
end
|
||||
zz = zeros(endo_nbr,ngroups+2,gend);
|
||||
kcum=[];
|
||||
for i=1:ngroups
|
||||
for j = shock_groups.(shock_ind{i}).shocks
|
||||
k = find(strcmp(j,cellstr(M_.exo_names)));
|
||||
zz(:,i,:) = zz(:,i,:) + z(:,k,:);
|
||||
z(:,k,:) = 0;
|
||||
kcum = [kcum k];
|
||||
end
|
||||
end
|
||||
zothers = sum(z(:,1:nshocks,:),2);
|
||||
shock_groups.(['group' int2str(ngroups+1)]).shocks = cellstr(M_.exo_names(find(~ismember([1:M_.exo_nbr],kcum)),:))';
|
||||
M_.shock_groups.(options_.use_shock_groups)=shock_groups;
|
||||
if any(any(zothers)),
|
||||
shock_names = [shock_names; {'Others + Initial Values'}];
|
||||
end
|
||||
zz(:,ngroups+1,:) = sum(z(:,1:nshocks+1,:),2);
|
||||
zz(:,ngroups+2,:) = z(:,nshocks+2,:);
|
||||
z = zz;
|
||||
else
|
||||
shock_names = M_.exo_names;
|
||||
end
|
||||
|
||||
func = @(x) colorspace('RGB->Lab',x);
|
||||
MAP = distinguishable_colors(size(z,2)-1,'w',func);
|
||||
% MAP = [MAP; MAP(end,:)];
|
||||
MAP(end,:) = [0.7 0.7 0.7];
|
||||
% MAP = [MAP; [0.7 0.7 0.7]; [0.3 0.3 0.3]];
|
||||
|
||||
if isempty(options_.colormap),
|
||||
options_.colormap = MAP;
|
||||
end
|
||||
steady_state = oo_.steady_state;
|
||||
fig_mode=type;
|
||||
|
||||
switch type
|
||||
|
||||
case '' % default
|
||||
|
||||
case 'qoq'
|
||||
|
||||
case 'yoy'
|
||||
z=z(:,:,1:end-3)+z(:,:,2:end-2)+z(:,:,3:end-1)+z(:,:,4:end);
|
||||
if ~isempty(initial_date),
|
||||
initial_date = initial_date+3;
|
||||
else
|
||||
initial_date = dates('0Q4');
|
||||
end
|
||||
fig_mode = type;
|
||||
steady_state = 4*steady_state;
|
||||
|
||||
case 'aoa'
|
||||
|
||||
if isempty(initial_date),
|
||||
initial_date = dates('1Y');
|
||||
t0=4;
|
||||
else
|
||||
initial_date = dates([int2str(initial_date.time(1)) 'Y']);
|
||||
t0=4-initial_date.time(2)+1;
|
||||
end
|
||||
z=z(:,:,t0:4:end);
|
||||
fig_mode = 'AoA';
|
||||
|
||||
otherwise
|
||||
|
||||
error('plot_shock_decomposition:: Wrong type')
|
||||
|
||||
end
|
||||
if steadystate
|
||||
options_.shock_decomp.steady_state=steady_state;
|
||||
end
|
||||
options_.shock_decomp.fig_mode=fig_mode;
|
||||
options_.shock_decomp.fig_names=fig_names;
|
||||
if detail_plot,
|
||||
graph_decomp_detail(z,shock_names,M_.endo_names,i_var,initial_date,M_,options_)
|
||||
else
|
||||
graph_decomp(z,shock_names,M_.endo_names,i_var,initial_date,M_,options_,options_.shock_decomp);
|
||||
end
|
||||
|
||||
if write_xls
|
||||
WriteShockDecomp2Excel(z,shock_names,M_.endo_names,i_var,initial_date,M_,options_,options_.shock_decomp);
|
||||
end
|
Loading…
Reference in New Issue