4
$\begingroup$

I would like to do a DensityPlot with logarithmic xy-axes and logarithmic color scale for the function

\begin{align} S(\epsilon_{v},\epsilon_{\phi}) = \frac{\pi}{\epsilon_{v}} \frac{\sinh \left(\frac{2 \pi \epsilon_{v}}{\pi^{2} \epsilon_{\phi}/6} \right)}{\cosh \left(\frac{2 \pi \epsilon_{v}}{\pi^{2} \epsilon_{\phi}/6} \right) - \cos \left(2 \pi \sqrt{\frac{1}{\pi^{2} \epsilon_{\phi}/6} - \left( \frac{\epsilon_{v}}{\pi^{2} \epsilon_{\phi}/6} \right)^{2}} \right)}\\ ~\\ \epsilon_{v} \to x , \epsilon_{\phi} \to y~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \end{align}

[Background: Considering velocity dependent Dark Matter interaction this function (Sommerfeld enhancement) arises when solving the corresponding Schrödinger equation with a Hulthén potential]

While searching for a solution I found these two posts:

1) Logarithmic scale in a DensityPlot and its legend

2) DensityPlot with one log axis

But I am searching in some sense a combination of these two ideas.

Alas I started using Mathematica only a few weeks ago and I am not familiar with all its features. Hence, I came to no satisfactorily result yet and would be very happy if anyone can help.

Here the Matematica code which I in principle took from 1):

f[x_, y_] := 
  Pi/x * Sinh[
     12*x/(Pi*y)]/(Cosh[12*x/(Pi*y)] - 
      Cos[2*Pi*Sqrt[ 6/(Pi*Pi*y) - (6*x/(Pi*Pi*y))^2]]);



plotter[min_, max_, NumberOfTicks_] := 
 DensityPlot[f[x, y], {x, 10^(-6), 10^(0)}, {y, 1/(10^4), 1/(10^3)}, 
  PlotPoints -> 10, PlotRange -> Full, ColorFunctionScaling -> False, 
  ColorFunction -> (ColorData["Rainbow"][
      LogarithmicScaling[#, min, max]] &), 
  PlotLegends -> 
   BarLegend[{ColorData["Rainbow"], {0, 1}}, LegendMarkerSize -> 340, 
    Ticks -> ({LogarithmicScaling[#, min, max], 
         ScientificForm[#, 2]} & /@ (min (max/min)^
          Range[0, 1, 1/NumberOfTicks]))]]
plotter[1, 10^(6), 6]
$\endgroup$
4
  • $\begingroup$ It would be very helpful if you could at least propose a form of your function in Mathematica code, rather than as a LaTex expression. Furthermore, what have you tried so far? $\endgroup$
    – MarcoB
    May 23, 2016 at 19:41
  • $\begingroup$ Have you seen this? $\endgroup$ May 23, 2016 at 19:43
  • $\begingroup$ @J.M. : Not yet, thank you! But this is in principle just an extension of 1). I am missing the logarithmic xy axes, since it seems to me that just the color scale has an arbitrary non-linear form. $\endgroup$
    – stef
    May 23, 2016 at 20:08
  • $\begingroup$ I'd define g[x_,y_] := f[10^x, 10^y] and plot g with the range {x, -6, 0}, {y, -4, -3}. $\endgroup$
    – wxffles
    May 23, 2016 at 23:14

2 Answers 2

4
$\begingroup$

wxffles suggestion to use a helper function to do the coordinate transformation seems quite effective:

f[x_, y_] := Pi/x*Sinh[12*x/(Pi*y)]/(Cosh[12*x/(Pi*y)] - 
      Cos[2*Pi*Sqrt[6/(Pi*Pi*y) - (6*x/(Pi*Pi*y))^2]]);

helper[x_, y_] = f[10^x, 10^y];

LogarithmicScaling[x_, min_, max_] := Log[x/min]/Log[max/min]
plotter[min_, max_, NumberOfTicks_] := DensityPlot[

  (* Modification to use the helper function *)
  helper[x, y],
  {x, -6, 0}, {y, -4, -3},
  (* end modification *)

  PlotRange -> Full,
  ColorFunctionScaling -> False,
  ColorFunction -> (ColorData["Rainbow"][
      LogarithmicScaling[#, min, max]] &),

  PlotLegends ->
   BarLegend[{ColorData["Rainbow"], {0, 1}}, LegendMarkerSize -> 340, 
    Ticks -> ({LogarithmicScaling[#, min, max], 
         ScientificForm[#, 2]} & /@ (min (max/min)^
          Range[0, 1, 1/NumberOfTicks]))]
  ]

With these in place:

plotter[1, 1*^6, 6]

Mathematica graphics

$\endgroup$
3
$\begingroup$

This uses the CustomTicks package available here, and the nonLinearDensityPlot function defined here. See below for a version that does not use these add-ons

loglogDensityPlot[func_, {x_, xmin_, xmax_}, {y_, ymin_, ymax_}, 
    plotopts : OptionsPattern[{DensityPlot, nonLinearDensityPlot}]] :=
  nonLinearDensityPlot[
  func /. {x -> Exp[x], y -> Exp[y]}, {x, Log@xmin, Log@xmax}, {y, 
   Log@ymin, Log@ymax},
  FrameTicks -> {Charting`ScaledTicks[{Log, Exp}],
    Charting`ScaledTicks[{Log, Exp}]},
  ImagePadding -> {{Automatic, None}, {Automatic, None}},
  Evaluated -> True,
  plotopts]

By default this function uses an ArcSinh scaling function, that doesn't look great for your data

loglogDensityPlot[f[x, y], {x, 1/1000000, 1}, {y, 1/10000, 1/1000}]

Mathematica graphics

To change this, you need to provide a scaling function that maps the values your function can take to the range {0,1}. The arguments of the scaling function are {value, scalefactor, maxval, minval}. So to get linear scaling we use ((#1 - #4)/(#3 - #4) &). For the log scaling we use

loglogDensityPlot[
 f[x, y], {x, 10^(-6), 10^(0)}, {y, 1/(10^4), 1/(10^3)}, 
 "ScalingFunction" -> (Log[#1/#4]/Log[#3/#4] &)]

Mathematica graphics

Here is a version that doesn't use external packages, but I can't get a nice legend out of it. It is similar to MarcoB's answer,

loglogDensityPlot[func_, {x_, xmin_, xmax_}, {y_, ymin_, ymax_}, 
  opts : OptionsPattern[]] := 
 DensityPlot[Log@(func /. {x -> Exp[x], y -> Exp[y]}),
  {x, Log@xmin, Log@xmax}, {y, Log@ymin, Log@ymax},
  FrameTicks -> {Charting`ScaledTicks[{Log, Exp}],
    Charting`ScaledTicks[{Log, Exp}]},
  opts, PlotRange -> All,
  ImagePadding -> {{Automatic, None}, {Automatic, None}},
  Evaluated -> True
  ]

loglogDensityPlot[f[x, y], {x, 1/1000000, 1}, {y, 1/10000, 1/1000}, 
 PlotPoints -> 100]

Mathematica graphics

$\endgroup$

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.