11

How can I plot a matrix of real values with TikZ/PGF such that it looks like plotted with imshow in MATLAB?

\addplot3 does something similar, but I'd like to have that in a color-coded 2D plot.

1

5 Answers 5

6

The following does the job very well:

\begin{tikzpicture}
  \begin{axis}[view={0}{90},
               xlabel=$x$,
               ylabel=$y$,
               title=View from top]
    \addplot3[surf] {x};
  \end{axis}
\end{tikzpicture}
1
  • 2
    The tick does not align to the middle of rectangle in this approach.
    – Dilawar
    Jun 14, 2018 at 7:00
6

There's a problem with @Christian's first answer: It does not work for data matrices. In that case, the values get mapped at the corners of each squares, and the colors are some interpolation between adjacent data values, not the values themselves. I found the following solution. It's not completely satisfactory since the size of the marks does not adapt to the size of the picture, but it's a start. You can also have empty values, as shown in the example.

\begin{tikzpicture}
\begin{axis}[
  width=0.75\textwidth, height=0.75\textwidth,
  tick align=inside, unbounded coords=jump,
  xmin=-1, xmax=5, ymin=-1, ymax=5,
  point meta min=0, point meta max=8, colorbar, colormap/bluered]
  \addplot[mark=square*,only marks, scatter, scatter src=explicit,
  mark size=17]
  coordinates {
  (0,0) [0]
  (0,1) [1]
  (0,2) [2]
  (0,3) [3]
  (0,4) [4]

  (1,0) [1]
  (1,1) [2]
  (1,2) [3]
  (1,3) [4]
  (1,4) [5]

  (2,0) [2]
  (2,1) [3]
  (2,4) [6]

  (3,0) [3]
  (3,1) [4]
  (3,2) [5]
  (3,3) [6]
  (3,4) [7]

  (4,0) [4]
  (4,1) [5]
  (4,2) [6]
  (4,3) [7]
  (4,4) [8]
  };
\end{axis}
\end{tikzpicture}

solution

2

I hacked a solution by my own, using a scatter plot. The key here is to adjust x and y, and the mark size to the right values.

\begin{tikzpicture}[]
    \begin{axis}[x=4mm,y=4mm,xtick=\empty,ytick=\empty]
    \addplot[scatter,scatter src=explicit, 
             only marks, mark=square*,mark size=2mm]  
             coordinates {(0,1)[0]  (1,1)[.1] (2,1)[.2]
                          (0,2)[.3] (1,2)[.4] (2,2)[.5]};
    \end{axis}
\end{tikzpicture}
1
2

I know that this is an old question, but for future reference, I want to include that pgfplots has included an imshow like plot, at least in version 1.18. It is called matrix plot. In contrast to the solutions above, it places the patches at the correct locations, leaves no gaps in between patches and does not require manual scaling of the patches with respect to the axis system.

\documentclass{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        width=4cm,
        height=4cm,
        colorbar,
        colormap name=viridis]
    \addplot[matrix plot, point meta=explicit]
        coordinates {
            (0,0) [0] (1,0) [1] (2,0) [2]
            
            (0,1) [3] (1,1) [4] (2,1) [5]
            
            (0,2) [6] (1,2) [7] (2,2) [8]
        }; 
    \end{axis}
\end{tikzpicture}
\end{document}

Example plot result.

Note similar to imshow it places the y-axis in the top, with the positive y-direction pointing downward. Use matrix plot* for a normal axis system definition.

For more information see the documentation.

2
  • Good answers to old questions are always welcome, thanks for helping future readers :) in the future though, when you post answers could you make sure that they compile please? As in starting with \documentclass{...} and ending with \end{document}, helps people in the future if they can copy and paste your answer as is
    – JamesT
    Oct 12, 2023 at 16:00
  • Good point, I had to look up how to do that, but the standalone works nicely.
    – BHeijden
    Oct 14, 2023 at 15:22
1

If preprocessing you data is an option, you can also use patch plots (4.6.13 in the manual). This has the advanted that you easily get the correct size for the cells and have no gaps.

For a patch plot, you have to specify coordinates of the shapes making up a surface manually. By listing a rectangle for each point you can get the desired result. For example for a matrix

2 3
4 5

you can write something like:

\begin{tikzpicture}
    \begin{axis}[
            % this prevents the borders of the
            % patches to be rendered
            shader=interp,
            % optional, add colorbar (here just
            % for showing that the values are
            % rendered correctly)
            colorbar,
        ]
        \addplot [
            % switch to patch mode
            patch,
            % The meta value determines the color.
            % "explicit" means that there is an extra
            % source for those, the default without
            % this option is to take the y value.
            point meta=explicit,
            % This tells pgfplots that the data is to
            % be interpreted as groups of four. Each
            % group represents the corners of a rectangle.
            patch type=rectangle,
        ] table [meta index=2] {
            x y meta
            -0.5 0.5 2
            -0.5 1.5 2
            0.5 1.5 2
            0.5 0.5 2
            
            0.5 0.5 3
            0.5 1.5 3
            1.5 1.5 3
            1.5 0.5 3
            
            -0.5 -0.5 4
            -0.5 0.5 4
            0.5 0.5 4
            0.5 -0.5 4
            
            0.5 -0.5 5
            0.5 0.5 5
            1.5 0.5 5
            1.5 -0.5 5
        };
    \end{axis}
\end{tikzpicture}

We set the point meta of each corner to the same value. This way the interpolation shader results in a single color. The data input as inline table is just an example, you can just as well load it from a file or use another variation like "coordinates".

rendered tex document

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .