# Making Pretty Graphs 101

Posted by **Loren Shure**,

Today I’d like to introduce a guest blogger, Jiro Doke (email: Jiro.Doke@mathworks.com), who is an applications engineer here at The MathWorks. He used MATLAB in his life prior to The MathWorks, and one of his

interests is data visualization.

### Contents

In my graduate work, I used MATLAB extensively for doing analysis and visualization. Often times, the plots that I created

were used for my publications. It was then when I started to explore the flexibility of Handle Graphics to customize MATLAB

plots in order to create publication-quality graphics. Ultimately, I was able to use MATLAB almost exclusively for my plots.

Let me walk you through the step-by-step process of how I did it. I'm using some fabricated data, but the plot is very similar

to the ones I generated for my research.

### Load Data

First you might download the data.

`load data`

### Create Basic Plot

First, I plot my data to create the crude visualization

figure('Units', 'pixels', ... 'Position', [100 100 500 375]); hold on; hFit = line(xfit , yfit ); hE = errorbar(xdata_m, ydata_m, ydata_s); hData = line(xVdata, yVdata ); hModel = line(xmodel, ymodel ); hCI(1) = line(xmodel, ymodelL); hCI(2) = line(xmodel, ymodelU);

### Adjust Line Properties (Functional)

Next, I do my first-round modification of my plots. At this point, I'm not worried about the esthetics yet.

set(hFit , ... 'Color' , [0 0 .5] ); set(hE , ... 'LineStyle' , 'none' , ... 'Marker' , '.' , ... 'Color' , [.3 .3 .3] ); set(hData , ... 'LineStyle' , 'none' , ... 'Marker' , '.' ); set(hModel , ... 'LineStyle' , '--' , ... 'Color' , 'r' ); set(hCI(1) , ... 'LineStyle' , '-.' , ... 'Color' , [0 .5 0] ); set(hCI(2) , ... 'LineStyle' , '-.' , ... 'Color' , [0 .5 0] );

### Adjust Line Properties (Esthetics)

To make it more publication-quality, I make the following changes to the line properties, including the errorbar widths. In

my opinion, using thicker lines and larger markers greatly improves the "look" of my graphics. It's quite subjective, but

I select them based on how much data is on the graph. I select the appropriate "crowdedness" (balance of dark and white space):

set(hFit , ... 'LineWidth' , 2 ); set(hE , ... 'LineWidth' , 1 , ... 'Marker' , 'o' , ... 'MarkerSize' , 6 , ... 'MarkerEdgeColor' , [.2 .2 .2] , ... 'MarkerFaceColor' , [.7 .7 .7] ); set(hData , ... 'Marker' , 'o' , ... 'MarkerSize' , 5 , ... 'MarkerEdgeColor' , 'none' , ... 'MarkerFaceColor' , [.75 .75 1] ); set(hModel , ... 'LineWidth' , 1.5 ); set(hCI(1) , ... 'LineWidth' , 1.5 ); set(hCI(2) , ... 'LineWidth' , 1.5 ); % adjust error bar width hE_c = ... get(hE , 'Children' ); errorbarXData = ... get(hE_c(2), 'XData' ); errorbarXData(4:9:end) = ... errorbarXData(1:9:end) - 0.2; errorbarXData(7:9:end) = .... errorbarXData(1:9:end) - 0.2; errorbarXData(5:9:end) = ... errorbarXData(1:9:end) + 0.2; errorbarXData(8:9:end) = ... errorbarXData(1:9:end) + 0.2; set(hE_c(2), 'XData', errorbarXData);

### Add Legend and Labels

No plot is complete unless it is well annotated.

hTitle = title ('My Publication-Quality Graphics'); hXLabel = xlabel('Length (m)' ); hYLabel = ylabel('Mass (kg)' ); hText = text(10, 800, ... sprintf('\\it{C = %0.1g \\pm %0.1g (CI)}', ... c, cint(2)-c)); hLegend = legend( ... [hE, hFit, hData, hModel, hCI(1)], ... 'Data (\mu \pm \sigma)' , ... 'Fit (\it{C x^3})' , ... 'Validation Data' , ... 'Model (\it{C x^3})' , ... '95% CI' , ... 'location', 'NorthWest' );

### Adjust Font and Axes Properties

Since many publications accept EPS formats, I select fonts that are supported by PostScript and Ghostscript. Anything that's

not supported will be replaced by Courier. I also define tick locations, especially when the default is too crowded.

