15

I have a problem like the one in this question concerning a tikz drawing but for a pgfplots plot. I want to create a plot that has one region filled without opacity and a neighboring one filled with opacity. The transparent region should be coated by a solid line. I managed to get pretty much what I want with this code:

\documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=1.3}

\usepackage{pgfplotstable} % For \pgfplotstableread
\usepgfplotslibrary{external}
\tikzexternalize

\usepackage{filecontents}

\begin{filecontents}{total.dos}
0  0  0  0  0   
1  2 -2  2 -2  
2  4 -4  4 -4  
3  2 -2  2 -2  
4  0  0  0  0 
5  1 -1  0  0 
6  2 -2  0  0 
7  1 -1  0  0 
8  0  0  0  0 
THIS WAS: TOTAL
\end{filecontents}

\pgfplotstableread[comment chars={T}]{total.dos}\total

\begin{document}

% Set a filename for the next tikzpicture.
\tikzsetnextfilename{total_dos} 

\begin{tikzpicture}
\begin{axis}[ymax=7, ymin=-7, xlabel={Energy [eV]}, ylabel={Intensity}, legend pos=north east]

\addplot [restrict x to domain=4:8, no markers, draw=red, fill=red, fill opacity=0.3] table [x=0, y expr=\thisrowno{2} - \thisrowno{4}] {\total}; \addlegendentry{$2-4$}

\addplot [restrict x to domain=4:8, no markers, draw=blue, fill=blue, fill opacity=0.3] table [x=0, y expr=\thisrowno{1} - \thisrowno{3}] {\total}; \addlegendentry{$1-3$}

\addplot [restrict x to domain=0:4, no markers, draw=blue , fill=blue] table [x=0, y=3] {\total}; \addlegendentry{$3$}

\addplot [restrict x to domain=0:4, no markers, draw=red, fill=red] table [x=0, y=4] {\total}; \addlegendentry{$4$}

\end{axis}
\end{tikzpicture}
\end{document}

This gives the following picture:

enter image description here

The problem is the intersections of the coating lines' ends (those that come from the draw=<color> options). They are not smooth, but look like this:

enter image description here

My question: How can I get these things smooth?

Side note: I know that using the option draw=none gives the behaviour I want, but then I have no line surrounding the transparent region.

Edit:

I have stumbled upon something interesting: Adobe Acrobat X and SumatraPDF seem to handle the plots slightly differently. Acrobat cuts off the parts of the rightmost line endings that loom beyond the plotting domain (I don't know a better word for it) while SumatraPDF doesn't. Interestingly, this doesn't happen for the line endings on the left or in the middle (see picture above, which was made with Acrobat).

enter image description here

I'm not sure why this is so and whether it affects the possible solutions to my problems. Maybe this is an issue worth adressing in a different question? Or is this a mere PDF viewer question which shouldn't be asked here?

Philipp
  • 3,815
  • Would line cap=round as an option to the \addplot commands do what you want? – Jake Jan 23 '12 at 00:19
  • Also the triangle 90 cap arrow from arrows library can increase the blend feel. – percusse Jan 23 '12 at 00:58
  • @Jake: This option does improve the situation at the ends of the plot (though it's still not yet the optimum) but the intersection in the middle becomes worse than before. – Philipp Jan 23 '12 at 01:22
  • @percusse: I'm pretty new to tikz and couldn't get your suggestion to work. I loaded \usetikzlibrary{arrows} in the preamble and tried to use the option line cap=triangle 90 cap after addplot but that didn't work. Was this all wrong? I expect it to look similar to line cap=round. But those are just workarounds. Will it be possible to make the lines really blend like in the tikz question I linked? – Philipp Jan 23 '12 at 01:32
  • @Philipp: Doing this properly is really hard. Take a look at http://tex.stackexchange.com/questions/10980/tikz-changing-colour-of-a-path-half-way-along/18717#18717 for some suggestions, but none of them are really the holy grail. – Jake Jan 23 '12 at 01:40
  • @Jake: Thanks for the link. Since I'm new to tikz I hadn't realized that this might be such a difficult question. Youthful naivety is wonderful, isn't it ;) – Philipp Jan 23 '12 at 01:54
  • 3
    Not to be rude but if you want to display the plot like the first picture is it not a bit 'overkill' to solve this minor issue? It is hardly visible with the naked eye in the first picture... – WG- Mar 09 '13 at 08:50
  • 3
    @WG-: It is admittedly a bit nit-picky, but I am quite a perfectionist when it comes to creating plots and documents. And apart from that I thought it to be an interesting problem whose solution might have helped me to learn more about how to do things with tikz and pgfplots in general. – Philipp Mar 31 '13 at 01:50
  • Based on the edit, this question might be related?: Incompatibility with TikZ and Mac OS X Preview Maybe not. I'm not totally sure if they're related, but I thought that I would at least mention it here. – Adam Liter Aug 09 '13 at 13:46

1 Answers1

2

Since draw = none gives the correct behavoir, we can simplify the problem. Use draw = none around the red and blue regions in the domain = 0:4. Now if we do line join = round, line width = .08pt, we can still see a border around dulled regions but we only have one connection of the lines to worry about. However, since we used line width = .08pt, it is very hard to notice anything when zoomed in at 1600%.

As you can see, we still have a border:

enter image description here

and zoomed at 1600% we see no issues with the connection:

enter image description here

Would this be an acceptable solution for you?


Option 2:

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows}
\begin{document}

\begin{tikzpicture}[]
  \begin{scope}
    \clip (0, 0) rectangle (8, 5);
    \filldraw[blue] (0, 0) -- (2, 4) -- (4, 0) -- cycle;
    \filldraw[blue, opacity = .3, draw = blue]
    (4, 0) -- (6, 2) -- (8, 0) -- cycle;
  \end{scope}

    \begin{scope}
    \clip (0, 0) rectangle (8, -5);
    \filldraw[red] (0, 0) -- (2, -4) -- (4, 0) -- cycle;
    \filldraw[red, opacity = .3, draw = red]
    (4, 0) -- (6, -2) -- (8, 0) -- cycle;
  \end{scope}
\end{tikzpicture}
\end{document}

Now all you need to do is draw the axis.

enter image description here

Then here is the intersection:

enter image description here


With darker outlines:

enter image description here

enter image description here

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows}
\begin{document}

\begin{tikzpicture}[]
  \begin{scope}
    \clip (0, 0) rectangle (8, 5);
    \filldraw[blue] (0, 0) -- (2, 4) -- (4, 0) -- cycle;
    \filldraw[blue, opacity = .3, draw = blue]
    (4, 0) -- (6, 2) -- (8, 0) -- cycle;
    \draw[blue] (4, 0) -- (6, 2) -- (8, 0);
  \end{scope}

    \begin{scope}
    \clip (0, 0) rectangle (8, -5);
    \filldraw[red] (0, 0) -- (2, -4) -- (4, 0) -- cycle;
    \filldraw[red, opacity = .3, draw = red]
    (4, 0) -- (6, -2) -- (8, 0) -- cycle;
    \draw[red] (4, 0) -- (6, -2) -- (8, 0);
  \end{scope}
\end{tikzpicture}
\end{document}
dustin
  • 18,617
  • 23
  • 99
  • 204
  • Thanks for your solution. Unfortunately, this will not do for my specific use case since I need a thicker line to coat the transparent region. This is because I might be required to use a very low opacity or leave out the transparent filling altogether, so that only the coating line remains as a visual guide for the transparent region. – Philipp Aug 04 '13 at 17:23
  • @Philipp you can always play with the thickness to see what is thick enough without a visual displeasure. – dustin Aug 04 '13 at 17:40
  • That's true, but I'd need about ten times the thickness you used in your solution which is enough to cause "visual discontinuities" that vex me. Also, the ommitance of the line coating for the opaque region is not ideal when I use a thicker line width. – Philipp Aug 04 '13 at 18:05
  • @Philipp there is always option 2. Draw the pictures in TikZ. – dustin Aug 04 '13 at 18:48
  • Drawing it with TikZ might be an option, though I would prefer using pgfplots since I have a lot of data files which I want to plot with more or less the same code. Do you think an automated solution with TikZ that mitigates the problems described in my question will be feasible? – Philipp Aug 04 '13 at 19:07
  • @Philipp have you considered trying gnuplot? Or does that cause the same issue too? – dustin Aug 04 '13 at 19:11
  • I have considered matplotlib, which does indeed work :). But at the time of asking this question I didn't know my way around python. – Philipp Aug 04 '13 at 19:11
  • @Philipp I use Python all the time for plots that wouldn't work in LaTeX. You can save it as pylab.savefig('name.eps', format = 'eps') and then just use \includegraphics. – dustin Aug 04 '13 at 19:13
  • @Philipp I think data can be imported in TikZ. I will have to look it up and see. – dustin Aug 04 '13 at 19:14
  • I think since version 1.2 matplotlib allows to export graphs as pgf code by including matplotlib.use("pgf") in the source code. This works quite good but with bigger plots this can run into memory issues. – Philipp Aug 04 '13 at 19:26