python need to convert a "linspace" into something more "logarithmic"

Viewed 93

Forgive me, I'm always been very bad at math, now trying to learn some python (and some math aswell) by coding.

I have this:

import numpy as np
import matplotlib.pyplot as plt

whole = 1 # percentage: 1 = 100%, 0.1 = 10% ecc 
nparts = 10 # how many "steps" we want to use
origin = 100 # starting value we

ranged = origin * whole # defining the percentage of our starting value

values = np.linspace(origin - ranged/2, origin + ranged/2, nparts * 2)

r = []
g = []
for v in values:
    if v > origin:
        r.append(v)
        #reds = f"{v} is {100*(v - origin)/origin}% of {origin}"
        #print(reds)

    else:
        g.append(v)
        #greens = f"{v} is {100*(v - origin)/origin}% of {origin}"
        #print(greens)
        
        
print("reds")
print(r)
print("greens")
print(g)

These last print(g) and print(r) output the numerical results.

If I plot this, you can clearly see what this does.

axes = plt.gca()

#origin BLUE 
plt.axhline(y=origin, color='b', linestyle='-')

#reds
for i in r:
        plt.axhline(y=i, color='r', linestyle='-')
#greens
for i in g:
        plt.axhline(y=i, color='g', linestyle='-')

plot

So as you can see given an origin (blue line) and giving a +/- percentage whole it creates n lines ( nparts ) both reds if they are > origin and green if < origin spreading them linearly values = np.linspace(origin - ranged/2, origin + ranged/2, nparts * 2) on this whole percentage from the origin value

now my question is: how can I spread those lines on a logarithmic way (don't get me wrong, I'm so bad at math I don't even know if what I'm looking for is logarithmic-related) I would like to achieve something like this (I did photoshop the plotted image). I would really love to keep that whole and maybe being able to add a new variable to "control" this logarithmic spreading

basically I need to find a way to find another function to replace values = np.linspace(origin - ranged/2, origin + ranged/2, nparts * 2) to achieve the desired result attached below. I tried both np.geomspace and np.logspace without any success, maybe I'm just bad or maybe I need to find another way to do this.

Desired result: desired result

Can you help me solve this out? Thanks a lot.

1 Answers

You can pass any linspace to np.log. This will give the logarithm of each point. To get the result within certain bounds, you can use a linear transformation: divide by the largest value and multiply with the desired range, perhaps add a baseline value.

For example:

values = np.log(np.linspace(1, 10, nparts))

r = 150 - 50 * (values / values[-1])
g =  50 + 50 * (values / values[-1])

This will result in the following plot:

logplot

If you need to include the origin and whole variables, here's one way to do that:

values = np.log(np.linspace(1, 10, nparts))
half_range = origin * whole / 2

g = origin + half_range * (1 - values / values[-1])
r = origin * 2 - g
Related