Plot and bar with descending data and double yaxes - matlab

I would like to create a plot with discending data, but I have some problem (see image).I would like that the green line followes yaxes on the right. Why I have this result?
Below there is my script
%grafico con doppio asse y
workdays = dataset.regione;
workhours = dataset.("somma_classe1");
y1 = dataset.("conteggio_classe1");
[~,arr] = sort(y1,'descend');
X = reordercats(categorical(workdays),workdays(arr));
figure;
bar(X,workhours,'yellow');
title('title 1+2')
ylabel('count news','FontSize',11)
hold on
plot(y1,'green')
yyaxis right
ylabel('media impact');

Related

How do I use code to generate a graph where the line crosses the origin in Matlab?

I am trying to use Matlab to generate a line graph, but the line terminates at the last point, and doesn't go all the way to the origin. Is there any way to make it so that the line goes beyond the points in code?
I've attached the code that I'm currently using, along with pictures of what the graph looks like right now and how I want it to look.
%Enter Data
fnet = [0.465, 0.560, 0.670, 0.763, 0.870, 0.971, 1.063];
faccel = [0.434, 0.514, 0.612, 0.684, 0.776, 0.850, 0.915];
asys = [0.4963, 0.6034, 0.7074, 0.8088, 0.9210, 1.030, 1.138]
mh = [0.050, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11]
x = fnet;
y = asys;
%Model Equation
model = 'm*x'
%the model can be changed, ex. m*x^2
IV = 'x'
DV = 'y'
%Create and perform curve fit
newfit = fittype(model, 'Independent', IV, 'Dependent', DV);
%result and goodness of fit, prime symbol converys rows to columns
[result, gof] = fit(x', y', newfit, 'StartPoint', 1)
%plot fits and data points, create plot object for formatting
p = plot(result, x, y);
%style the data points
p(1).MarkerSize = 10;
p(1).Marker = '.';
p(1).MarkerFaceColor = 'blue';
%p(1).MarkerEdgeColor = 'green';
%style the line of best fit
p(2).LineWidth = 1;
p(2).Color = 'black';
%Create graph object, set formatting to latex
graph = gca;
set(graph, 'defaultTextInterpreter', 'latex');
set(legend, 'visible', 'off');
%format title and subtitle
graph.Title.String = {'System Acceleration vs. Net Force on System', 'in Modified Atwood Machine'};
graph.Title.FontSize = 16;
%subtitle, where we will place our equation and statistics
%specifically, the equation w/ units, r squared, slope with plusminus %
graph.Subtitle.Interpreter = 'latex';
graph.Subtitle.String = '$a_{sys} = 1.064 m^{-1}F_{net}, \, r^2=0.9994, m=1.064 \pm 0.007$';
graph.Subtitle.FontSize = 13;
%format x and y axes
graph.XLabel.Interpreter = 'latex';
graph.XLabel.String = '$F_{net} \: (N)$';
graph.XLabel.FontSize = 15;
graph.XLim = [0,1.5];
graph.XGrid = 'on';
graph.XMinorGrid = 'on';
graph.XMinorTick = 'on';
graph.YLabel.Interpreter = 'latex';
graph.YLabel.String = '$a_{sys} \: (\frac{m}{s^2})$';
graph.YLabel.FontSize = 15;
graph.YLim = [0,1.5];
graph.YGrid = 'on';
graph.YMinorGrid = 'on';
graph.YMinorTick = 'on';
Instead of using plot directly on the fit result object, you can call plot with a bit more control and evaluate the result directly for the line
Replace this:
p = plot(result, x, y);
with this:
hold on
p(1) = plot( x, y );
p(2) = plot( [0,2.2], feval(result, [0,2.2]) );
Note you could add the marker and line options during the plot calls now if you wanted, instead of updating p(1) and p(2) in retrospect.

Plot function line specification

