I'm trying to get the green line in the following Matlab code to start from the same point as the other two ones WITHOUT shifting the whole figure to the left, i.e the starting point shouldn't
be attached to the y axis. But I cannot figure out how to. If anyone could help explain how to do it, I'd greatly appreciate the help. :)
all_local = [ 1.0001 1.0001 1.0001 1.0001];
mix_diff_paragraphs = [ 0.59 0.93 0.97 1.0001];
mix_same_paragraphs = [ 0.35 0.55 0.80 1.0001];
axis manual
axis([1,4,0,2]);
y=[1 2 3 4];
h = plot(y+1,all_local,'-om',...
y+1,mix_diff_paragraphs,'-xb',...
y,mix_same_paragraphs,'-+g','LineWidth',2,'MarkerSize',8);
set(gca,'xtick', [1 2 3 4 5]);
set(gca,'XTickLabel',{0,300,500,1000,1500});
set(gca,'ytick', 0:0.2:1.2);
set(gca,'yticklabel', {'0', '0.2', '0.4', '0.6', '0.8','1',''});
legend('Location','BEST','Local users only','Local/Remote users alternate on Pargs.','Local/Remote users modify the same Parg.')
ylabel('Responsiveness');
xlabel('Thinking Period(msec)')
grid on;
That's quite a messy way to do what you did (I don't see why you'd want to change the tick labels without changing the actual x values), but this aside, just add (+1) to the green line:
h = plot(...
...
y+1 ...,'LineWidth',2,'MarkerSize',8);
and in the end add: xlim([1,5]);
If I understood correctly what you were trying to do...
Related
Using Octave 4.2.1 on Windows with the qt graphics toolkit (I can't use gnuplot because it crashes in some other part of the code). I have a dataset which is 35x7x4 (35 data points for 7 conditions on 4 channels) - you can use random data for the purpose of this exercise.
I am trying to create 4 subplots (1 for each channel), with 7 bar graphs on each subplot (one per condition) to see how the distribution of data changes with each condition. Each of the 7x4 = 28 distributions has its own set of bins and frequencies, and I can't seem to be able to combine the 7 datasets on one graph (subplot).
Posting the whole of the code would be too complicated, but here's a simplified version:
nb_channels = 4;
nb_conditions = 7;
nbins = 15;
freq = zeros(nbins,nb_conditions,nb_channels);
xbin = zeros(nbins,nb_conditions,nb_channels);
plot_colours = [91 237 165 255 68 112 255;
155 125 165 192 114 173 0;
213 49 165 0 196 71 255];
plot_colours = plot_colours / 255;
for k = 1:nb_channels
for n = 1:nb_conditions
% some complex calculations to generate temp variable
[freq(:,n,k),xbin(:,n,k)] = hist(temp,nbins);
end
end
figure
for k = 1:nb_channels
subplot(2,2,k)
for n = 1:nb_conditions
bar(xbin(:,n,k),freq(:,n,k),'FaceColor',plot_colours(:,n))
hold on
end
hold off
legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
end
which gives something like this:
So you can't really see anything, all the bars are on top of each other. In addition, Octave doesn't support transparency property for patch objects (which is what bar charts use), so I can't overlay the histograms on top of each other, which I would really quite like to do.
Is there a better way to approach this? It seems that bar will only accept a vector for x data and not a matrix, so I am stuck in having to use hold on and loop through the various conditions, instead of using a matrix approach.
OK, so I'll try to answer my own question based on the suggestions made in the comments:
Suggestion 1: make all the bins the same
This does improve the results somewhat but it's still an issue due to the lack of transparency for patch objects.
Code changes:
nbins = 15;
xbin = linspace(5.8,6.5,nbins);
for k = 1:nb_channels
for n = 1:nb_conditions
% some complex calculations to generate temp variable
freq_flow(:,n,k) = hist(temp,xbin);
end
end
figure
for k = 1:nb_channels
subplot(2,2,k)
for n = 1:nb_conditions
bar(xbin,freq_flow(:,n,k),'FaceColor',plot_colours(:,n))
hold on
end
hold off
xlim([5.8 6.3])
legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
end
Which gives the following plot:
Suggestion 2: Use line plots instead of bar charts
This helps a bit more in terms of readability. However, the result is a bit "piece-wise".
Code changes:
figure
for k = 1:nb_channels
subplot(2,2,k)
for n = 1:nb_conditions
plot(xbin,freq_flow(:,n,k),'LineStyle','none','marker','.',...
'markersize',12,'MarkerEdgeColor',plot_colours(:,n),...
'MarkerFaceColor',plot_colours(:,n))
hold on
end
hold off
xlim([5.8 6.3])
legend('condition #1','condition #2','condition #3','condition #4','condition #5','condition #6','condition #7')
end
Which gives the following result:
The legend is a bit screwed but I can probably sort that out.
A variation on this I also tried was to plot just the points as markers, and then a fitted normal distribution on top. I won't post all the code here, but the result looks something like this:
Suggestion 3: transparency workaround with gnuplot
Unfortunately, before I even got to the transparency workaround, gnuplot keeps crashing when trying to plot the figure. There's something it doesn't like with subplots and legends I think (which is why I moved to qt graphics toolkit in the first place, as I had exactly the same issue in other parts of the code).
Solution 4: use 3D bar graph
I found this on SO: 3D histogram with gnuplot or octave
and used it as such:
figure
for k = 1:size(flow_factor,2)
subplot(2,2,k)
h = my_bar3(freq_flow(:,:,k));
fvcd = kron((1:numel(freq_flow(:,:,k)))', ones(6,1));
set(h, 'FaceVertexCData',fvcd, 'FaceColor','flat', 'CDataMapping','scaled')
colormap hsv; axis tight; view(50,25)
ylbl = cell(length(xbin),1);
for k=1:length(xbin)
ylb{k} = num2str(xbin(k));
end
set(gca,'YTick',1:2:nbins);
set(gca,'YTickLabel',ylb(1:2:end));
end
to produce:
Which isn't bad, but probably not as clear as the line plots.
Conclusion
On balance, I will probably end up using one of the line plots approaches, as they tend to be clearer.
I have been trying to plot two vectors against some x values on the same graph. And I want to set the numerical x labels manually, as characters. But the final result looks weird.
vars = {'50', '100', '250', '500'};
inducing_p = linspace(1,4,4);
ind_table_mse = [0.9051 0.8911 0.8770 0.8688];
ind_table_mseF = [0.9155 0.9070 0.8796 0.8708];
plot(inducing_p, ind_table_mse);
hold on;
plot(inducing_p, ind_table_mseF);
title('ASA Flight Delay Dataset','interpreter','latex');
xlabel('Inducing points','interpreter','latex');
ylabel('MSE','interpreter','latex');
set(gca,'XTickLabel',vars);
xtickangle(45);
And I get this graph, which is not at all of what I indented. As, I would like to see only 50 100 250 500 labels on x. Any suggestions please?
You have first to modify the location of the ticks in your figure
figure
plot(inducing_p, ind_table_mse);
hold on;
plot(inducing_p, ind_table_mseF);
title('ASA Flight Delay Dataset','interpreter','latex');
xlabel('Inducing points','interpreter','latex');
ylabel('MSE','interpreter','latex');
set(gca,'XTick',[1 2 3 4]); %%%% HERE
set(gca,'XTickLabel',vars);
xtickangle(45);
The weird behavior is indeed due to the fact that you specify less labels than ticks. So Matlab just repeats them.
I seem to have the strange problem that when I plot the following, the bars of the two histograms do not seem to have the same width:
hold on
[N,X] = hist(feature_1(:,1))
Bh = bar(X,N,'facecolor',[0.7 0.2 0.2]);
[A,Y] = hist(feature_2(:,1))
Bh = bar(Y,A,'facecolor',[0.3 0.6 0.2]);
hold off
Why is that?
Thanks
Edit: Sorry for not providing input.
For instance, feature_1(:,1:5) =
[0.72507334
0.019627856
0.19571847
-0.23818338
1.6526113
0.23925941
0.69914567
0.15934853
0.28082907
-0.035707321
0.072205774
-0.15791744
0.81654513
0.19398287
-0.33666527
-0.24295111
-1.0770919
-1.2977802
0.67290813
-0.56841594
-0.28522778
-2.2450733
-1.4413888
-2.2216258
-0.46346179
1.8239603
1.6443830
1.3715266
0.34339836
-0.29903534]
and feature_2(:,1) =
[0.18098037
-0.81469119
-0.086869463
-0.67799056
1.1408544
1.2589806
1.0065788
0.64472252
-0.70849174
0.69045025
-0.0031675443
-0.82824785
0.15744546
-0.028384065
-0.065391541
-0.35754660
-1.0809286
-0.12427557
1.3792992
-0.28740802
1.7593855
-1.2061185
-3.0156419
-1.1680259
0.23381938
0.97127295
0.91487378
0.83101124
0.24949571
-0.96599007]
MATLAB suggests you use histogram() instead of hist().
If I had to guess why your bars are of different widths, it would be because you have different numbers of bins for each histogram, though don't take my word for it. (It also could be a stylistic thing, where the bars are offset so that you can see both colors, as hist() does not blend like histogram() does.)
You can solve the width problem by specifying the width using histogram():
histogram(feature_1(:,1:5),'BinWidth',.5);
hold on
histogram(feature_2(:,1),'BinWidth',.5);
If you run this code, you'll be able to see the differences in plotting styles:
subplot(2,1,1)
hold on
[N,X] = hist(feature_1(:,1:5));
Bh = bar(X,N,'facecolor',[0.7 0.2 0.2]);
[A,Y] = hist(feature_2(:,1));
Bh = bar(Y,A,'facecolor',[0.3 0.6 0.2]);
subplot(2,1,2)
histogram(feature_1(:,1:5),'BinWidth',.5,'FaceColor','r');
hold on
histogram(feature_2(:,1),'BinWidth',.5,'FaceColor','g');
Hope this helped somewhat!
I don't get the purpose but width is same for both, the bins are different. If you want to show both in a same figure for comparison purpose, then you must adapt this way
bar([X',Y'])
xlable('-->No of bins')
legend('Feature1','Feature2')
I have 4x1 figure plot with 1 plot taking the upper half. I am viewing it on a relatively high-resolution 1600x1200 monitor, so Matlab should have no problem to fit in. This is especially odd considering a 4x2 figure I have, where Matlabs fits everything alright.
So what is the problem with the 4x1 plot and how do I fix it? Why on earth can't Matlab (2016b) can't do for it what it can for 4x2?
identifier='unshielded';
bat_discharging=readtable('battery_discharging.txt','Format', '%u%f%f%f');
subplot(4,1,[1 2]);
yyaxis left;
plot(bat_discharging{:,1},bat_discharging{:,2});
ylabel('Voltage, V');
yyaxis right
plot(bat_discharging{:,1},bat_discharging{:,3});
hold on
plot(bat_discharging{:,1},bat_discharging{:,4});
ylabel('Current, A');
hold off
xlabel(bat_discharging.Properties.VariableNames{1});
legend('Voltage', 'Current with external reference',...
'Current with internal refence', 'Location','east');
title( ['Discharging, ' identifier]);
subplot(4,1,3);
[ext_currentfit,ext_gof, ext_output] = fit(double(bat_discharging{:,1}),...
bat_discharging{:,3}, 'smoothingspline');
plot(bat_discharging{10:end,1}, ext_output.residuals(10:end));
xlabel(bat_discharging.Properties.VariableNames{1});
ylabel('Current, A');
title(sprintf(...
'Battery current measurement noise, external reference, %s, span=%.3e, %s=%e',...
identifier,range(ext_output.residuals(10:end)),...
'\sigma',std(ext_output.residuals(10:end))));
subplot(4,1,4);
[int_currentfit,ext_gof, int_output] = fit(double(bat_discharging{:,1}),...
bat_discharging{:,4}, 'smoothingspline');
plot(bat_discharging{10:end,1}, int_output.residuals(10:end));
ylabel('Current, A');
xlabel(bat_discharging.Properties.VariableNames{1});
title(sprintf(...
'Battery current measurement noise, internal reference, %s, span=%.3e, %s=%e',...
identifier,range(int_output.residuals(10:end)),...
'\sigma',std(int_output.residuals(10:end))));
first 20 data sets from "battery_discharging.txt"
should be enough to get the code running.
Sample Voltage, V Current external ref Current internal ref
1 3.327263594e+00 -8.607864380e-05 -8.599996567e-05
2 3.326871395e+00 -8.591771126e-05 -8.585631847e-05
3 3.326753676e+00 -8.580327034e-05 -8.570969105e-05
4 3.326707184e+00 -8.567452431e-05 -8.563339710e-05
5 3.326638043e+00 -8.560776711e-05 -8.552610874e-05
6 3.326614201e+00 -8.551001549e-05 -8.547961712e-05
7 3.326560557e+00 -8.546590805e-05 -8.539199829e-05
8 3.326546252e+00 -8.538603783e-05 -8.535683155e-05
9 3.326498866e+00 -8.535146713e-05 -8.528172970e-05
10 3.326489627e+00 -8.528113365e-05 -8.525252342e-05
11 3.326448202e+00 -8.525490761e-05 -8.518755436e-05
12 3.326441050e+00 -8.518815041e-05 -8.516192436e-05
13 3.326403201e+00 -8.516669273e-05 -8.509933949e-05
14 3.326398730e+00 -8.510708809e-05 -8.508086205e-05
15 3.326362669e+00 -8.508801460e-05 -8.502542973e-05
16 3.326360881e+00 -8.503198624e-05 -8.500695229e-05
17 3.326325417e+00 -8.501410484e-05 -8.495271206e-05
18 3.326324224e+00 -8.496403694e-05 -8.493661880e-05
19 3.326291144e+00 -8.494853973e-05 -8.488714695e-05
20 3.326291144e+00 -8.489966393e-05 -8.487284184e-05
MCVE
x = 1:100;
y = rand(100, 1);
subplot(3,1,[1 2]);
plot(x, y);
xlabel('label');
subplot(3,1,3);
plot(x, y);
title('TITLE');
I don't know what causes this problem, and cannot reproduce it, but I think the simplest solution will be to get the handle to the first axes:
ax = subplot(4,1,[1 2]);
and after you completed plotting them, move them a little up:
ax.Position(2) = ax.Position(2)*1.02; % This may be adjusted
% subplot(4,1,3); etc...
Here I take them up by 2%, but you may need a little more. Also, by the same way, you can take the last axes a little down:
ax = subplot(4,1,4);
% do all the plotting
ax.Position(2) = ax.Position(2)*0.98; % This may be adjusted
I have asked several questions about making links on images in matlab, but I want to be able to make a patch a link. I tried the code I posted below but that didnt work. Any ideas on how to make this work?
patch([x2(i) x2(i+1) x2(i+1) x2(i)],[y3(j) y3(j) y3(j+1) y3(j+1)],[-0.01 -0.01 -0.01 -0.01],'r','FaceAlpha' ,.4,'EdgeColor','none','ButtonDownFcn', ['winopen(''' file(j,i) ''');']);
function [filePath] = file( x, y )
filePath = strcat('C:\Documents and Settings\Sentinelle\My Documents\Prostate_082_31\sl5_knt1\sl5_',num2str(x),'-',num2str(y),'.ps');
end
Here is a working example (just adjust the paths of files to something that actually exist):
BASE_DIR = 'C:\path\to\directory';
fcn = #(x,y) fullfile( BASE_DIR , sprintf('file_%d-%d.txt',x,y) );
patch([-1 -1 1 1], [-1 1 -1 1], 'r', ...
'ButtonDownFcn',{#(o,e,f)winopen(f), fcn(2,1)})
axis([-2 2 -2 2])
title('Click the shape to open file...')
Normally, callbacks are called with two input arguments, the handle to an object and a usually empty eventdata. This might lead to the error. Try this instead of ['winopen(''' file(j,i) ''');']:
#(u,v)winopen(#()file(j,i))
The problem is with the position of the patch it was positioned behind the image [-0.01 -0.01 -0.01 -0.01]. The links were being covered up by the image. I changed the code to [0 0 0 0] and this works how I want it to.
patch([x2(i) x2(i+1) x2(i+1) x2(i)],[y3(j) y3(j) y3(j+1) y3(j+1)],[0 0 0 0],'r','FaceAlpha' ,.4,'EdgeColor','none','ButtonDownFcn', ['winopen(''' file(j,i) ''');']);