gmt icon indicating copy to clipboard operation
gmt copied to clipboard

Let logarithimc plots accept negative values

Open phalucy opened this issue 2 years ago • 3 comments

Description of the desired feature

It is common now to have parameters varying from negative to positive with a large spread. To plot that, logarithmic or exponential plots may be good choices. However, GMT currently accepts positive ranges only since it only takes the u'=alog10(u)+b.

Could if judge the sign of u before taking the logarithmic transformation, and then append the sign back? Just like the symlog module in other plotting software. If so, the plotting module could easily handle the rest since it originally accepts both negative and positive values.

phalucy avatar Jan 01 '24 05:01 phalucy

👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. We appreciate that you took the time to contribute!

Please make sure you read our Contributing Guide and abide by our Code of Conduct.

welcome[bot] avatar Jan 01 '24 05:01 welcome[bot]

Would you be able to provide an actual example where this is used? If we were to add the transformation y = sign(x)*log10(abs(x)), I suppose x = 0 should give y = 0?

PaulWessel avatar Jan 01 '24 08:01 PaulWessel

What I want is something like the Symlog plots in Matplotlib. For example: https://matplotlib.org/stable/gallery/scales/symlog_demo.html They actually did something tricky that making the values near zero display linearlly.

I wish such a function could work in GMT.

Currently, what I've done is: I got X for x and A for y. ` #positive and negative values (but reversed) in one plot region=[-10,10,-5, 5] # for 10^-5 ~10^5 fig.shift_origin(yshift=1.4) fig.basemap(region=region,projection='X2.8/1.4', frame=['x20f10g100', 'y1+l"A"', 'Wne']) for i in range(0,len(A)): if A[i]*1.44 > 0: fig.plot(x=X[i], y=np.log10(A[i]), pen='0.1', fill=color[i], style='c0.1')

fig.shift_origin(yshift=-1.4) fig.basemap(region=region,projection='X2.8/-1.4', frame=['x20f10g100+l"A"', 'y1', 'WSe']) for i in range(0,len(A)): if A[i] < 0: fig.plot(x=X[i], y=np.log10(abs(A[i])), pen='0.1', fill=color[i], style='c0.1') `

After that I just modified the figure to change the labels on y-axis to 10^-5~10^5 & -10^-5~-10^5 manually

phalucy avatar Jan 01 '24 08:01 phalucy