7

Following this answer, I have a data file P.dat which I need to plot it as a filled contour plot.

However, I got this error

Package pgfplots Error: CRITICAL: shader=interp: got unsupported pdf shading type '0'. This may corrupt your pdf!. \end{axis}

I would be grateful if I could know the error source and how I can make the output match the MATLAB desired one.


P.dat

http://pastebin.com/PAvQMxdC


MWE

\RequirePackage{luatex85}
\documentclass[tikz]{standalone}

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

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
    \addplot3[contour filled] table {P.dat};
    \end{axis}
    \end{tikzpicture}
\end{document}

MATLAB Desired Output

enter image description here


Update 1

I made another data file with NaN z values to account for the void data (white space) and specified the number of rows and columns, but I got this undesired output.

P2.dat

http://pastebin.com/CCUjeQUm

MWE 2

\RequirePackage{luatex85}
\documentclass{standalone}

\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=newest}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[view={0}{90}]
    \addplot3[contour filled,mesh/rows=31,mesh/cols=11,mesh/check=false] table {P2.dat};
    \end{axis}
    \end{tikzpicture}
\end{document}

Output 2

enter image description here


Update 2

Recalling my raw MATLAB data, how can I remove all the points whose z values equal to or exceed 1723 in order to get an output similar to my desired one?

P3.dat

http://pastebin.com/jvNVfJMU

MWE 3

\RequirePackage{luatex85}
\documentclass{standalone}

\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=newest}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[view={0}{90},colorbar, point meta max=1723, point meta min=300,]
    \addplot3[contour filled={number = 25,labels={false}},mesh/rows=31,mesh/cols=11,mesh/check=false
    ] table {P3.dat};
    \end{axis}
    \end{tikzpicture}
\end{document}

Output 3