set( gca , ... 'FontName' , 'Helvetica' ); set([hTitle, hXLabel, hYLabel, hText], ... 'FontName' , 'AvantGarde'); set([hLegend, gca] , ... 'FontSize' , 8 ); set([hXLabel, hYLabel, hText] , ... 'FontSize' , 10 ); set( hTitle , ... 'FontSize' , 12 , ... 'FontWeight' , 'bold' ); set(gca, ... 'Box' , 'off' , ... 'TickDir' , 'out' , ... 'TickLength' , [.02 .02] , ... 'XMinorTick' , 'on' , ... 'YMinorTick' , 'on' , ... 'YGrid' , 'on' , ... 'XColor' , [.3 .3 .3], ... 'YColor' , [.3 .3 .3], ... 'YTick' , 0:500:2500, ... 'LineWidth' , 1 );

### Export to EPS

I set `PaperPositionMode` to auto so that the exported figure looks like it does on the screen.

set(gcf, 'PaperPositionMode', 'auto'); print -depsc2 finalPlot1.eps close;

### Postprocess

This looks great! One thing that I may want to change is the way the dotted and dashed lines look. Notice that the dots are

too small. So, I wrote a simple function that goes into the EPS file and modifies the line definitions. I have posted the

function, `fixPSlinestyle`, on the File Exchange.

fixPSlinestyle('finalPlot1.eps', 'finalPlot2.eps');

And there you go. I have automated the process of creating publication-quality graphics. Handle Graphics give you advanced control of how graphics look. In case you didn't know, MATLAB allows you to quickly take a MATLAB script

and publish a formated report (HTML, Word, LaTeX, XML, PPT), where the figures are automatically converted to various graphics format,

including EPS. This document was created using `publish`.

### Your Examples

Tell us here about some of the cool things you do with Handle Graphics to make your figures look prettier.

Published with MATLAB® 7.5

**Category:**- Best Practice,
- Graphics,
- Less Used Functionality

### Note

Comments are closed.

## 101 CommentsOldest to Newest

**1**of 101

**2**of 101

**3**of 101

**4**of 101

**5**of 101

**6**of 101

**7**of 101

**8**of 101

**9**of 101

**10**of 101

**11**of 101

**12**of 101

**13**of 101

**14**of 101

**15**of 101

**16**of 101

**17**of 101

**18**of 101

**19**of 101

**20**of 101

**21**of 101

**22**of 101

**23**of 101

**24**of 101

**25**of 101

**26**of 101

**27**of 101

**28**of 101

**29**of 101

**30**of 101

**31**of 101

**32**of 101

**33**of 101

**34**of 101

**35**of 101

**36**of 101

**37**of 101

**38**of 101

**39**of 101

**40**of 101

**41**of 101

**42**of 101

**43**of 101

**44**of 101

**45**of 101

**46**of 101

**47**of 101

**48**of 101

**49**of 101

**50**of 101

**51**of 101

**52**of 101

`xlabel([’5 ‘,char(8240)])`

**53**of 101

**54**of 101

**55**of 101

**56**of 101

**57**of 101

**58**of 101

**59**of 101

**60**of 101

**61**of 101

**62**of 101

**63**of 101

**64**of 101

**65**of 101

`set(gcf, 'PaperPositionMode', 'auto')`

Then when you save, it will preserve the look of the figure on the screen.
@Ulla,
Thanks for your input. I will submit an enhancement request for error bar width. **66**of 101

**67**of 101

**68**of 101

**69**of 101

normplot(rand(1,1000)); ylab = {'0.001','','','','','','','0.50','','','','','','','0.999'}; set(gca, 'YTickLabel', ylab);Hope this helps. jiro

**70**of 101

**71**of 101

**72**of 101

**73**of 101

**74**of 101

legend text for line 1 legend text for line 2 ... line style for line 1 marker style for line 1 line style for line 2 marker style for line 2 ...With this in mind, you can change the marker size in the legend this way:

```
plot(rand(10, 4), '.');
[a,b,c,d] = legend('line1', 'line2', 'line3', 'line4');
set(b(6:2:end), 'MarkerSize', 20);
```

Hope this helps. **75**of 101

**76**of 101

**77**of 101

```
plot(rand(10,4))
set(gca, 'box', 'off');
set(gca, 'ytick', []);
set(gca, 'ycolor', get(gcf, 'color'));
print -depsc test.eps
```

**78**of 101

