## Posts Tagged ‘plot’

### Paper-worthy rendering in MATLAB

Thursday, July 20th, 2017

MATLAB is not a great tool for creating 3D renderings. However, the learning curves for most commercial rendering tools are quite steep. Other tools like Mitsuba can create beautiful pictures, but can feel quite cumbersome for rendering pure geometry rather than the physical scenes their designed for.

Over the years, I’ve developed a way of creating plots of 3D shapes in MATLAB using a few extra functions in gptoolbox. This started as a way to just make images from research prototypes more palatable, but eventually became the usual way that I render images for papers. If the code for my research is already written in MATLAB then one huge advantage is that every image in my paper can have a *.m script that deterministically generates the result and the corresponding image with user intervention. This helps with reproducibility, editing and sharing between collaborators.

Here’s a “VFX Breakdown” of rendering a 3D shape in MATLAB.

t = tsurf(F,V);
set(gcf,'COlor',0.94*[1 1 1]);
teal = [144 216 196]/255;
pink = [254 194 194]/255;
bg_color = pink;
fg_color = teal;
for pass = 1:10
switch pass
case 1
% blank run
axis([-209.4       119.38      -181.24       262.67      -247.28 247.38]);
case 2
axis equal;
axis([-209.4       119.38      -181.24       262.67      -247.28 247.38]);
axis vis3d;
case 3
t.EdgeColor = 'none';
case 4
set(t,fphong,'FaceVertexCData',repmat(fg_color,size(V,1),1));
case 5
set(t,fsoft);
case 6
l = light('Position',[0.2 -0.2 1]);
case 7
set(gca,'Visible','off');
case 8
set(gcf,'Color',bg_color);
case 9
case 10
end

vidObj = VideoWriter(sprintf('nefertiti-%02d.mp4',pass),'MPEG-4');
vidObj.Quality = 100;
vidObj.open;
thetas = linspace(30,-30,450);
for theta = thetas(1:end-1)
view(theta,30);
drawnow;
vidObj.writeVideo(getframe(gcf));
end
vidObj.close;

end


### Plot a bunch of edges in matlab with per-edge color data

Monday, December 19th, 2016

