# ListPlot with different interval [duplicate]

I met a complicated function y=f(x) in my research, this function has no analytical expression, and only numerical values are accessible to me (So I can only use ListPlot rather than Plot). I need to plot it with points evenly distributed in my graph, and I don't know how to do it. Let me just simplify my problem as follows:

Now I am trying to plot y=1/x around x=0:

ListPlot[Table[{n,y = 1/n}, {n, -10, 10}]]


and I can get:

I am happy with those data with |n|>3, but I am not happy with the data around n=0, so I want to find a way to plot more data around n=0 while keep the data density elsewhere unchanged. I know I can plot two graphs with different range and interval of n and use Show[] to combine them together, but I hope to find a neat way to it. Thank you!

## marked as duplicate by corey979, Feyre, xzczd, MarcoB, m_goldberg plotting StackExchange.ready(function() { if (StackExchange.options.isMobile) return; $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() { var$hover = $(this).addClass('hover-bound'),$msg = $hover.siblings('.dupe-hammer-message');$hover.hover( function() { $hover.showInfoMessage('', { messageElement:$msg.clone().show(), transient: false, position: { my: 'bottom left', at: 'top center', offsetTop: -7 }, dismissable: false, relativeToBody: true }); }, function() { StackExchange.helpers.removeMessages(); } ); }); }); Jan 3 '17 at 18:42

• Just to make sure, you don't want to use Plot, right? – xzczd Jan 3 '17 at 2:19
• Does Plot[1/x, {x, -10, 10}, Mesh -> 30, MeshFunctions -> {"ArcLength"}, MeshStyle -> Red, PlotRange -> {-2, 2}, PlotStyle -> None] work for you? – J. M. is away Jan 3 '17 at 4:01
• Plot can be used on numeric functions: func[n_?NumericQ] := 1/n; Plot[func@n, {n, -1, 1}] – xzczd Jan 3 '17 at 5:11

So after the other answer and comment I really really hope you ment working with ListPlot. Otherwise im sad :D

-

So it's not an anwser with a pretty short code but it works well.

To uniformly distribute your points, we want the length between adjacent points to be constant. So we formulate:

$$l=\sqrt{(\Delta x)^2+(\Delta y)^2}$$ $$l=\sqrt{(x_1-x_2)^2+(1/x_1-1/x_2)^2}$$

Solving this for $x_2$ gives two solutions. One backward (the first) and one forward solution (represented by Root). So if we define a $l$ and a $y_{min,max}$-value

l = 1/5; (*length between points*)
yBorder = 2; (*max absolute y value*)
sol = x2 /. Solve[l == Sqrt[(x1 - x2)^2 + (1/x1 - 1/x2)^2], x2, Reals];


we could solve the points as long as they are in the range using Reap and Sow in a Do from both sides starting by $x=3$ and $x=-3$:

xPoints = Reap[
Do[
x = 3*(-1)^(i + 1); Sow[x];
y = 1/x;
While[Abs[y] <= yBorder, x = N[sol[[i]] /. {x1 -> x}]; Sow[x];
y = 1/x];
, {i, 1, 2}]
][[2, 1]];


getting everything together and ploting it:

l = 1/5; (*length between points*)
yBorder = 2; (*max absolute y value*)
xBorder = 3;
sol = x2 /. Solve[l == Sqrt[(x1 - x2)^2 + (1/x1 - 1/x2)^2], x2, Reals];
xPoints = Reap[
Do[
x = xBorder*(-1)^(i + 1); Sow[x];
y = 1/x;
While[Abs[y] <= yBorder, x = N[sol[[i]] /. {x1 -> x}]; Sow[x];
y = 1/x];
, {i, 1, 2}]
][[2, 1]];
yPoints = 1/xPoints;
points = Transpose[{xPoints, yPoints}];
ListPlot[points]


Attention: You should also take the AspectRatio and PlotRange into account, since it seems that for bigger $y$-values the distance between the adjacent points shrinks or grows which is not the case.

I've did it for you (which was more easier than i thought):

It uses the fact that we just need to stretch one of the coordinates to the PlotRange and AspectRatio:

$$l=\sqrt{(\Phi\cdot (y_{max}-y_{min})/(x_{max}-x_{min})\cdot\Delta x)^2+(\Delta y)^2}$$

Where $\Phi$ is the inverse AspectRatio which is by default the GoldenRatio.

l = 1; (*length between points*)
yBorder = 10; (*max absolute y value*)
xBorder = 50;
sol = x2 /.
Solve[l ==
Sqrt[(yBorder/xBorder)^2*
GoldenRatio^2*(x1 - x2)^2 + (1/x1 - 1/x2)^2], x2, Reals];
xPoints = Reap[
Do[
x = xBorder*(-1)^(i + 1); Sow[x];
y = 1/x;
While[Abs[y] <= yBorder, x = N[sol[[i]] /. {x1 -> x}]; Sow[x];
y = 1/x];
, {i, 1, 2}]
][[2, 1]];
yPoints = 1/xPoints;
points = Transpose[{xPoints, yPoints}];
ListPlot[points, PlotRange -> Full]


• Thank you! I can only use ListPlot since the real problem I met is so complicated that no analytical answer can be used for Plot. It is not neat, but I can accept it. – Jieyu You Jan 3 '17 at 3:55

If you are planning to use Plot then...

You can do it fairly easily with Piecewise

f[x_] := Piecewise[{{1/x, -10 <= x < 0}, {1/x, 0 < x <= 10}}]
Plot[f[x], {x, -10, 10}]


• Plot[1/x, {x, -10, 10}] will give this Plot – Bob Hanlon Jan 3 '17 at 3:30
• @BobHanlon You are right but the idea was split the interval. – zhk Jan 3 '17 at 10:07