Scaling the x-axis in ListLogLogPlot[] or ListLogPlot[] in lieu of DataRange

I will present my existing workaround but I am wondering if there is a better solution that takes less time (my solution seems to ~double the time it takes to produce the desired plot). Using DataRange would be ideal, but I’m either missing something or it doesn’t work when a ListPlot has logarithmic axes.

I have some data in a list (1D) that I’m plotting with ListLogLogPlot. I know that the x-values should range from 1 to 5000; with ListPlot I would just use DataRange to take care of this. However, DataRange seems to do nothing when using ListLogPlot or ListLogLogPlot.

Let’s do an example:

fakedata = Table[1/x, {x, 1, 100, .1}];
ListLogLogPlot[fakedata, Frame -> True, ImageSize->500]

Adding DataRange->{1,5000} does nothing to the plot. I can instead make a new list, composed of the x-values since I know they should vary linearly from 1 to 5000 over the length of the data:

sol = Solve[1 == m + b && 5000 == m*Length@fakedata + b, {m, b}];
fakexvals =
Table[Evaluate[x*m + b] /. First@sol, {x, 1, Length@fakedata}];

Using this new list, I can get the desired plot:

ListLogLogPlot[Transpose[{fakexvals, fakedata}], Frame -> True,
ImageSize -> 500]

This is ok for this example, but it becomes cumbersome with the data set is large. It appears to take Mathematica roughly twice as long to create the list plot from x-y pairs versus just y-values. I have some data sets with 200,000 points and for these generating a list plot from {x,y} pairs takes between 10-20 seconds.

=================

DataRange only works if you give a list of single values to these functions. It does not work if you give a list of value pairs.
– Szabolcs
May 13 ’13 at 23:27

=================

3

=================

You could use Rescale to map the range {1,100} to {1,5000} :

rescaledX = Rescale[#, {1, 100}, {1, 5000}] & /@ Table[x, {x, 1, 100, .1}];

ListLogLogPlot[Transpose[{rescaledX, fakedata}], Frame -> True, ImageSize -> 500]

Ah that’s a nifty little function that I wasn’t familiar with. The issue still remains, though, that it would be a plot of {x,y} pairs which makes it take much longer.
– skratch
May 13 ’13 at 21:35

In v8.0 on Windows 7, DataRange seems to do what it’s supposed to:

data = Table[1/x, {x, 1, 100, .1}];
ListLogLogPlot[data,
Frame -> True,
ImageSize -> 500,
DataRange -> {1, 5000},
PlotRange -> {{1, 5000}, {0.01, 1}}]

Wow you’re right. I happen to still have v8 installed so I loaded it up and checked. It looks like in v9 it no longer works. That’s very strange.
– skratch
May 13 ’13 at 22:04

As mentioned before, this seems to be a MM9 bug (as it was working in MM8 correctly). As a quick workaround I put together a FixDataRange function:

FixDataRange[dr_][data_] := Module[{res, xd , nop},
If[Length[data[[1]]] == 0,
nop = Length[data];
xd = Rescale[Range[nop], {1, nop}, dr];
res = Transpose[{xd, data}];
,
res = Map[FixDataRange[dr], data, {1}];
];

res
];

(* Test FixDataRange *)
data = Table[Abs[Sin[x]], {x, 0, 10, 0.1}];
data2 = Table[Abs[Sin[2*x]], {x, 0, 10, 0.1}];

ListLogPlot[data, DataRange -> {0, 10}]
ListLogPlot[FixDataRange[{0, 10}][data]]
ListLogPlot[FixDataRange[{0, 10}][{data, data2}]]