*switch to PDFLatex!!!*It will make your lives many times easier and your documents better looking. MATLAB's pdf generator (at least from the GUI) gives great results that are (best I can tell) 100% compatible with Adobe. This means you can open them directly in Illustrator (which saves as PDF with zero loss and stays vector!) and you can place them into your tex docs with no problem. I realize that many of you out there may be .eps devotees, but this solution is much more workable than the multiple saves many people describe. Plus, I find that I am able to get the plots much better looking this way, and then if they require subtle editing, I can do it in Illustrator. I guess the point I'm trying to make is that Latex (pdflatex that is) works great using just .pdf figures, and this is a great option because the .pdf format can store both vector and bitmap information (also, your text stays text this way, instead of rasterizing...), so I think it's the way to go. EPS people will say that .eps does the same thing, but not really, because look how much trouble it is to create a decent looking .eps from MATLAB. Not to mention the fact that .eps files aren't compatible with much at all and very few programs will open them. So, I'm just saying, save yourself time and effort, get a better quality graphic that many programs can open--it'll still be vector and you can avoid using 1980s technology.

**79**of 101

**80**of 101

plot(1:10, 1:10); set(gca,'XTickLabel','10^4');It produces 10^4 instead of 10 raised to the power of 5. I need this when chaning labels on a histogram. There no way in matlab do generate nice histograms of log binned data. Any suggestions? Martin

**81**of 101

**82**of 101

```
help quiver
doc quiver
```

you'll see some options to change the look for your quiver plot. **83**of 101

% Plot the first two sets of data ph1(1) = plot(xdata,y1,'-ko','DisplayName','Y1 Legend Text'); hold on ph1(2) = plot(xdata,y2,'-bs','DisplayName','Y2 Legend Text'); % Create the first legend lh1 = legend(ph1,'Location','NorthOutside','Orientation','horizontal'); lh1_position = get(lh1,'Position'); % Now set any axis properties that you want (Font, Ticks, etc) set(gca,'XLim',xlimits,'YLim',ylimits,'FontSize',18,'XTick',xticks,'YTick',yticks); % Name the first axis ax1 and create a second axis on top of the first ax1 = gca; ax2 = axes('Position',get(ax1,'Position')); % Plot the second two sets of data on ax2 ph2(1) = plot(xdata,y3,'-rd','DisplayName','Y3 Legend Text','Parent',ax2); hold on ph2(2) = plot(xdata,y4,'-g^','DisplayName','Y4 Legend Text','Parent',ax2); % Again set any axis properties that you want (Font, Ticks, etc) to make sure that the Legend fonts are the same set(ax2,'XLim',xlimits,'YLim',ylimits,'FontSize',18,'XTick',xticks,'YTick',yticks); % Now, link the first axis to the second and make the second invisible linkaxes([ax1 ax2],'xy'); set(ax2,'Color','none','XTick',[],'YTick',[],'Box','off'); % Now make the second legend just below the first lh2 = legend(ax2,ph2,'Orientation','horizontal'); lh2_position = lh1_position; lh2_position(2) = lh1_position(2)-lh2_position(4); set(lh2,'Position',lh2_position);This should basically get you what you want, which is a legend in a matrix form:

-o- Y1 Legend Text -s- Y2 Legend Text -d- Y3 Legend Text -^- Y4 Legend TextYou may have to play around with the legend positions and options a bit to get things to look exactly like you want - I just directly set my legend positions for each legend instead of automatically setting it as I did in the above example code. Anyways, since I spent so much time trying to get this right, figured I'd pass it on. Hope that works for others! Jeremy

**84**of 101

**85**of 101

**86**of 101

**87**of 101

**88**of 101

**89**of 101

fullscreen = get(0,'ScreenSize') figure('Position',[0 -50 fullscreen(3) fullscreen(4)])Note that my screen size is 1680 x 1050. Then I use the plot command, label axes, and finally print to an eps file.

plot(Ec,Pavg,'k*','MarkerSize',20) grid on xlabel('Energy Flux Density (dB re 1\muPa^2 s )','FontSize',44) ylabel('Average Detection Probability','FontSize',44) set(get(gca,'XLabel'),'Position',[165 0.0030 0]) set(gca,'FontSize',36) set(gcf,'PaperPositionMode','auto') print -depsc -loose sl_probdet_test4.epsIf I choose a font size of 20, for example, everything looks fine but the fonts appear rather small on the eps file. This is a big issue because the journal will further shrink the figures and no one will be able to read the labels! However if I increase the font size to a "decent" size in terms of appearance, then when printing to eps the x label appears clipped at the bottom. I have tried many different things but so far was not able to overcome this problem. I would really appreciate if anyone has any suggestions! Thanks Liz

**90**of 101

**91**of 101

**92**of 101

**93**of 101

set(0,'defaultLineMarker', 'o') X = 0:pi/10:pi; Y = sin(X); E = std(Y)*ones(size(X)); h = errorbar(X,Y,E); h2 = get(h, 'Children'); % Second handle is the handle to the error bar lines set(h2(2), 'Marker', 'none');

**94**of 101

**95**of 101

**96**of 101

**97**of 101

**98**of 101

**99**of 101

**100**of 101

**101**of 101

## Recent Comments