I want to display an image onto a cube. The original image should not be changed, neither in size, nor in color.
The code is as follows:
cdata = flip( imread('1234.jpg'), 1 );
% imshow(cdata)
cdatar = flip( cdata, 2 );
% bottom
surface([-1 1; -1 1], [-1 -1; 1 1], [-1 -1; -1 -1], ...
'FaceColor', 'texturemap', 'CData', cdatar );
% top
surface([-1 1; -1 1], [-1 -1; 1 1], [1 1; 1 1], ...
'FaceColor', 'texturemap', 'CData', cdata );
% font
surface([-1 1; -1 1], [-1 -1; -1 -1], [-1 -1; 1 1], ...
'FaceColor', 'texturemap', 'CData', cdata );
% back
surface([-1 1; -1 1], [1 1; 1 1], [-1 -1; 1 1], ...
'FaceColor', 'texturemap', 'CData', cdatar );
% left
surface([-1 -1; -1 -1], [-1 1; -1 1], [-1 -1; 1 1], ...
'FaceColor', 'texturemap', 'CData', cdatar );
% right
surface([1 1; 1 1], [-1 1; -1 1], [-1 -1; 1 1], ...
'FaceColor', 'texturemap', 'CData', cdata );
% E1 = 24;
% for z = 0:360
% view(z,E1)
% pause(0.1)
% end
view(3);
This is the image I want to display:
The color has been changed and and the image resized:
How can I display this image on the cube without resizing or changing color?
You explicitly plot your image on the range [-1 1] on every axis, i.e. it's a perfect cube. Having your image on a face of a cube will be a square, whereas your image is a rectangle. Either don't use a cube to plot it on, or zero-pad the sides to make it appear only in the middle. Calculate the ratio of your image, retain the height, pad (height-width)/2 zeros (or ones, depending on the desired colour) on both sides to end up with a square matrix.
MATLAB used the default colour map, parula. Given you have a binary image, the easiest would be to define a colour map as:
% You might need to flip zeros and ones for the colours
my_colur_map = [0 0 0 ; 1 1 1];
figure;
surface(...)
colormap(my_colour_map)
In other words: create a custom colour map with only two colours: black and white.
Related
How can I find the centroid of left and right side part of ellipsoid to cross section plane. Here is the code.
[x,y,z]=ellipsoid(0,0,0,0.5,1,0.25,50);
direction = [1 0 0];
figure
h=surfl(x,y,z);
set(h,'facealpha',0.5)
shading interp
xlabel('x')
ylabel('y')
zlabel('z')
hold on
s=patch([1 -1 -1 1], [1 1 -1 -1], [0 0 0 0]) ;
rotate(s,direction,120)
Is there a way to vectorize/accelerate the task of plotting multiple lines with different colors?
The working-but-slow approach is
X = [1 2; 3 4];
Y = [2 -4; 5 2];
figure;
hold on;
colors = [1 0 0; 0 1 0];
for idx = 1:size(X, 2)
l = plot(X(:, idx), Y(:, idx), 'Color', colors(idx, :));
end
hold off;
I tried
X = [1 2; 3 4];
Y = [2 -4; 5 2];
figure;
plot(X, Y, 'Color', [1 0 0; 0 1 0]);
but no luck.
This is probably too hacky to be a useful replacement of the loop, but here it goes:
set(gca, 'ColorOrder', [1 0 0; 0 1 0], 'NextPlot', 'add')
plot(X, Y);
The 'ColorOrder' property contains the colors to be used by default for new plots. Setting 'NextPlot' to 'add' seems to be necessary so that the call to plot doesn't reset 'ColorOrder' to its default value.
Tested on R2015b.
Below is some code that recreates my problem as simplified as I can make it. It does a subplot with two plots, you'll notice the plot on the right (contour only) has the correct correlation between the contour colors and the color bar but when a surface is added (left plot) the colors no longer match up.
Notes:
I've tried contourslice but I get the same results. I've posted the code for that below too.
How far off the colors are seems to depend on the values of the contour data itself. If you replace my contour data with peaks, it works fine. However this does not solve the underlying problem.
Code using contour:
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
%make contour data
[x,y] = meshgrid(-1:.5:1,-1:.5:1);
con = (x.^2+y.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contour(x,y,con) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,con)
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Code using contourslice instead of contour (same problem)
clear all; close all; clc
%define box coordinates
bx = [0 1 1 0 0;0 1 1 0 0]-.5;
by = [0 0 1 1 0;0 0 1 1 0]-.5;
bz = [0 0 0 0 0;1 1 1 1 1]-.5;
x = -1:.5:1;
y = x;
z = x;
%make contour data
[xg,yg,zg] = ndgrid(x,y,z);
V = 3-(xg.^2+yg.^2+zg.^2);
figure(1)
subplot(1,2,1)
box = surf(bx,by,bz); %draw box
set(box,'FaceColor',[1 1 1],'FaceAlpha',1,'EdgeAlpha',0,'EdgeColor',[.5 .5 .5])
hold on
camlight(30,70)
contourslice(x,y,z,V,[],[],0) %draw contour
colorbar
axis([-1 1 -1 1 -1 1])
axis equal
subplot(1,2,2)
contour(x,y,V(:,:,3))
axis([-1 1 -1 1])
axis equal
colorbar
set(gcf,'outerposition',[150 150 800 300])
Thanks for your help!
Just set the caxis property as you wish:
colorbar
caxis([0 2])
...
colorbar
caxis([0 2])
The problem was probably caused, because the surf plot changed the color determining values of your plot. By setting a fixed color axis you can avoid all misinterpretations.
Consider the rectangle formed by the vertices (0, 0), (0, 10), (1, 10), and (1, 0). How would I shade it red in MATLAB?
Note. For some reason, none of the mentioned shadings here works.
You can do that for example with patch:
vertices = [0 0; 0 10; 1 10; 1 0];
patch(vertices(1:end,1), vertices(1:end,2), [1 .2 .2], 'edgecolor', [0 0 0]);
%// [1 .2 .2] is light red for the fill; [1 1 1] is black for the edge
axis([-1 2 -10 20]); %// set axis limits to properly see rectangle
I have a 2D binary matrix that I want to display as a black and white plot. For example, let's say I have a 4-by-4 matrix as follows:
1 1 0 1
0 0 1 0
1 1 0 1
1 0 0 0
How can this be plotted as a black and white matrix? Some of my input binary matrices are of size 100-by-9, so I would ideally need a solution that generalizes to different sized matrices.
If you want to make a crossword-type plot as shown here (with grid lines and black and white squares) you can use the imagesc function, a gray colormap, and modify the axes properties like so:
mat = [1 1 0 1; 0 0 1 0; 1 1 0 1; 1 0 0 0]; % Your sample matrix
[r, c] = size(mat); % Get the matrix size
imagesc((1:c)+0.5, (1:r)+0.5, mat); % Plot the image
colormap(gray); % Use a gray colormap
axis equal % Make axes grid sizes equal
set(gca, 'XTick', 1:(c+1), 'YTick', 1:(r+1), ... % Change some axes properties
'XLim', [1 c+1], 'YLim', [1 r+1], ...
'GridLineStyle', '-', 'XGrid', 'on', 'YGrid', 'on');
And here's the image you should get:
I'm not sure if I got your question right, but you may try the image function, like this:
A = [ 1 1 0; 1 0 1; 1 1 1 ];
colormap([0 0 0; 1 1 1 ]);
image(A .* 255);
Try the spy function to start with perhaps.