Suppose you have a list of vertices V (#V by dim) and a list of edges E (#E by 2) indexing V, then one hacky to draw all of these edges with per-vertex color data DV (#V by 1) is to use trisurf:

trisurf(E(:,[1 1 2]),V(:,1),V(:,2),V(:,3),'CData',DV,'EdgeColor','interp');


However, if you try to use this trick to draw per-edge color data DE (#E by 1), you’ll find that 'EdgeColor','flat' does not work. Instead you can explode you compact “mesh” of edges into individual edges and repeat you edge color data for each edge point:

trisurf(reshape([1:size(E,1),1:size(E,1)*2],[],3),V(E(:),1),V(E(:),2),V(E(:),3),'CData',repmat(DE,2,1),'EdgeColor','interp');


### Retrieve matlab plot colors

Tuesday, August 4th, 2015

I couldn’t find any documentation about where the plot line colors are stored or how to access them. Here’s a hacky way to retrieve them. Currently plot cycles through 7 colors:

p = plot(repmat(1:7,2,1));
plot_colors = reshape([p.Color],3,7)';


Update:

The correct way as Daniele writes in the comments is:

get(groot,'defaultAxesColorOrder')


### Enlarge matlab axis by a specific factor

Tuesday, April 8th, 2014

Here’s the code I use to double or enlarge the axis of a plot window by any factor. Say 150%:

a = axis;
axis(a+1.5*[a(1:2)-(a(1)+a(2))*0.5 a(3:4)-(a(3)+a(4))*0.5]);


### Speed up slow scatter and line plots in MATLAB

Tuesday, February 4th, 2014

Matlab seems to default to its CPU renderer 'painters' when creating new figures with scattered dots or lines. So

plot3(X,Y,Z);


where X and so on are very large can take a long time (say 1 minute).

Whereas first setting the renderer to the GPU renderer 'OpenGL' is much faster.

set(gcf,'Renderer','OpenGL');
plot3(X,Y,Z);


for the same large X takes 6 seconds.

Awkwardly, plotting a bunch of (disconnected) line segments from vertices in N and edge indices in E in matlab using something like:

plot3([N(E(:,1),1) N(E(:,2),1)]',[N(E(:,1),2) N(E(:,2),2)]',[N(E(:,1),3) N(E(:,2),3)]','k');


or

line([N(E(:,1),1) N(E(:,2),1)]',[N(E(:,1),2) N(E(:,2),2)]',[N(E(:,1),3) N(E(:,2),3)]');


is much slower to render and interact with than to just draw a bunch of degenerate triangles using:

trisurf([E E(:,1)],N(:,1),N(:,2),N(:,3))


This has the added bonus that it seems to throw the renderer automatically in to ‘OpenGL’ mode.

### Correlation does not imply causation

Tuesday, November 26th, 2013

### Vector field with actual arrows

Sunday, August 11th, 2013

I recently discovered MATLAB’s quiver function which produces visualizations of vector fields. This function creates “arrows” using three line segments. This is fine for prototyping, but not great for making nice images.

Here’s an example using quiver:


[X,Y] = meshgrid(linspace(0,1,40),linspace(0,1,40));
U = sin(X*2*pi).*sin(Y*2*pi)+X;
V = sin(X*2*pi).*cos(Y*2*pi);
quiver(X,Y,U,V);
set(gca,'Visible','off')
set(gcf,'color','w')


which produces:

Here’s my updated pipeline for making nice images of vector field using MATLAB and Adobe Illustrator.

In Matlab:


% scale appropriately
s = 1e-1;
% plot just lines
plot([X(:) X(:)+s*U(:)]',[Y(:) Y(:)+s*V(:)]','-b');
set(gca,'Visible','off')
set(gcf,'color','w')


which produces:

Save this as an .eps file and open it with illustrator.

Inevitably, matlab will have saved much more than just the line segments. Clean it up a bit. Select one of the “dot” markers (especially visible if any of your lines were very small). Then choose Select > Same > Stroke Weight. This will select all dots. Then hit Delete.

Now select one of the line segments and choose Select > Same > Stroke Weight. This will select all line segments. Now choose an appropriate arrowhead. This will produce something like:

### Mismatching axis size of subplots due to colorbar

Sunday, April 21st, 2013

When using subplots and axis commands the colorbar command in matlab can mess up alignments:


subplot(1,2,1);
plot([0 100],[0 100]);
axis equal;
subplot(1,2,2);
plot([0 100],[0 100]);
axis equal;
colorbar


Produces:

A quick fix to get the fix axis to be the same size as the second is to use:


set(colorbar,'Visible','off');


So that


subplot(1,2,1);
plot([0 100],[0 100]);
axis equal;
set(colorbar,'Visible','off');
subplot(1,2,2);
plot([0 100],[0 100]);
axis equal;
colorbar


Produces:

### Sans-serif not supported in MATLAB text using latex interpreter

Thursday, September 6th, 2012

If I try to issue in MATLAB:


title('\textsf{sans-serif}','interpreter','latex');


I get the following error:


Warning: Font cmss10 is not supported.
Warning: Font cmss10 is not supported.
Font creation failed twice.
java.io.IOException when creating Font object
Using File /Applications/MATLAB_R2011b.app/sys/fonts/ttf/cm/mwa_cmss10.ttf to create font mwa_cmss10
File.exists(): false
File.length(): 0
Exception:
at java.awt.Font.createFont(Font.java:978)
at com.mathworks.hg.util.FontConverter.convertToJavaFont(FontConverter.java:169)
at com.mathworks.hg.uij.GraphicsContext.SetWindowFont(GraphicsContext.java:1039)
Caused by:
null
Warning: Could not set font mwa_cmss10


I fixed this by finding cmss10.ttf on the web. And copying on top of /Applications/MATLAB_R2011b.app/sys/fonts/ttf/cm/mwa_cmss10.ttf.

Then when I issue the above command I get the correct output and only a few warnings:


Warning: Font cmss10 is not supported.
Warning: Font cmss10 is not supported.


### Nabla (∇) in matlab plot title

Thursday, September 6th, 2012

I tried:


title('\nabla');


Which produces no errors or warnings on the terminal, but the title in the plot on my mac is just a little question mark in a black box: �
You can do a little better by switching to the latex interpreter, which unfortunately uses that smelly latex font


title('$\nabla$','interpreter','latex');