I plotted a bubble chart using scatter plot in Matlab with text lables on x axis and integer numbers on y axis. The bubble sizes are also considered as integer numbers. I included both code and figure of my chart. When I try to transform the figure to tikz using "matlab2tikz" library, I see the following error:
"Error using categorical/cat (line 69): Can not concatenate a double array and a categorical array".
I don't have any double numbers in my values. How can I transform this figure to tikz format?
x = ["C","A", "P", "K"]; %x lables
x1=categorical(x);
y = [33,68,200,14];% values
y1 = [48,177,200,16];
y2=[6,6,200,3];
sz = [35,7, 10, 56];%Bubble sizes
sz1=[25,7, 30, 53];
sz2=[44, 8,4,10];
scatter(x1,y,sz,'g','LineWidth',2);
hold on
scatter(x1,y1,sz1,'b','LineWidth',2);
hold on
scatter(x1,y2,sz2,'r','LineWidth',2);
hold off
legend({'y = Method1','y = Method2', 'y = Method3'},'Location','north');
title('NewModel');
ylabel('%Value');
saveas(gcf,'test.png');
You do have double numbers. y, y1 and y2 are double whereas x1 is categorical which is why you are getting that error.
For your case, the error can be fixed by changing the square brackets to curly brackets in line 4052. i.e. change:
data = [xData(:), yData(:)]; %line 4052 of matlab2tikz.m
to:
data = {xData(:), yData(:)};
The reason is what the error message says. You have categorical xData and double yData. These cannot be concatenated into a regular array. A cell array is for combining different types of data.
Similarly,
data=applyHgTransform(m2t,[xData(:), yData(:), zData(:)]); %line 4056 of matlab2tikz.m
should be modified to the following if you are plotting in 3D and have mixed data type:
data=applyHgTransform(m2t,{xData(:), yData(:), zData(:)});
Related
I want to calculate the area beween the orange and the blue line. I managed to shade the area. But I do not know how to apply the trapz function in order to get the area. In this post: Area under surface between two curves I got some solutions but I do not have a specific equation for the curves just the plots per se.
The code for the orange line is:
x_1 = [0,M1_1];
y_1 = [c1,c1];
v = plot(x_1,y_1,'LineWidth',2)
The blue curve is a plot of arrays with the length of (10000x1)-abscissa and (1x10000)-ordinate.
If I use
%c0_1: Intersection blue curve with y-axis
%c1_1: Intersection orange curve with y-axis
A = trapz(ab1(0:c1_1),ab_y1(c1_1:c0_1))
I get the following error:
Warning: Integer operands are required for colon operator when used as
index Warning: Integer operands are required for colon operator when
used as index Error using trapz (line 58) LENGTH(X) must equal the
length of Y in dim 2.
How can I apply my trapz function easily on my problem?
Here is an answer, although I'm not sure what is the difference between the situation here and here, and therefore I'm not sure it truelly answers your question...
Anyway, you don't need to know y1 function explicitly, just to have its' series of data.
x = 0:0.1:12; % x data
y1 = 3*exp(-0.5*x); % y data
y2 = 0.5;
lineStart = find(x>=0,1);
lineEnd = find(y1<=y2,1);
f = plot(x,y1,'b',x,ones(1,length(x))*y2,'r','LineWidth',2);
ylim([0 4])
hold on
area(x(lineStart:lineEnd),y1(lineStart:lineEnd), y2,...
'EdgeColor', 'none', 'FaceColor', [0.5 0.5 1],'ShowBaseLine','off')
hold off
A = trapz(x(lineStart:lineEnd),y1(lineStart:lineEnd));
I added also the illustration of the integrated area:
Tell me is that solves the problem ;)
I have a MATLAB subplot figure. I need the YLabels to left align justify. To do this I am setting the Position property for each ylabel. My problem is the subplots are being created programmatically and therefore I don't know what to set the position as.
In MATLAB I want to use the longest/widest YTickLabel as a reference point for positioning. To do that I want to get the length of each label. I am able to get the YTickLabels by doing:
% Set Label format as string
set(gca, 'YTickLabel', num2str(transpose(get(gca, 'YTick'))))
% Get axis YTickLabels
ax = gca;
labels = get(ax, 'YTickLabel');
% Print labels to console
disp(labels)
I would like to iterate through the labels and find the length of the longest label. I've tried accessing them as a cell array but get 'Cell contents reference from a non-cell array object error.' And when I try matrix indexing nothing prints.
Does anyone know if it is possible to get the length of each individual YTickLabel value?
Useful info:
MATLAB R2014b
By "length of each individual YTickLabel value" I understand that you wish to get the number of characters forming each label.
It's quite easy using the numel function, which outputs the number of elements in a cell for an example. Since labels are stored in a cell array, we can use the fancy function cellfun to apply numel to each cell, then convert to a numeric array with cell2mat
In short you can use this:
LabelLength = cell2mat(cellfun(#(x) numel(x),labels,'uni',0))
here is some sample code to illustrate:
clear
clc
close all
x = 1:5;
y = rand(size(x));
scatter(x,y,40,'r','filled')
set(gca,'YTick',[1 3 5],'YTickLabel',{'One';'ThisIsThree';'AndFive'})
grid on
labels = get(gca,'YTickLabel')
LabelLength = cell2mat(cellfun(#(x) numel(x),labels,'uni',0))
and output:
LabelLength =
3
11
7
You could replace cellfun with this equivalent for-loop:
LabelLength = zeros(numel(labels),1);
for k = 1:numel(labels)
LabelLength(k) = numel(labels{k});
end
LabelLength
Note that as a workaround offering quite a lot of flexibility, you could replace the YTickLabels by text objects, for which you can set the HorizontalAlignment property to left for the text to be left-justified.
Hope that helps!
So I need to plot a function, let's say it's: y = sin( xk )
But I can only write the matlab code like:
x = -pi : .1 : pi;
y = sin(x);
plot(x,y);
If I try to do xk, then it cries about not knowing what k is. Any idea how I can plot functions with variables that contain subscripts (the subscripts are just descriptive, they don't hold any value)? Thanks
Variables cannot have subscripts. You don't have to reproduce the formula exactly in a MATLAB statement. This is fine to name variable just x, or xk, or x_k, etc.
On the other hand, if you have multiple vectors that you want to associate with the same name, you can put them into a cell array and get each vector as x{k}.
You can use subscripts in axes labels, title and text annotations using Tex (default) or Latex interpretor. Use underscore character followed by subscript in a text string.
title('y = sin(x_k)')
or
title('y = sin(x_{several chars})')
I try to read a text files with 20x20 data into variable C, and attempt to plot a histogram on the left Y-axes, and a ecdf/ksdensity on the right X-axes.
Using textscan, the data is read into a 400x1 array. However, when I tried to call plotyy to plot histogram, the code belows return
Error using plot
Vectors must be the same lengths.
Error in pt (line 11)
axes = plotyy(x,C{1},x,C{1});
I guess it is due to C{1}. But have no clue on how to resolve it. I am new to matlab, would anyone point out the correct way to perform the above operations?
fid = fopen('t1_error.txt','r');
C = textscan(fid, '%.3f');
fclose(fid);
disp(C{1});
x = -1:7; % <-- change to x = length(C{1}); then histogram is plotted.
axes = plotyy(x,C{1},x,C{1});
hold on
hist(axes(1), C{1}, x);
ylim(axes(1),'auto');
set(axes(1),'mode','auto');
hold off
The length of x does not equal the length of C{1}. Try x = 1:length(C{1}) or x = -1:8/length(C{1}):7.
I have a custom function which returns either 0 or 1 depending on two given inputs:
function val = myFunction(val1, val2)
% logic to determine if val=1 or val=0
end
How can I create a contour plot of the function over the x,y coordinates generated by the following meshgrid?
meshgrid(0:.5:3, 0:.5:3);
This plot will just simply display where the function is 0 or 1 on the contour map.
If your function myFunction is not designed to handle matrix inputs, then you can use the function ARRAYFUN to apply it to all the corresponding entries of x and y:
[x,y] = meshgrid(0:0.5:3); %# Create a mesh of x and y points
z = arrayfun(#myFunction,x,y); %# Compute z (same size as x and y)
Then you could use the function CONTOUR to generate a contour plot for the above data. Since your z data only has 2 different values, it would probably make sense for you to only plot one contour level (which would be at a value of 0.5, halfway between your two values). You might also want to instead use the function CONTOURF, which produces color-filled contours that will clearly show where the ones and zeroes are:
contourf(x,y,z,1); %# Plots 1 contour level, filling the area on either
%# side with different color
NOTE: Since you are plotting data that only has ones and zeroes, plotting contours may not be the best way to visualize it. I would instead use something like the function IMAGESC, like so:
imagesc(x(1,:),y(:,1),z);
Keep in mind the y-axis in this plot will be reversed relative to the plot generated by CONTOURF.
The following will do it:
function bincontour
clear; clc;
xrange = 0:.5:3;
yrange = 1:.5:5;
[xmesh, ymesh] = meshgrid(xrange, yrange);
z = arrayfun(#myFunction, xmesh, ymesh);
contourf(xrange, yrange, z, 5)
end
function val = myFunction(val1, val2)
val = rand() > 0.5;
end