# DensityPlot with logarithmic xy-axes and logarithmic color scale

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:

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]

• 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? – MarcoB May 23 '16 at 19:41
• Have you seen this? – J. M.'s discontentment May 23 '16 at 19:43
• @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. – stef May 23 '16 at 20:08
• I'd define g[x_,y_] := f[10^x, 10^y] and plot g with the range {x, -6, 0}, {y, -4, -3}. – wxffles May 23 '16 at 23:14

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] 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 -> {ChartingScaledTicks[{Log, Exp}],
ChartingScaledTicks[{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}] 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] &)] 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 -> {ChartingScaledTicks[{Log, Exp}],
ChartingScaledTicks[{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] 