I'm trying to visualize electric fields. StreamPlot is helpful:

ef[q_, source_, at_] = (k q)/Norm[source - at]^3 (at - source)
myfield[x_, y_] =
   (ef[-1, {-1, 0}, {x, y}] + ef[+1, {+1, 0}, {x, y}]) /. k -> 8.99 10^9;
StreamPlot[myfield[x, y], {x, -3, 3}, {y, -3, 3}]

Output from <code>StreamPlot</code>, correctly showing the field lines

But when I want to see the strength of the field as well, StreamDensityPlot understandably chokes because $\lim_{(x,y) \to (\pm 1,0)} \lVert \texttt{myfield}[x,y] \rVert = \infty$. This is what I get:

StreamDensityPlot[myfield[x, y], {x, -3, 3}, {y, -3, 3}, 
 ColorFunction -> "TemperatureMap"]

Output from <code>StreamDensityPlot</code>: blue everywhere with a couple of bright dots at the poles

Now, I can adjust the scalar field by Mining the actual Norm with some fixed value:

StreamDensityPlot[{myfield[x, y], 
  Min[Norm[myfield[x, y]], 10^11]}, {x, -3, 3}, {y, -3, 3}, 
 ColorFunction -> "TemperatureMap"]

Output from <code>StreamDensityPlot</code> with a <code>Min</code> clamp; a bit nicer

But this requires some trial and error to find a good value, and it still doesn't look particularly great (there's noticeable clipping). More importantly, there's really only two regions: the poles (red) and the farfield (blue); I don't really gain much insight into the field strength, at, say, $(0, \frac{1}{2})$.

Throwing a Log in there gives you more contrast, but you still have to fiddle with the clamp:

StreamDensityPlot[{myfield[x, y], 
  Min[Log[Norm[myfield[x, y]]], 28]}, {x, -3, 3}, {y, -3, 3}, 
 ColorFunction -> "TemperatureMap"]

Output of <code>StreamDensityPlot</code> with a <code>Min</code> clamp of the <code>Log</code> transform

Hence my question. How can I get StreamDensityPlot to

  • yield nice output even when the domain contains singularities,
  • such that I can clearly see both the singularities and the farfield, and the regions in between,
  • while still retaining a reasonable degree of physical accuracy,
  • and as automatically as possible? (e.g., I don't very much like having to manually specify the scalar field)

I read the main StreamDensityPlot documentation and skimmed the "Options" section (that's how I found that you can manually specify the scalar field) but didn't see anything pertinent.


1 Answer 1

vals = Table[Norm[myfield[x, y]], {x, -3, 3, 6/100}, {y, -3, 3, 6/100}];
m = Mean@Log@Flatten@vals;
st = StandardDeviation@Log@Flatten@vals;

(* For some cases you may use these instead
   m = NIntegrate[Log@Norm[myfield[x, y]], {x, -3, 3}, {y, -3, 3}]/36;
   st = NIntegrate[(m - Log@Norm[myfield[x, y]])^2, {x, -3, 3}, {y, -3, 3}]/36 // Sqrt;
 sta = a st; 
       myfield[x, y],  
       Rescale[Log@Norm[myfield[x, y]], {m - sta, m + sta}]}, 
       {x, -3, 3}, {y, -3, 3}, ColorFunction -> "TemperatureMap", 
       ColorFunctionScaling -> False], 
{a, 1, 5}]

Mathematica graphics

  • 1
    $\begingroup$ Ooh, clever to use the standard deviation! I'll look into this. $\endgroup$
    – wchargin
    Aug 13, 2015 at 4:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.