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
    s = add_shadow(t,l,'Color',bg_color*0.8,'BackgroundColor',bg_color,'Fade','infinite');
  case 10
    apply_ambient_occlusion(t,'AddLights',false,'SoftLighting',false);
  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

matlab plot line colors

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)';

matlab plot line colors

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

Correlation does not imply causation

http://alecjacobson.com/art/digital

http://alecjacobson.com/art/

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:
quiver plot of trig function

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:
plot of trig function as lines

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:
arrows for vector field in illustrator

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:
mismatching axis in matlab due to colorbar

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:
mismatching axis in matlab due to colorbar

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:
java.io.IOException: Can't read /Applications/MATLAB_R2011b.app/sys/fonts/ttf/cm/mwa_cmss10.ttf
	at java.awt.Font.createFont(Font.java:978)
	at com.mathworks.hg.util.FontConverter.loadTexFontSecondAttempt(FontConverter.java:254)
	at com.mathworks.hg.util.FontConverter.loadTexFont(FontConverter.java:218)
	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');