I am plotting my data as
%% Plot relative wrt to GT for each frame
XIndx_lsd = linspace(1,592, size( accu_RE_lsdSlam, 1 ) );
XIndx_my = linspace(1,592, size( accu_RE_my_method, 1 ) );
plot( XIndx_lsd, accu_RE_lsdSlam(:,5), 'r-.' )
hold on
plot( XIndx_my, accu_RE_my_method(:,5), 'b-' )
AX=legend( 'rel translation error for Kerl et al.', 'rel translation error for D-EA' );
xhand = xlabel( 'Frame#' );
yhand = ylabel( '||trans(E_i)||_2 (in mm)' );
axis( [1 600 0 16] );
set(gca,'FontSize', 78);
set(xhand,'fontsize',78)
set(yhand,'fontsize',78)
I am able to get large font size. My question is how to get a large symbol size. See marked figure below.
Using an older answer of mine, which suggests to actually replot the legend symbols,
plot( 0:10, 0:10, 'b-' ); hold on;
plot( 0:10, 10:-1:0, 'r-' ); hold on;
%// Legend Style
style = #(LineStyle,LineWidth) plot(0,0,LineStyle,'LineWidth',LineWidth,'visible','off')
AX = legend( [style('b-',20),style('r-',20)], {' Legend entry 2',' Legend entry 1'}, 'box','off' );
xlim([0 10]); ylim([0 10]);
xhand = xlabel( 'Frame#' );
yhand = ylabel( '||trans(E_i)||_2 (in mm)' );
set(gca,'FontSize', 28);
set(xhand,'fontsize',28)
set(yhand,'fontsize',28)
Related
I am making a frequency plot and I would like some help on tick labeling.
Here is what I have:
semilogx([200,1000,5000], [0,6,0]);
xlim([20 20000]);
sc = [20:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];
xticks(scale);
xticklabels(scale);
set(gca,'XMinorTick','Off')
grid on;
set (gca, "xminorgrid", "off")
xlabel('frequency (Hz)');
ylabel('dB');
How can I make all numbers from 1000 and upwards appear as 1K, 2K, 5K and so on?
How could I make the lines on 50,100,200,500,1K,2K,5K,10K appear thicker/more black?
Octave approach (probably works on matlab too though)
I wouldn't rely on latex trickery to do this to be honest.
Here is the way I usually do stuff like this.
Effectively, because the axis labels object is considered a single object, and you cannot split it into parts, the trick is to overlay an invisible, bare-minimum axes object defining only the labels you want, and treat those as you'd like (e.g. adjust its fontweight, fontsize, xcolor, etc etc).
H = semilogx([200,1000,5000], [0,6,0]);
A = gca();
B = axes();
subscale = [20:10:100,125:25:175];
scale = [subscale,subscale * 10,subscale * 100, 20000];
ScaleTextLabels = {};
for i = 1 : length( scale )
if scale(i) >= 1000, ScaleTextLabels{i} = sprintf("%dk", scale(i) / 1000 );
else, ScaleTextLabels{i} = num2str( scale(i) );
end
end
SpecialTickLabels = { '50', '100', '200', '500', '1k', '2k', '5k', '10k'};
ScaleIndices = 1 : length( ScaleTextLabels );
SpecialIndices = nthargout( 2, #ismember, SpecialTickLabels, ScaleTextLabels );
NormalIndices = setdiff( ScaleIndices, SpecialIndices );
set( A, 'xgrid', 'on', 'xlabel', 'frequency (Hz)', 'xlim', [20 20000] , 'xminorgrid', 'off', 'xminortick', 'off', 'xticklabel', ScaleTextLabels(NormalIndices), 'xtick', scale(NormalIndices) , 'ylabel', 'dB', 'gridlinestyle', ':', 'gridcolor', 'k', 'gridalpha', 0.5 );
set( B, 'xgrid', 'on', 'xlabel', '' , 'xlim', get( A, 'xlim' ), 'xminorgrid', 'off', 'xminortick', 'off', 'xticklabel', ScaleTextLabels(SpecialIndices), 'xtick', scale(SpecialIndices), 'ylabel', '' , 'color', 'none', 'fontsize', 12, 'fontweight', 'bold', 'position', get( A, 'position'), 'xcolor', [0,0,0], 'xscale', 'log', 'ylim', get( A, 'ylim'), 'ytick', [], 'gridlinestyle', '--', 'gridcolor', 'k', 'gridalpha', 0.8 );
This "layers of transparent axes objects" technique is very useful to keep in mind in general, it allows great flexibility when designing complex graphs. :)
In MATLAB
*I unfortunately could not yet find how to bold the specific lines
Adding the following code allows the ticks to converted to the new names/format suggested in part 1. For part 2 the best I could find out right now is bolding the specific numbers, unfortunately not the specific ticks/lines. Here \bf indicates which labels are to be bolded. All the names will correspond to the positions set originally by your axis vector scale. The last line in the code below indicates the replacement of the current axis, gca.
semilogx([200,1000,5000],[0,6,0]);
sc = [20:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];
Current_Axis = gca;
Current_Axis.XMinorTick = 'off';
xlabel('frequency (Hz)'); ylabel('dB');
xlim([20 20000]);
grid on;
X_Scale_Names = {'\bf20'; '30'; '40'; '\bf50'; '60';
'70';'80';'90';'\bf100';'125';'150';'175';'\bf200';'300';'400';
'500';'600';'700';'800';'900';'\bf1K';'1.25K';'1.5K';'1.75K';
'\bf2K';'3K';'4K';'\bf5K';'6K';'7K';'8K';'9K';'\bf10K';'12.5K';'15K';
'17.5K';'20K'};
To Adjust More Grid and Axis Properties:
Current_Axis = gca;
set(Current_Axis,'xtick',scale,'xticklabel',X_Scale_Names);
Current_Axis.LineWidth = 1;
Current_Axis.GridColor = 'k';
Current_Axis.GridAlpha = 0.5;
Ran using MATLAB R2019b
I did it like this:
semilogx([200,1000,5000], [0,6,0]);
xlim([20 20000]);
sc = [20:5:35,40:10:100,125:25:175];
scale = [sc,sc*10,sc*100, 20000];
xticks(scale);
xticklabels(scale);
set(gca,'XMinorTick','Off')
grid on;
set(gca,'gridlinestyle',':');
set(gca,'gridalpha',0.6);
set (gca, "xminorgrid", "off");
xg = [50,100,200,500,1000,2000,5000,10000]; #highlight grids
xx = reshape([xg;xg;NaN(1,length(xg))],1,length(xg)*3);
yy = repmat([ylim() NaN],1,length(xg));
line(xx,yy,'Color',[0.65,0.65,0.65]);
xlabel('frequency (Hz)');
ylabel('dB');
X_Scale_Names = {'\fontsize{11}\bf20'; '25'; '30';'35';'40'; '\fontsize{11}\bf50'; '60';
'70';'80';'90';'\fontsize{11}\bf100';'125';'150';'175';'\fontsize{11}\bf200';'250';'300';'350';'400';
'\fontsize{11}\bf500';'600';'700';'800';'900';'\fontsize{11}\bf1K';'1.25K';'1.5K';'1.75K';
'\fontsize{11}\bf2K';'2.5K';'3K';'3.5K';'4K';'\fontsize{11}\bf5K';'6K';'7K';'8K';'9K';'\fontsize{11}\bf10K';'12.5K';'15K';
'17.5K';'\fontsize{11}\bf20K'};
set(gca,'xtick',scale,'xticklabel',X_Scale_Names);
But I don't think this is the best/fastest/easiest way to do it...
Consider the following example:
[ X, Y, Z ] = peaks( 30 );
figure( 100 );
surfc( X, Y, Z );
zlabel( 'Absolute Values' );
colormap jet;
c = colorbar( 'Location', 'EastOutside' );
ylabel( c, 'Relative Values' );
The output looks as follows:
How can I scale the ticks on the colorbar, i.e. scale the c-axis (e.g. divide the values by 100):
without changing the z values and colors on the plot
without changing the colors on the colorbar
without changing the relation between the colors on the plot, the colors on the colorbar and the z values of the plot
while still using the full range of the colorbar
In the picture above, I would like to scale the c-axis such that it shows this values for the related z:
z | c-axis
----------
8 | 8/100
6 | 6/100
4 | 4/100
. | ...
The function caxis, as I understand it, is not suited here, as it would just show the colors for a subsection of the z-axis and not for the whole z-axis.
Bonus question: How could one scale the color mapping and the colorbar as a function of X, Y and/or Z?
[ X, Y, Z ] = peaks( 30 );
figure( 101 );
surfc( X, Y, Z );
zlabel( 'Absolute Values' );
%
Z_Scl = 0.01;
Z_Bar = linspace( min(Z(:)), max(Z(:)), 10 );
%
colormap jet;
c = colorbar( 'Location', 'EastOutside', ...
'Ticks', Z_Bar, 'TickLabels', cellstr( num2str( Z_Bar(:)*Z_Scl, '%.3e' ) ) );
ylabel( c, 'Relative Values' );
For an arbitrary mapping between the z-values and the colorbar, it is possible to combine surf, contourf and contour as follows (inspired by these two great answers):
[ X, Y, Z ] = peaks( 30 ); % Generate data
CB_Z = (sin( Z/max(Z(:)) ) - cos( Z/max(Z(:)) )).^2 + X/5 - Y/7; % Generate colormap
CF_Z = min( Z(:) ); % Calculate offset for filled contour plot
CR_Z = max( Z(:) ); % Calculate offset for contour plot
%
figure( 102 ); % Create figure
clf( 102 );
hold on; grid on; grid minor; % Retain current plot and create grid
xlabel( 'x' ); % Create label for x-axis
ylabel( 'y' ); % Create label for y-axis
zlabel( 'Scaling 1' ); % Create label for z-axis
surf( X, Y, Z, CB_Z ); % Create surface plot
%
CF_H = hgtransform( 'Parent', gca ); % https://stackoverflow.com/a/24624311/8288778
contourf( X, Y, CB_Z, 20, 'Parent', CF_H ); % Create filled contour plot
set( CF_H, 'Matrix', makehgtform( 'translate', [ 0, 0, CF_Z ] ) ); % https://stackoverflow.com/a/24624311/8288778
%
CR_H = hgtransform( 'Parent', gca ); % https://stackoverflow.com/a/24624311/8288778
contour( X, Y, CB_Z, 20, 'Parent', CR_H ); % Create contour plot
set( CR_H, 'Matrix', makehgtform( 'translate', [ 0, 0, CR_Z ] ) ); % https://stackoverflow.com/a/24624311/8288778
%
colormap jet; % Set current colormap
CB_H = colorbar( 'Location', 'EastOutside' ); % Create colorbar
caxis( [ min( CB_Z(:) ), max( CB_Z(:) ) ] ); % Set the color limits for the colorbar
ylabel( CB_H, 'Scaling 2' ); % Create label for colorbar
As I wrote in your answer, I think a better choice for showing two related values is not to create a new axis for that, but to show them one near the other. Here is a suggestion:
[X,Y,Z] = peaks(30);
surfc(X,Y,Z);
zlabel('Absolute (Relative) Values');
colormap jet
Z_Scl = 0.01;
zticks = get(gca,'ZTick');
set(gca,'ZTickLabel',sprintf('%g (%g)\n',[zticks;zticks.*Z_Scl]))
I created a plot with two data sets, in a primary and secondary Y axes, respectively, using
[ ha, hl1, hl2 ] = plotyy( xr, yr, xq, yq );
Then I formatted the lines with
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
and I finally created a common legend for both with
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
I guess it is not important the contents of ( xr, yr, xq, yq ). The two lines are correctly plotted, and each one on the correct axis.
The first line in the legend should have a (solid, blue) line, and
the second line should have a (dash, red) line.
The result is the opposite (see figure).
This is the same if I use
hl = legend( [ hl2, hl1 ], 'r', '\theta/\pi' );
and if I change the comma by a semicolon [ hl2; hl1 ].
What is the right way of doing it?
with octave-4.0.1-rc4, default graphics_toolkit ("qt"), the result seems fine.
x = linspace(0, 2*pi, 101);
[ha, hl1, hl2] = plotyy(x, sin(x), x, -sin(x));
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
Except the \theta/\pi is not correctly interpreted.
No need to file a bug report, since it has been solved in the development version.
But with 4.0.1 and graphics_toolkit("gnuplot") the plot is fine:
So it might be time to upgrade. Here are the ftp site and windows installers.
Using code like ederag's
x = linspace(0, 2*pi, 101);
[ha, hl1, hl2] = plotyy(x, sin(x), x, -sin(x));
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
I found out that adding the line
set( hl, 'fontsize', 20 );
after it inverts the lines in the legend. As far as I understand, this is unexpecetd (possibly a bug?).
I have a pretty simple MatLab code her that perfectly well plots 6 datapoints. The x coordinates from the dt list; the y coordinates from the TempTable table in row 7. It all works fine, I just need to join the points with a straight line.
% Plotting T_new(7) vs. dt
dt=[0.001,0.005,0.01,0.05,0.1,0.25] % The time steps
y=[300,320,330,340,345,350]
for i=1:1:6 % Looping through all temperature profiles
hold all;
plot( dt(i), y(i), 'b*-', 'LineWidth', 1);
title(['Temperatures at nodal point 7']);
xlabel( 'dt [s]' );
ylabel( 'T [\circC]' );
set( gca, 'LineWidth', 1 );
axis( [ dt(2)-0.1, dt(6)+0.1, 300, 350 ] );
pause( 0.1 ); % Animation step time
end
Shouldn't the dash - in b*- add these joining lines, or what? What is missing here, since they don't?
Your loop is your problem. With only one point plotted per iteration, it is impossible for Matlab to know what points to connect. So if you want to use a loop, you'll have to connect the points manually with another plot-statement.
A solution without a loop could be:
hold all;
plot( dt, TempTable(7,:), 'b*-', 'LineWidth', 1);
title(['Temperatures at nodal point 7']);
xlabel( 'dt [s]' );
ylabel( 'T [\circC]' );
set( gca, 'LineWidth', 1 );
axis( [ dt(2)-0.1, dt(6)+0.1, 300, 350 ] );
pause( 0.1 ); % Animation step time
I have 3 sets of 3D co-ordinates and I have fitted planes to each set. Now, I want to plot all the data points and the 3 planes in one figure.
So far, I have the following function:
function [fitresult, gof] = create_fit(xx, yy, zz, grp)
[xData, yData, zData] = prepareSurfaceData( xx, yy, zz );
ft = fittype( 'poly11' );
opts = fitoptions( ft );
opts.Lower = [-Inf -Inf -Inf];
opts.Upper = [Inf Inf Inf];
hold on;
% figure( 'Name', 'fit1' );
[fitresult, gof] = fit( [xData, yData], zData, ft, opts );
h = plot( fitresult, [xData, yData], zData);
if grp == 1
colormap(hot);
elseif grp == 2
colormap(cool);
else
colormap(grey);
end
legend( h, 'fit1', 'zz vs. xx, yy', 'Location', 'NorthEast' );
xlabel( 'xx' );
ylabel( 'yy' );
zlabel( 'zz' );
grid on
However, there are 2 problems with this:
The planes, when plotted individually are scaled according to the data points which are also plotted with them. When the planes are plotted together, they scale badly and the data points are converge to a small blob (very small scale compared to the planes)
I tried fixing the problem with axis([-0.04 0.04 -0.04 0.04 -0.04 0.04 -1 1]);, but it is hard coded and still looks a little off.
The colormap command seems to work only when called for the first time. Hence, all the planes turn out to be blue. How can I color each plane and the points fitted for that plane differently?
Is this the best way to plot multiple planes?
Edit
Here is an edited version of my initial answer. The output of plot is a two-element graphical object, so you have to call separately h(1) and h(2) to set the properties of the plane and of the data points.
Here is the code for the function:
function [fitresult, gof, h] = create_fit(xx, yy, zz, color)
[xData, yData, zData] = prepareSurfaceData( xx, yy, zz );
ft = fittype( 'poly11' );
opts = fitoptions( ft );
opts.Lower = [-Inf -Inf -Inf];
opts.Upper = [Inf Inf Inf];
hold on;
[fitresult, gof] = fit( [xData, yData], zData, ft, opts );
h = plot( fitresult, [xData, yData], zData);
set(h(1), 'FaceColor', color);
set(h(2), 'MarkerFaceColor', color, 'MarkerEdgeColor', 'k');
and here is a sample script that calls the function:
% Define sample data
N = 20;
x = rand(1,N);
y = rand(1,N);
z = rand(1,N);
% Call the function, specify color
[f1, gof1, h1] = create_fit(x, y, z, 'r');
[f2, gof2, h2] = create_fit(x, y.^10, z, 'g');
[f3, gof3, h3] = create_fit(x.^10, y, z, 'b');
% Figure adjustments
xlabel( 'xx' );
ylabel( 'yy' );
zlabel( 'zz' );
view(3)
grid on
xlim([min(x) max(x)]);
ylim([min(y) max(y)]);
zlim([min(z) max(z)]);
and the result: