19

I did some calculations in Mathematica that gave me a contour plot: enter image description here

To include the output I wanted to however draw it with pfgplot. But there I don't get it to work, first of all the y-axis doesn't start at 0 and second I cannot find a specifier to fill the areas between the lines. The part that is white in the plot I am trying to reproduce is an area of complex values that I wanted to exclude as well. My MWE up to now looks like

\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat = 1.7}

\begin{document}

\begin{tikzpicture}

\begin{axis}[
     xlabel = $x$
     , ylabel = $y$
    , domain = 1:2
     , y domain = 0:90
    , view = {0}{90}
    ]

    \addplot3[
        contour gnuplot={number = 30,labels={false}}, 
            thick
        ]{-2.051^3*1000/(2*3.1415*(2.99*10^2)^2)/(x^2*cos(y)^2)};

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

with the following output

enter image description here

It should be a common problem but I couldn't find a solution. Another thing that I tried was using addplot3 with surf, but the way how the colors are put together didn't seem to work right

\addplot3[surf,shader=interp,samples=2, patch type=bilinear] 
  • Are y values in radians or degree? – Red Aug 30 '13 at 13:25
  • in the original plot in degrees. So the whole region from 0 to 90 degrees. I thought gnuplot uses by default also deg? – spookyfw Aug 30 '13 at 13:36
  • Pgfplots comes without support for filled contours. – Christian Feuersänger Aug 30 '13 at 17:40
  • is there any workaround? the addplot3 environment seems to call gnuplot. Or is gnuplot here only used for the calculations? The other possibility I was considering: to create a surface plot and then set the view from the top. I dont care so much about the contour lines, I rather want to show the change accross the variables, as in the Mathematica plot – spookyfw Aug 30 '13 at 18:35
  • There is a trick for gnuplot to fill the contour lines: gnuplot-tricks.blogspot.com.br/2009/07/… and pgfplots can call scripts directly with \addplot[raw gnuplot] gnuplot {#code}; – juliohm Sep 1 '13 at 13:03
15

enter image description here

Another possibility: filled contours with Asymptote, MWE:

% fcontour.tex:
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}
\begin{figure}
\begin{asy}
import graph;
import contour;
import palette;
defaultpen(fontsize(10pt));
size(14cm,8cm,IgnoreAspect);
pair xyMin=(1,74);  
pair xyMax=(3,86);
real f(real x, real y) {return -2.051^3*1000/(2*3.1415*(2.99*10^2)^2)/(x^2*Cos(y)^2);}
int N=200;
int Levels=16;
defaultpen(1bp);
bounds range=bounds(-3,-0.10); // min(f(x,y)), max(f(x,y))
real[] Cvals=uniform(range.min,range.max,Levels);
guide[][] g=contour(f,xyMin,xyMax,Cvals,N,operator --);
pen[] Palette=Gradient(Levels,rgb(0.3,0.06,0.5),rgb(0.9,0.9,0.85));
for(int i=0;i<g.length-1;++i){
  filldraw(g[i][0]--xyMin--(xyMax.x,xyMin.y)--xyMax--cycle,Palette[i],darkblue+0.2bp);
}
xaxis("$x$",BottomTop,xyMin.x,xyMax.x,darkblue+0.5bp,RightTicks(Step=0.2,step=0.05),above=true);
yaxis("$y$",LeftRight,xyMin.y,xyMax.y,darkblue+0.5bp,LeftTicks(Step=2,step=0.5),above=true);
palette("$f(x,y)$",range,point(SE)+(0.2,0),point(NE)+(0.3,0),Right,Palette,
        PaletteTicks("$%+#0.1f$",N=Levels,olive+0.1bp));
