Skip to main content

plotting - ContourPlot shows only part of the contours



Consider these contour plots:


f[x_,y_]:=Cos[x] + Cos[y]

ContourPlot[f[x, y] == 0, {x, 0, 4 Pi}, {y, 0, 4 Pi}]


enter image description here


ContourPlot[f[x, y]*f[x, y] == 0, {x, 0, 4 Pi}, {y, 0, 4 Pi}]

enter image description here


ContourPlot[Abs[f[x, y]] == 0, {x, 0, 4 Pi}, {y, 0, 4 Pi}]

enter image description here


Question: Why the second and third contour plot don't work? How to fix them to make them to reproduce the first contour plot?


I tried to increase the MaxRecursion and it's supper slow and doesn't help much:



ContourPlot[Abs[f[x, y]] == 0, {x, 0, 4 Pi}, {y, 0, 4 Pi}, MaxRecursion -> 15]

enter image description here






This part is just my context of the problem, you can safely ignore it if you are not interested.


Why do I want to plot the contour of Abs[f[x,y]]==0 or f[x,y]*Conjugate[f[x,y]]==0 if they are the same of f[x,y]==0?


Because it would help a lot when f[x,y] is a complex function(x and y are real variables but f[x,y] maybe complex). For any function f[x,y], it can be written in the form r[x,y]*Exp[I θ[x,y]] where r[x,y] and θ[x,y] are real function. So for f[x,y]==0 what we really means is r[x,y]==0, and instead of contour plotting f[x,y]==0 I should put r[x,y]==0. However, sometimes it would be difficult to get r[x,y] given the function f[x,y], but fortunately we can just plot the contour of f[x,y]*Conjugate[f[x,y]]==0 or Abs[f[x,y]]==0 since which is mathematically equivalent to r[x,y]==0.


For example,


I have a function



a0 = 10.;a = 1.4;
f[k_,K0_]:=a^2 Sech[(a a0)/2]^2 (-2 I (1 + E^(2 I a0 k)) k + a (-1 + E^(2 I a0 k)) Tanh[(a a0)/2]) + 2 k (I E^(I a0 k) ((a - k) (a + k) Cos[a0 k] + (a^2 + k^2) Cos[a0 K0]) + a (-1 + E^(2 I a0 k)) k Tanh[(a a0)/2])

I know it can be separate into the form r[k,K0]*Exp[I θ[k,K0]], but it's difficult to find what r and θ is. Since I want to plot the contour of r[k,K0]==0, instead I can plot the contour of Abs[f[k,K0]]==0, but I encountered the same problem as the simple example above.


ContourPlot[Abs[f[k, K0]] == 0, {K0, -2 π/a0, 2 π/a0}, {k, 0, 4}]

enter image description here


However if we plot the real and imaginary part, we can get the correct contour(the diamond shape) but also introduced other artificial contours(horizontal lines) come from Cos[θ[x,y]]==0 or Sin[θ[x,y]]==0.


Row@{ContourPlot[
Re[f[k, K0]] == 0, {K0, -2 π/a0, 2 π/a0}, {k, 0, 4}, PlotLabel -> "Re", PlotPoints -> 60],

ContourPlot[
Im[f[k, K0]] == 0, {K0, -2 π/a0, 2 π/a0}, {k, 0, 4}, PlotLabel -> "Im", PlotPoints -> 60]}

enter image description here


Just for comparison, the above function can be separated into


2 I E^(I a0 k) (a^2 Sech[(a a0)/2]^2 (-2 k Cos[a0 k] + a Sin[a0 k] Tanh[(a a0)/2]) + k ((a - k) (a + k) Cos[a0 k] + (a^2 + k^2) Cos[a0 K0] + 2 a k Sin[a0 k] Tanh[(a a0)/2]))

so


r[k_,K0_]:=a^2 Sech[(a a0)/2]^2 (-2 k Cos[a0 k] + a Sin[a0 k] Tanh[(a a0)/2]) + 
k ((a - k) (a + k) Cos[a0 k] + (a^2 + k^2) Cos[a0 K0] +

2 a k Sin[a0 k] Tanh[(a a0)/2])

and contour plot of r is


ContourPlot[r[k, K0] == 0, {K0, -2 \[Pi]/a0, 2 \[Pi]/a0}, {k, 0, 4}, PlotPoints -> 60]

enter image description here



Answer



The reason for the difficulties that ContourPlot is having can be attributed to the fact that you are looking for a contour right at the boundary of the function's range, i.e., $0$ for a function whose range is $f(x,y)\ge 0$. Since there is no loss of visual accuracy in moving this contour slightly into the allowed range of values, I would do it this way:


ContourPlot[f[x, y]*f[x, y] == 0.000001, {x, 0, 4 Pi}, {y, 0, 4 Pi}]


contours


and similarly for the other examples.


Edit


Unfortunately, this still doesn't work when the maximal function values vary steeply across the plot region, as is the case in the example


a0 = 10.; a = 1.4;
f[k_, K0_] :=
a^2 Sech[(a a0)/2]^2 (-2 I (1 + E^(2 I a0 k)) k +
a (-1 + E^(2 I a0 k)) Tanh[(a a0)/2]) +
2 k (I E^(I a0 k) ((a - k) (a + k) Cos[a0 k] + (a^2 + k^2) Cos[
a0 K0]) + a (-1 + E^(2 I a0 k)) k Tanh[(a a0)/2])


if we plot the Abs. Then the absolute contour value of, say, 0.01 is perhaps OK in part of the plot where the function itself varies only between 0 and 1, but it won't be large enough relative to the typical function values in regions where the maxima reach values of 100 or more.


In this case one could try to replace the constant contour value (0.01) by something that varies in the direction in which the range increases most rapidly. However, I don't have any good way of doing this in an automated way, so it would require manual tuning.


So here is a manual approach where I slice the contour plot into 9 different regions where the contours can then be identified in a hopefully more accurate way because the function doesn't vary too rapidly in each slice:


c = {{0, .01}, {.5, .03}, {1, .05}, {1.5, .15}, {2, .2}, \
{2.5, .5}, {3, 1}, {3.5, 1}, {4, 10}}

(*
==> {{0, 0.01}, {0.5, 0.03}, {1, 0.05}, {1.5, 0.15}, {2,
0.2}, {2.5, 0.5}, {3, 1}, {3.5, 1}, {4, 10}}

*)

t = Table[
ContourPlot[
Abs[f[k, K0]] == c[[i, 2]], {K0, -2 Pi/a0, 2 Pi/a0}, {k,
c[[i, 1]], c[[i + 1, 1]]}, PlotPoints -> 100],
{i, 1, Length[c] - 1}];

Show[t, PlotRange -> All]


slices


Comments

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...