1

I am not sure if this question has been asked before, but I want to produce a 3D plot like in this example.

enter image description here

Currently, I have

\documentclass[tikz,border=3.14pt]{standalone}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.16}

\begin{document}
\begin{tikzpicture}[scale=1, transform shape]
\begin{axis}[
view={120}{40},
width=10cm,
height=10cm,
grid=major,
xmin=1,xmax=4,
ymin=1,ymax=5,
zmin=-1,zmax=3,
xtick={1,2,3,4},
xticklabels={L1, L2, L3, L4},
ytick={1,2,3,4,5},
yticklabels={A, B, C, D, E},
ylabel={$y$},
xlabel={$x$},
zlabel={$z$},
axis equal,
]

\addplot3[only marks,scatter,mark=cube*,mark size=1cm, fill=blue]
coordinates {(1,1,0.7)(1,2,0.5)(1,3,0.9)(1,4,0.4)(1,5,0.33)};

\addplot3[only marks,scatter,mark=cube*,mark size=1cm, fill=orange]
coordinates {(2,1,0.6)(2,2,0.3)(2,3,0.65)(2,4,0.67)(2,5,0.31)};

\addplot3[only marks,scatter,mark=cube*,mark size=1cm,fill=violet]
coordinates {(3,1,0.3)(3,2,0.45)(3,3,0.7)(3,4,0.89)(3,5,0.45)};

\addplot3[only marks,scatter,mark=cube*,mark size=1cm,fill=red]
coordinates {(4,1,1)(4,2,0.2)(4,3,0.6)(4,4,0.72)(4,5,0.78)};

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

but I cannot get the bars to start at z=0 since they have a fixed size. Thank you in advance to anyone who helps out and apologies if I am being daft.

Owen
  • 79

1 Answers1

4

This repeats an old answer with a slightly new tilt concerning the half cube* plot marks.

\documentclass[tikz,border=3.14pt]{standalone}
\usetikzlibrary{calc}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.16}
\pgfkeys{/tikz/.cd,
cube top color/.store in=\CubeTopColor,
cube top color=blue!60,
cube front color/.store in=\CubeFrontColor,
cube front color=blue!30,
cube side color/.store in=\CubeSideColor,
cube side color=blue!40,
3d cube color/.code={\colorlet{mycolor}{#1}%
\tikzset{cube top color=mycolor!60,cube front color=mycolor!30,%
cube side color=mycolor!40,draw=mycolor}}
}
\makeatletter
\pgfdeclareplotmark{half cube*}
                {%
                        \pgfplots@cube@gethalf@x
                        \let\pgfplots@cube@halfx=\pgfmathresult
                        \pgfplots@cube@gethalf@y
                        \let\pgfplots@cube@halfy=\pgfmathresult
                        \pgfplots@cube@gethalf@z
                        \let\pgfplots@cube@halfz=\pgfmathresult
                        \pgfmathparse{0*\pgfplots@cube@halfz}%
                        \let\pgfplots@cube@topz=\pgfmathresult
                        \pgfmathparse{-1*\pgfplots@cube@halfz}%
                        \let\pgfplots@cube@bottomz=\pgfmathresult
                        %
                        \pgfplotsifaxissurfaceisforeground{0vv}{%
                                \pgfsetfillcolor{\CubeFrontColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }{% 
                                \pgfsetfillcolor{\CubeFrontColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }%
                        \pgfplotsifaxissurfaceisforeground{v0v}{%
                                \pgfsetfillcolor{\CubeSideColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }{% 
                                \pgfsetfillcolor{\CubeSideColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }%
                        \pgfplotsifaxissurfaceisforeground{vv0}{%
                                \pgfsetfillcolor{\CubeTopColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@bottomz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }{% 
                                \pgfsetfillcolor{\CubeTopColor}
                                \pgfpathmoveto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{-\pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{ \pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathlineto{\pgfplotsqpointxyz{ \pgfplots@cube@halfx}{-\pgfplots@cube@halfy}{\pgfplots@cube@topz}}%
                                \pgfpathclose
                                \pgfusepathqfillstroke
                        }%
            }
\makeatother
\begin{document}
\begin{tikzpicture}[scale=1, transform shape]
\pgfmathsetmacro{\gconv}{63.85498}%<- you get told what you need to put here
\begin{axis}[
view={110}{20},
width=10cm,
height=10cm,
grid=major,
xmin=0,xmax=4.5,
ymin=0,ymax=5.5,
zmin=0,%zmax=1.5,
xtick={1,2,3,4},
xticklabels={L1, L2, L3, L4},
ytick={1,2,3,4,5},
yticklabels={A, B, C, D, E},
ylabel={$y$},
xlabel={$x$},
zlabel={$z$},
axis equal,
]
\path let \p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in 
\pgfextra{\pgfmathsetmacro{\conv}{2*\y1}
\ifx\gconv\conv
\typeout{z-scale\space good!}
\else
\typeout{Kindly\space consider\space setting\space the\space 
        prefactor\space of\space z\space to\space \conv}
\fi     
        };  

\pgfplotsset{3d bars/.style={only marks,scatter,mark=half cube*,mark size=0.6cm, 
3d cube color=#1,point meta=0,
,visualization depends on={\gconv*z \as \myz},
scatter/@pre marker code/.append style={/pgfplots/cube/size z=\myz},}}

\addplot3[3d bars=blue]
    coordinates {(1,1,0.7)(1,2,0.5)(1,3,0.9)(1,4,0.4)(1,5,0.33)};

\addplot3[3d bars=orange]
    coordinates {(2,1,0.6)(2,2,0.3)(2,3,0.65)(2,4,0.67)(2,5,0.31)};

\addplot3[3d bars=violet]
    coordinates {(3,1,0.3)(3,2,0.45)(3,3,0.7)(3,4,0.89)(3,5,0.45)};

\addplot3[3d bars=red]
     coordinates {(4,1,1)(4,2,0.2)(4,3,0.6)(4,4,0.72)(4,5,0.78)};

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

enter image description here

If you are wondering why the bars are so tiny: this is because of the axis equal key. You are probably not wondering why I did not make this more elegant by writing the conversion factor to the aux file and recovering it from there, do you?