\end{asy}
\caption{A contour plot.}
\end{figure}
\end{document}
% 
% To process it with `latexmk`, create file `latexmkrc`:
% 
%     sub asy {return system("asy '$_[0]'");}
%     add_cus_dep("asy","eps",0,"asy");
%     add_cus_dep("asy","pdf",0,"asy");
%     add_cus_dep("asy","tex",0,"asy");
% 
% and run `latexmk -pdf fcontour.tex`.
  • I don't graph in LaTeX (yet), but that's a beautiful result! – Steven B. Segletes Aug 30 '13 at 20:05
  • @Steven B. Segletes: The range of features available by means of graphic LaTeX tools is amazing indeed. – g.kov Aug 31 '13 at 6:16
22

EDIT

Starting with pgfplots 1.14, you can draw filled contour plots by means of builtin methods in pgfplots:

\documentclass{standalone}

\usepackage{pgfplots}
\usepgfplotslibrary{colorbrewer,patchplots}
\pgfplotsset{compat=1.14}

\begin{document}
\begin{tikzpicture}

\begin{axis}[
    domain = 1:2,
    %y domain = 0:90,
    y domain = 74:87.9,
    view = {0}{90},
    colormap={violet}{rgb=(0.3,0.06,0.5), rgb=(0.9,0.9,0.85)},
    colorbar,
    point meta max=-0.1,
    point meta min=-3,
    ]

    \addplot3[
        contour filled={number = 30,labels={false}}, 
            thick
        ]{-2.051^3*1000/(2*3.1415*(2.99*10^2)^2)/(x^2*cos(y)^2)};

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

enter image description here


Apparently, gnuplot's contouring algorithm gets confused near the singularity: all its contour lines will be placed there. I restricted the y domain such that it is a little bid away from it and then gnuplot produced useful contour lines:

enter image description here

\documentclass[a4paper]{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.8}

\begin{document}

\begin{tikzpicture}

\begin{axis}[
     colorbar,
     xlabel = $x$
     , ylabel = $y$
    , domain = 1:2
     , y domain = 74:87.9
    , view = {0}{90},
    ]

    \addplot3[
        contour gnuplot={number = 30,labels={false}}, 
            thick,
            samples=40,
        ]
        {-2.051^3*1000./(2*3.1415*(2.99*10^2)^2)/(x^2*cos(y)^2)};

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

Filling the space between these lines is currently unsupported in pgfplots.

Note that the math expression is evaluated by means of pgfplots (which operates on degrees). The contour lines are evaluated by means of gnuplot and are reimported into pgfplots.


As requested, here is a result optained by means of a surf plot.

enter image description here

\documentclass[a4paper]{standalone}

\usepackage{pgfplots}

\pgfplotsset{compat=1.8}

\begin{document}

\begin{tikzpicture}

\begin{axis}[
    colorbar,
    colorbar style={
        ytick={-3,-2,-1,0},
        yticklabels={$\le -3$, $-2$,$-1$, $0$},
    },
     xlabel = $x$
     , ylabel = $y$
    , domain = 1:2
     , y domain = 74:89.999
    , view = {0}{90},
    point meta min=-3,
    point meta max=0,
    ymax=90,
    ]

    \addplot3[
        surf,shader=interp,
        samples=40,
        ]
        {-2.051^3*1000./(2*3.1415*(2.99*10^2)^2)/(x^2*cos(y)^2)};

\end{axis}  
\end{tikzpicture}



\end{document}

Note that I restricted the color data to the range -3,0, that's what causes the blue area on top. I modified the colorbar to express this restriction near the singularity. Perhaps the -3 was too tight; feel free to experiment with some other limit like -10. The character of the image is similar, though: you only move the contour line which is visible in this surface plot.

The color set is the default of pgfplots, it can be adopted to your needs using something like colormap={examplemap}{rgb=(0.3,0.06,0.5) rgb=(0.9,0.9,0.85)}, (which is close to the one of g.kov).

  • I am sorry, but I am new to contour plots using pgfplots, and I think that the information in your answer can help me solve my problem described in this question. I would be grateful if you could consider it. – Diaa Jan 22 '17 at 19:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.