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?).
Related
I am using subplot() and pcolor(zeros(7,7)); to produce the following figure for a battleship game (please see link below). Im trying to change the color of specific grids to represent ships, but I can't figure it out, so can I please get help with this, I need to for example change grids 22 and 23 in "your board" to red and have the existing figure updated, not get a new figure.
It's easiest if you set up a function to create/colour a specific square, then this is trivial, and can be recycled throughout your game. Below I've made the local function drawSquare(bs,N,player,color) which accepts a board size (bs), square number (N), a player ('top' or 'bottom'), and a colour, which can be any valid MATLAB colorspec.
Then I've made another function setup(bs) which calls this a bunch of times to create the "board" for each player.
Then you can see it's as simple as calling drawSquare( bs, 3, 'top', 'r' ); to turn the top player's square number 3 red.
Equally it's easy to call drawSquare( bs, 4, 'top', [0.6,0.5,0.5] ); to colour square 4 for that player a grey-ish tone to show something like a "hit" square in the battleships game.
figure(100);
bs = 6; % board size
% Initialise the board
setup( bs );
% Example usage colouring in specific squares
drawSquare( bs, 3, 'top', 'r' )
drawSquare( bs, 4, 'top', [0.6,0.5,0.5] );
function setup( bs )
clf; % clear the board
for ii = 1:(bs^2)
% Loop over all squares, make the base boards
drawSquare( bs, ii, 'top', 'w' );
drawSquare( bs, ii, 'bottom', 'w' );
end
% Format the plots without ticks and with titles
subplot( 2, 1, 1 );
set( gca, 'XTickLabel', '', 'YTickLabel', '', 'BoxStyle', 'full' );
title( 'Computer Board' );
subplot( 2, 1, 2 );
set( gca, 'XTickLabel', '', 'YTickLabel', '', 'BoxStyle', 'full' );
title( 'Your Board' );
end
function drawSquare( bs, N, player, color )
% sq = square size, N = square number, player = 'top' or 'bottom'
% color = valid plot colour for different square types
x = mod(N-1,bs); % x axis in grid
y = floor( (N-1)/bs ); % y axis in grid
if strcmpi( player, 'top' )
subplot( 2, 1, 1 ); % top player is subplot 1
x = bs - x; % top player square 1 is bottom-right
else
subplot( 2, 1, 2 ); % bottom player is subplot 2
y = bs - y; % bottom player square 1 is top-left
end
xp = [x, x+1, x+1, x]; % x coordinates of grid square
yp = [y, y, y+1, y+1]; % y coordinates of grid square
patch( xp, yp, color ); % use patch to make coloured square
text( x+(1/2), y+(1/2), num2str(N), 'HorizontalAlignment', 'center' );
end
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 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 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)