enter image description here

  • 1
    I guess this has at least two causes. (1) You didn't provide a valid mesh. That means that the given "blocks" in the first data columns need to be identical (always). (2) You don't have any empty lines in your data file and (at least from the given table) PGFPlots cannot guess the number of mesh/rows and/or mesh/cols right. For me your example compiles fine when you comment/delete all data rows after line 40, i.e. the line starting with a value of 2 and providing mesh/cols=8 to the \addplot3 options. – Stefan Pinnow Jan 22 '17 at 12:38
  • @StefanPinnow Thanks for your comment. I am new to contour plots with pgfplots. My ultimate result is supposed to be 2D, but your suggestion ended in 3D plot. So, how can do this? – Diaa Jan 22 '17 at 13:19
  • To make a 2D plot from the 3D one add view={0}{90} to the axis options. To the contour filled question: As I said, you need to provide a "uniform" grid, i.e. the number of rows and the number of columns in the grid have to be identical. So you have either the possibility to add some dummy grid points and use NaN as z value (assuming that the white parts don't have any value) or provide additional grid points in between the given "boundaries" with the corresponding z value. (I am not sure if method 2 really works ...) – Stefan Pinnow Jan 22 '17 at 13:36
  • @StefanPinnow I followed your first suggestion and made another .dat file with NaN z values for the white space. Now I have a uniform mesh with 11 columns and 31 rows. However, I got this error Package pgfplots Error: the arguments of [mesh/rows=31,mesh/cols=11] assume 3omplete or overcomplete!? [Use mesh/check=false to disable this message]. \end{axis}. What might be missing? – Diaa Jan 22 '17 at 13:55
  • @StefanPinnow You can find my second data file and undesired output in the updated question body. – Diaa Jan 22 '17 at 14:09
5

Here I present two solutions.


Solution 1 (left part of the image)

This tries to reproduce the Matlab figure with the capabilities of PGFPlots. To "confirm" that I did it right, I first saved your Matlab image and cropped the axis parts. Then I added this as \addplot graphics and on top of that I added the real plot, i.e. \addplot contour filled plot in 50% transparent. That allowed to check, if I found the interval boundaries right.

Said that I think your above statement is wrong. It seems that you removed the color for all values >1600. This also makes sense, because the maximum value in the P3.dat file is 1723 ...

Solution 2 (right part of the image)

Here I just used the above cropped Matlab image and reproduced the colorbar.

Comparison

As you can see in solution 1 there are some "artifacts" which don't make the result as smooth as the Matlab result. That is, because the contours calculation/visualization only depends on the features of your PDF viewer. Said that it could be that your result differs from mine. I made the screenshot from a view in Acrobat Reader XI.

That is why I favor solution 2.

To improve the result you should modify your Matlab view to only show the contours, that means remove the axis and the grid lines. Then the only difference could be the colors used/shown in Matlab contour plot and the colorbar calculated by PGFPlots. Concrete I mean that one could use RGB colors and the other CMYK. But since you have the illustrator as you said, you could check for that and adapt one of the both parts, i.e. the Matlab or PGFPlots output.

You could also create a "pure", that means also without any axis, version of the colorbar in Matlab and also import this graphics into the PGFPlots colorbar. Of course then colors are identical.


For more details on how the solutions work, please have a look at the comments in the code.

% used PGFPlots v1.14
\RequirePackage{luatex85}
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{
    % you need at least this `compat' level or higher to use the below features
    compat=1.14,
    % define a "white" colormap for the white part of the image
    colormap={no data}{
        color=(white)
%        color=(white)
        color=(red)
    },
    % load this colormap which is later used
    colormap/bluered,
    % define the "parula" colormap that was used to create the exported image
    % from Matlab
    % (borrowed from http://tex.stackexchange.com/a/336647/95441)
    colormap={parula}{
        rgb255=(53,42,135)
        rgb255=(15,92,221)
        rgb255=(18,125,216)
        rgb255=(7,156,207)
        rgb255=(21,177,180)
        rgb255=(89,189,140)
        rgb255=(165,190,107)
        rgb255=(225,185,82)
        rgb255=(252,206,46)
        rgb255=(249,251,14)
    },
}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            view={0}{90},
            colorbar,
            % modify the style of the colorbar a bit
            colorbar style={
                ytick distance=200,
                ymax=1600,
            },
            % this key--value is needed because of the `\addplot graphics'
            enlargelimits=false,
        ]
            % import the "exported" graphics
            \addplot graphics [
                xmin=0,
                xmax=50,
                ymin=0,
                ymax=150,
            ] {P3};
            % now try to reproduce the style of the exported graphics
            \addplot3 [
                % for that use, e.g., the `countour filled' feature ...
                contour filled={
                    % ... in combination with the `levels of colormap' feature
                    % which allows to customize the used colormap
                    levels from colormap={
                        % this part of the colormap is for the "colored" part
                        of colormap={
                            % here we use the above initialized `bluered' colormap
                            bluered,
%                            % (`viridis' is a colormap which is similar to the
%                            %  used `parula' comormap in Matlab.
%                            %  But because the yellow is hard to identify
%                            %  in this context we use the above colormap)
%                            viridis,
                            % with this we state there is more to come
                            target pos max=,
                            % and here we state where the corresponding levels
                            % should *start*
                            target pos={200,400,600,800,1000,1200,1400},
                        },
                        % here comes the second part of the colormap which
                        % should have no color which isn't possible or at least
                        % I don't have an idea how to do it ...
                        of colormap={
                            % ... so I use a "white" colormap instead
                            no data,
                            % here the lower end isn't needed because that was
                            % specified in the first part of the colormap
                            target pos min=,
                            % and here is the corresponding interval *start*
                            % for that colormap
                            % (as you can see -- or not ;) -- the white starts
                            %  at position/values >=1600)
                            target pos={1600},
                        },
                    },
                },
                % you need only to provide `rows' or `cols' because
                % PGFPlots can then calculate the other value together with
                % the provded number of data points
                mesh/rows=31,
                % make the plot half transparent to check that the `target pos'
                % of the colormap are chosen correct
                opacity=0.5,
            ] table {P3.dat};
        \end{axis}
    \end{tikzpicture}
    \begin{tikzpicture}
        \begin{axis}[
            % show the colorbar
            colorbar,
            % because there is no real plot where PGFPlots can get the `meta'
            % data from, one has to provide them manually
            point meta min=200,
            point meta max=1800,
            %%% here we define the needed colormap and its style again
            % we want to use constant intervals in the colormap
            colormap access=piecewise const,
            % and also here we have to provide the limits again ...
            of colormap/target pos min*=200,
            of colormap/target pos max*=1800,
            % ... and use this feature which makes easier to provide the
            % samples at the right position
            % (please have a look at the PGFPlots manual for more details)
            of colormap/sample for=const,
            % this is similar to the above example
            colormap={CM}{
                of colormap={
                    % ... except that we use the `parula' colormap here
                    parula,
                    target pos max=,
                    target pos={200,400,600,800,1000,1200,1400,1600},
                },
                of colormap={
                    no data,
                    target pos min=,
                    % here you can use an arbitrary value which is greater than
                    % the last `target pos' of the previous colormap part of course.
                    % But here I tried to "overwrite" the last color of the
                    % colormap, i.e. the "bright" yellow, as well by just
                    % giving it a very small interval
                    % (to show the effect increase the `ymax' value in the
                    %  `colorbar style')
                    target pos={1601},
                },
            },
            % modify the style of the colorbar a bit
            colorbar style={
                ytick distance=200,
                ymin=300,
                ymax=1600,
            },
            % this key--value is needed because of the `\addplot graphics'
            enlargelimits=false,
        ]
            \addplot graphics [
                xmin=0,
                xmax=50,
                ymin=0,
                ymax=150,
            ] {P3};
        \end{axis}
    \end{tikzpicture}
\end{document}

image showing the result of above code

  • Many thanks for your comprehensive answer. I think I need some time to study it. At the moment, the first solution seems to be clumsy/blurry after I tested it. I will study your both solutions very well and get back to you if you don't mind. – Diaa Jan 23 '17 at 9:52
  • You are welcome. Sure, please ask. That is, what this site is all about :) If you find my answer useful, don't forget to upvote it and of course if it solves your problem to accept it (by clicking on the checkmark ✓) ;) – Stefan Pinnow Jan 23 '17 at 18:34
  • I am sorry for not accepting your answer quickly. For your second solution, I will post another question on how to reproduce the MATLAB color bar using pgfplots, and I would be thankful if you could consider it. – Diaa Jan 23 '17 at 22:30
  • Not a problem. But lately people seem to forget this quite often and I just write this as reminder before they don't look at TeX.SX again and because nothing was stated we cannot be sure if that solution now was ok or not. And of course if the question (you asked) would not be answered to your satisfaction there is no need to accept it. But then it would be nice to let us know what is still missing or whatever ... Of course I will have a look at your follow-up question, as long it will have the tag {pgfplots} ;) – Stefan Pinnow Jan 23 '17 at 22:43
  • Your second solution is helpful to me so that I figured out how to import MATLAB figures into pgfplots in a clean way. However, this part of colorbar is overloading my brain circuit, and I need to formulate a specific question on it to better understand. Anyway, thanks for being supportive :). – Diaa Jan 23 '17 at 22:56

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.