I am trying to plot a graph using a straight line in MATLAB; however, I can only print it using dot circles.
I tried changing "ro-" with "r-" and other different solutions but nothing worked. When using "r-" it does not print anything.
This is my code:
for T = temp
figure(i)
for xb = linspace (0,1,10)
xt = 1-xb;
Pb = 10^(6.89272 - (1203.531/(T+219.888)));
Pt = 10^(6.95805 - (1346.773/(T+219.693)));
Ptot = Pb*xb + Pt*xt;
yb = (Pb*xb)/Ptot;
plot(xb, Ptot, 'bo-.')
hold on
plot(yb, Ptot, 'ro-')
end
i = i + 1;
saveas(gcf, filename, 'png')
end
This is what I get:
This is what I want:
How can I make this plot with lines?
To plot a line, the plot command must get all the points along the line in one function call. Repeated calls to plot will add new lines to the figure, and in this case each line is composed of a single point. In short, MATLAB doesn't know you want to connect these dots.
So how do you get all the data points in one array? Simply store them within your loop:
T = 70;
xb = linspace(0,1,10);
Plot = zeros(size(xb)); % preallocate output array
yb = zeros(size(xb)); % preallocate output array
for ii=1:numel(xb)
xt = 1-xb(ii);
Pb = 10^(6.89272 - (1203.531/(T+219.888)));
Pt = 10^(6.95805 - (1346.773/(T+219.693)));
Ptot(ii) = Pb*xb(ii) + Pt*xt;
yb(ii) = (Pb*xb(ii))/Ptot(ii);
end
figure
plot(xb, Ptot, 'b-')
hold on
plot(yb, Ptot, 'r--')
But it is actually easier to do this without a loop at all:
T = 70;
xb = linspace(0,1,10);
xt = 1-xb;
Pb = 10^(6.89272 - (1203.531/(T+219.888)));
Pt = 10^(6.95805 - (1346.773/(T+219.693)));
Ptot = Pb*xb + Pt*xt;
yb = (Pb*xb)./Ptot; % note ./ is the element-wise division
figure
plot(xb, Ptot, 'b-')
hold on
plot(yb, Ptot, 'r--')

volumetric slice plot gone wrong

Here is my code:
xslice = [bestcoefs(1), cc1(no1)];
yslice = [bestcoefs(2), cc2(no2)];
zslice = [cc3(1), bestcoefs(3)];
slice(V, xslice, yslice, zslice, 'linear');
cb = colorbar;
xlabel('c1'); ylabel('c2'); zlabel({'likelihood of (c1,c2,c3)','c3'});
view(3);
V is a matrix of probabilities 6x13x9 and bestcoefs(1), cc1(no1), etc. are points where I want to slice the plot. However, I get this result:
Why does it come out like this? I want it to look like the first one here.
When I run:
% some data:
V = randn(6,13,9);
bestcoefs = randi(6,3,1);
cc = randi(6,3,1);
% your code with slight modifications:
xslice = [bestcoefs(1), cc(1)];
yslice = [bestcoefs(2), cc(2)];
zslice = [cc(1), bestcoefs(3)];
slice(V, xslice, yslice, zslice, 'linear');
cb = colorbar;
xlabel('c1'); ylabel('c2');...
zlabel({'likelihood of (c1,c2,c3)','c3'});
view(3);
I get something like this:
Which looks fine to me. Try to see if your bestcoefs, cc's and no's are defined correctly.

MATLAB - stacked bar plot with negative value in GUI

