# Why is this 2D plot so slow?

I first do a 3D Plot of four surfaces (eigenvalues of a $4\times4$ matrix) over $kx,kz$ (setting $ky=0$ all along). And then I try to give a 2D plot along three connected particular lines in $kx,kz$-plane, which is simply a tiny part of the 3D one. However, the 2D one turns out to be far slower than the 3D one. Also I use Evaluate in both cases, otherwise a weird mess (Why?). What's wrong with my code? And I'm wondering what the faster code ought to be.

zero2 = DiagonalMatrix[{0, 0}];
I2 = IdentityMatrix;
I4 = IdentityMatrix;
t = 1/2;
λ = 1;
Subscript[λ, z] = 1;
ϵ = 6 t;
b = {0, 0, 0, 1};

H[kx_, ky_, kz_] := 2 λ KroneckerProduct[PauliMatrix, PauliMatrix Sin[ky] - PauliMatrix Sin[kx]] + 2 Subscript[λ, z]   KroneckerProduct[PauliMatrix, I2] Sin[kz] + KroneckerProduct[PauliMatrix, I2] (ϵ - 2 t (Cos[kx] + Cos[ky] + Cos[kz]));
Subscript[H, 1][kx_, ky_, kz_] := b.{KroneckerProduct[PauliMatrix, PauliMatrix], -KroneckerProduct[PauliMatrix, PauliMatrix], KroneckerProduct[PauliMatrix, PauliMatrix], KroneckerProduct[I2, PauliMatrix]};
Eval[kx_, ky_, kz_] := FullSimplify[Eigenvalues[H[kx, ky, kz] + Subscript[H, 1][kx, ky, kz]]];

Plot3D[Evaluate[Eval[kx, 0, kz]],
{kx, -π, π}, {kz, -π, π},
AxesLabel -> Automatic, PlotLegends -> "Placeholder"
]

a0 = 1;
b1 = 2 π/a0;
b2 = 2 π/a0;
b3 = 2 π/a0;
BZKx = b1/2;
BZKz = b3/2;
Plot[Evaluate@Eval[If[k <= 0, k/Sqrt, If[k <= BZKx, 0, BZKx]], 0, If[k <= 0, k/Sqrt, If[k <= BZKx, k, k - BZKx]]],
{k, -Sqrt BZKx, 2 BZKx},
ImageMargins -> 0, PlotStyle -> Thickness[.01]
]

• just out of curiosity: is this a band structure of some topological insulator?
– hat
Feb 11, 2016 at 9:33
• @hat That's right! Feb 11, 2016 at 9:53

Clear[Eval,kx, ky, kz];

Then the plots will be faster. This will symbolically evaluate the eigenvalues once, and the variables kx, ky, kz get substituted into the symbolic result when needed.
Regarding the need for Evaluate mentioned in the question, it's needed because Plot has attribute HoldAll as explained here.