I need to make stacked bar plot with my data to look like this:
Graph1
My data set:
data1 = [0 0 3.16 25.08 46.87 57.97 39.25 28.81 10.63 0.06 0 0]
data2 = [74.00 152.68 319.99 514.05 635.73 647.61 645.32 569.51 398.48 226.13 84.88 52.08]
data3 = [628.07 497.66 426.97 285.56 220.67 184.04 212.71 239.93 318.25 451.61 545.02 626.39]
If I make it like this:
x = 1:12;
y = [data2' data1' data3'];
bar(handles.axes1,x,y,'stacked')
It looks like this:
Graph2
So I need to green part be like negative values on the first graph (blue values)
If I do it like this in classic workspace:
x = 1:12;
y1 = [data2' data3'];
bar(x,y1,'stacked')
hold on
bar(x, -data1, 'g')
hold off
It looks as I want, but if I do it this way in GUI
x = 1:12;
y1 = [data2' data3'];
bar(handles.axes1,x,y1,'stacked')
hold on
bar(handles.axes1,x, -data1, 'g')
hold off
Only negative values are plotted.
Thank you for advice.
All you need is specifying the handle you are operating with in hold
clear;clc;close all
data1 = [0 0 3.16 25.08 46.87 57.97 39.25 28.81 10.63 0.06 0 0]
data2 = [74.00 152.68 319.99 514.05 635.73 647.61 645.32 569.51 398.48 226.13 84.88 52.08]
data3 = [628.07 497.66 426.97 285.56 220.67 184.04 212.71 239.93 318.25 451.61 545.02 626.39]
x = 1:12;
y1 = [data2' data3'];
ax = axes;
figure % some other figures that interferes gcf()
bar(ax,x,y1,'stacked')
hold(ax,'on')
bar(ax,x, -data1, 'g')
hold(ax,'off')

Convert matlab line plot to stl

I'm trying to output Voronoi cells to a format which can be used for 3D printing.
MATLAB generates voronoi cells from lists of X and Y coordinates. My script generates such a list of points, but getting to a format I can export is seeming problematic.
My main hopes lie with stlwrite, http://www.mathworks.com/matlabcentral/fileexchange/20922-stlwrite-write-binary-or-ascii-stl-file
This function/script requires a surface to export.
function [lines, LineData, pOut] = makeSurfaceFromVorVerts(Lx, Ly, varargin)
p = inputParser;
addRequired(p,'Lx',...
#(x) (isequal(class(x),'double') && isequal(size(x,1),2)));
addRequired(p,'Ly',...
#(x) (isequal(class(x),'double') && isequal(size(x,1),2)));
defaultResolution = 100;
addOptional(p,'Resolution',defaultResolution,...
#(x) (isequal(class(x),'double') && isequal(size(x),[1 1])));
defaultBoundary = [0 110; 0 110];
addOptional(p,'Boundaries',defaultBoundary,...
#(x) (isequal(class(x),'double') && isequal(size(x),[2 2])));
parse(p,Lx,Ly,varargin{:});
pOut = p;
LX = p.Results.Lx;
LY = p.Results.Ly;
Bounds = p.Results.Boundaries;
% Strip high values
reducedXdat = [];
reducedYdat = [];
for i=1:size(LX,2)
if LX(1,i) > Bounds(1,1) && LX(1,i) < Bounds(1,2) && ... % X value of start of line
LX(2,i) > Bounds(2,1) && LX(2,i) < Bounds(2,2) && ... % Y value of start of line
LY(1,i) > Bounds(1,1) && LY(1,i) < Bounds(1,2) && ... % X value of end of line
LY(2,i) > Bounds(2,1) && LY(2,i) < Bounds(2,2), % Y value of end of line
reducedXdat = [reducedXdat, LX(:,i)];
reducedYdat = [reducedYdat, LY(:,i)];
end
end
% Initialise a grid of points
%sXnew = (Bounds(1,2) - Bounds(1,1)) * p.Results.Resolution;
%sYnew = (Bounds(2,2) - Bounds(2,1)) * p.Results.Resolution;
%Z = zeros(sXnew, sYnew,'uint8');
%for x=1:size(X,1)
% for y=1:size(Y,1)
% nX = floor(X(x)*p.Results.Resolution);
% nY = floor(Y(y)*p.Results.Resolution);
% Z(nX,nY) = 1;
% end
%end
%surface = Z;
%coords = [X,Y];
lines = line(reducedXdat,reducedYdat);
LineData = [reducedXdat; reducedYdat];
end
My processing script, above, takes the points generated by the command
[Lx, Ly] = voronoi(xValuesOfCellCentres, yValuesOfCellCentres);
along with an optional 'boundary' matrix (there's also a check for resolution, for the commented section) and then outputs lines.
I would like these lines to form the surface. I considered creating a mesh using a binary Z value (1 for points, 0 for everywhere else), but I don't know how I could also include the positions between points, ie those covered by the lines.
I expect that there is some relevant middle step I can take, to create a frame based on extrusion of the lines drawn (either by this script, which has cut away the extra lines to infinity, or by voronoi(X,Y), but I can't work it out.
Found a way to do this.
Changed the script, new script is pasted at the bottom.
Workflow goes:
Matlab (create line plot, then for i=1:size(lineHandles,1), set(lineHandles(i),'lineWidth',4),end). Change the line width as required.)
Save as .png file.
Gimp (crop file to a nice rectangle)
InkScape (open png file, click image, menu Path -> Trace Bitmap -> Color Quantization (2 colors) -> Drag the path aside (it shows path in the status bar at the bottom when you have this selected). Click image and delete. Place path (with nodes) back onto the page (there's an x/y coordinates setting in a toolbar at the top, set these both to 0.
Save as a .dxf file. To get these to input more nicely, use the extension provided at http://www.thingiverse.com/thing:14221. This should be installed by copying the .py and .inx files to /usr/share/inkscape/extensions (or similar)
Open in OpenSCAD using the command import("/path/to/filename.dxf");
This object can be extruded using the linear_extrude(height = x) where x is a height in mm (other lengths probably configurable)
Render using CGAL (F6 is the shortcut for this in OpenSCAD.)
Export to .stl file (menu Design > Export as STL...)
MATLAB script (edit as needed and take outputs as required, if you want the line handles you'll need to put in almost all of the output arguments (or reorder them):
%voronoiScriptHex generates voronoi cells in a hexagonal tesselation grid
% [X, Y, Fig, Axis, Lx, Ly, lH, lD] = voronoiScript(Bnd, Spc, D, ...)
%
% Output variables
% X is the x coordinate of the voronoi cell centres
% Y is the y coordinate of the voronoi cell centres
% Fig is the handle of the figure generated
% Axis is the handle of the axes used
% Lx gives the start and end x coordinates of the voronoi lines
% Ly gives the start and end y coordinates of the voronoi lines
% lH is the set of handles for the voronoi lines
% lD is constructed from [Lx; Ly], it is a [4 by Length] array
%
% Bnd specifies the boundaries for the region to be covered. It should be
% either one number, or a pair of numbers in a [1x2] vector, specifying
% [maxX, maxY]. 0 is taken as the minimum value.
%
% Spc specifies the average spacing. For a hex grid, it only accepts one
% value.
%
% D specifies the variation from a uniform grid. It is multiplied by a
% random number between -0.5 and 0.5 and added to the [x,y] coordinates
% of a point. If size(D) = [1x2], then the values are for [Dx, Dy].
%
% Optional arguments can be used to place some points exactly on the grid
% they would lie on with D[x/y] = 0. The first should be 'PartFixed' -
% this is a boolean and if true, some points are fixed to the grid.
%
% The second argument is 'FractionFixed'. This is an integer value
% (double class variables are accepted, but floor(arg) must be equal to
% (arg)). It specifies inversely how often points should be fixed, eg a
% value of 1 fixes every point, whilst a value of 5 fixes 1/5 of the
% points.
%
% PlotScatter is another boolean value, which sets if a scatter plot of
% the X,Y values corresponding to the cell centres should be included in
% the figure.
function [X, Y, Figure, Axis, Lx, Ly, lineHandles, lineData] = ...
voronoiScriptHex(Boundary, Spacing, Delta, varargin)
p = inputParser;
p.FunctionName = 'voronoiScript';
addRequired(p, 'Boundary', #checkTypes);
addRequired(p, 'Spacing', #isnumeric);
addRequired(p, 'Delta', #checkTypes);
defaultPart = false;
addOptional(p, 'PartFixed', defaultPart, #islogical);
defaultFraction = 2;
addOptional(p, 'FractionFixed', defaultFraction, #isAnInt);
defaultScatter = false;
addOptional(p, 'PlotScatter', defaultScatter, #islogical);
parse(p, Boundary, Spacing, Delta, varargin{:});
% Get values for boundaries and delta
% (Can be vectors or scalars)
if isequal(size(p.Results.Boundary),[1,2])
% Boundary is a vector [maxX, maxY]
BoundaryY = p.Results.Boundary(1,2);
else
BoundaryY = p.Results.Boundary(1,1);
end
if isequal(size(p.Results.Delta),[1,2])
% Delta is a vector [dX, dY]
DeltaY = p.Results.Delta(1,2);
else
DeltaY = p.Results.Delta(1,1);
end
Spacing = p.Results.Spacing;
BoundaryX = p.Results.Boundary(1,1);
DeltaX = p.Results.Delta(1,1);
D1 = [2*Spacing*cosd(30), Spacing];
numP = [ceil(BoundaryX/D1(1,1)) ceil(BoundaryY/D1(1,2))];
D2 = D1 ./ 2;
% Create the values
counter = 1;
xList(numP(1,1)*numP(1,2)) = 0;
yList(numP(1,1)*numP(1,2)) = 0;
for x=1:numP(1,1)
for y = 1:numP(1,2)
xList(counter) = (getPointValue(x, D1(1,1), DeltaX)-D2(1,1));
xList(counter+1) = getPointValue(x, D1(1,1), DeltaX);
yList(counter) = (getPointValue(y, D1(1,2), DeltaY)-D2(1,2));
yList(counter+1) = getPointValue(y, D1(1,2), DeltaY);
counter = counter + 2;
end
end
% Set some of the points to be without random change
if (p.Results.PartFixed),
for counter=1:p.Results.FractionFixed:size(xList,2),
[x, y] = getXYfromC(counter, numP(1,2));
xList(counter) = x*Spacing;
yList(counter) = y*Spacing;
end
end
X = xList;
Y = yList;
% Set manual ticks for the figure axes
ticksX = zeros(1,numP(1,1)+1);
for i=1:numP(1,1)+1,
ticksX(i) = i*D1(1,1);
end
ticksY = zeros(1,numP(1,2)+1);
for i=1:numP(1,2)+1,
ticksY(i) = i*D1(1,2);
end
BoundCoeff = 1.08;
Bounds = [0 BoundCoeff*BoundaryX; 0 BoundCoeff*BoundaryY];
% Give the figure a handle that is returned, and set axes values
Figure = figure;
Axis = axes;
axis equal;
minor = 'off';
gridtoggle = 'off';
set(Axis,'XTickMode','manual','YTickMode','manual', ...
'XGrid',gridtoggle,'YGrid',gridtoggle, ...
'XMinorGrid',minor,'YMinorGrid',minor, ...
'XTick',ticksX,'YTick',ticksY, ...
'XMinorTick',minor,'YMinorTick',minor, ...
'XLim',[0 Bounds(1,2)],'YLim',[0 Bounds(2,2)]);
%set(Axis,'XLim',[0 Bounds(1,2)],'YLim',[0 Bounds(2,2)]);
% Create the voronoi cells, returning the line points
[Lx, Ly] = voronoi(X,Y);
% Strip high values
counter = 1;
reducedXdat = zeros(2,size(Lx,2));
reducedYdat = zeros(2,size(Lx,2));
for i=1:size(Lx,2)
if Lx(1,i) > Bounds(1,1) && Lx(1,i) < Bounds(1,2) && ... % X value of start of line
Lx(2,i) > Bounds(2,1) && Lx(2,i) < Bounds(2,2) && ... % Y value of start of line
Ly(1,i) > Bounds(1,1) && Ly(1,i) < Bounds(1,2) && ... % X value of end of line
Ly(2,i) > Bounds(2,1) && Ly(2,i) < Bounds(2,2), % Y value of end of line
reducedXdat(:,counter) = Lx(:,i);
reducedYdat(:,counter) = Ly(:,i);
counter = counter + 1;
end
end
Lx = reducedXdat(:,1:counter-1);
Ly = reducedYdat(:,1:counter-1);
% Plot the voronoi lines
lineHandles = line(Lx, Ly);
% Set colours to black
if (1)
for i=1:size(lineHandles,1)
set(lineHandles(i),...
'LineWidth',3, ...
'LineSmoothing','on', ...
'Color',[0 0 0]);
end
end
lineData = [Lx; Ly];
if (p.Results.PlotScatter)
hold on;
scatter(X,Y);
end
end
function bool = checkTypes(arg)
bool = (isequal(class(arg),'double') && ...
(isequal(size(arg),[1,1]) || isequal(size(arg),[1,2])));
end
function bool = isAnInt(arg)
bool = (isequal(floor(arg),arg) && ...
isequal(size(arg),[1,1]) && ...
isnumeric(arg));
end
function val = getPointValue(intV, spacing, delta)
val = (((rand(1)-0.5)*delta)+(intV*spacing));
end
function [x,y] = getXYfromC(counter, sizeY)
x = floor(counter/sizeY)+1;
y = counter - ((x-1)*sizeY);
end
SCAD script file to place the voronoi cells within a pair of cylinders for 3D printing a grid. Edit as needed with path, or changes to shapes etc:
$fn = 360;
inkFile = "/path/to/my/file";
scl = 1.05; // Scale variable
transVec = [-100, -98, 0]; // Move the imported image pattern so that it's centred.
union(){
makeRing([0,0,3],inR=96, outR=99, height=6);
makeRing([0,0,1.5], inR=99, outR=102, height=3);
intersection() {
#linear_extrude(height = 6.05, convexity=40, center=false) // Removing the # will get rid of the overlay, which helps see where the grid is.
scale([scl, scl, 1])
translate(transVec)
import(inkFile);
makeCylinder([0,0,3], 96, 6, $fn=360);
}
}
module makeCylinder(centre, radius, height) {
translate(centre){
cylinder(h = height, r = radius, center=true);
}
}
module makeRing(centre,inR, outR, height) {
difference() {
makeCylinder(centre, outR, height);
makeCylinder(centre, inR, height+0.1);
}
}