在Matplotlib中将对数刻度和线性刻度结合起来

11
这里的示例清楚地展示了如何在原点处使用线性刻度以及其他地方使用对数刻度,可以参考“log”和“symlog”的区别。我想反过来,将1-100之间使用对数刻度,100-1000之间使用线性刻度。有哪些选项可供选择?但是像上面的图那样尝试并不起作用。
    import matplotlib.pyplot as plt
    plt.figure()
    plt.errorbar(x, y, yerr=yerrors)
    plt.xscale('symlog', linthreshx= (100,1000))

问题似乎是因为 linthreshx 定义了取范围 (-x,x)。所以如果 x 是 5,我们会在 (-5,5) 上得到一个线性刻度。这限制了一个的起点。我原以为选择不同的范围就可以解决问题,但事实并非如此。有什么建议吗?

1
为什么不直接使用1到1000的对数刻度?我不明白你的目标是什么?你能提供一张你想要实现的草图吗? - David Zwicker
可能最后一句话有错别字?标题说是对数和线性,但问题中说有两个对数刻度。 - Bonlenfum
3个回答

11

来自用户user1318806对cphlewis的回应

谢谢你。实际上我想要在x轴上结合log和linear,而不是y轴。但我认为你的代码应该很容易适应。

你好!如果您想在x轴上结合log和linear(仿照Duncan Watts和CubeJockey的代码):

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

# Numbers from -50 to 50, with 0.1 as step
xdomain = np.arange(-50,50, 0.1)

axMain = plt.subplot(111)
axMain.plot(np.sin(xdomain), xdomain)
axMain.set_xscale('linear')
axMain.set_xlim((0.5, 1.5))
axMain.spines['left'].set_visible(False)
axMain.yaxis.set_ticks_position('right')
axMain.yaxis.set_visible(False)


divider = make_axes_locatable(axMain)
axLin = divider.append_axes("left", size=2.0, pad=0, sharey=axMain)
axLin.set_xscale('log')
axLin.set_xlim((0.01, 0.5))
axLin.plot(np.sin(xdomain), xdomain)
axLin.spines['right'].set_visible(False)
axLin.yaxis.set_ticks_position('left')
plt.setp(axLin.get_xticklabels(), visible=True)

plt.title('Linear right, log left')

上面的代码生成了:Answer1

(杂项) 这里是标题和右侧无刻度标记的极小修正:

# Fix for: title + no tick marks on the right side of the plot
ax2 = axLin.twinx()
ax2.spines['left'].set_visible(False)
ax2.tick_params(axis='y',which='both',labelright='off')

添加这些代码将会得到以下结果:Answer2


欢迎来到SO。在这种情况下 - 回答在评论中提出的问题 - 你完全可以在SO上提出一个全新的问题,可能会链接回源,并回答自己的问题。请参阅http://stackoverflow.com/help/self-answer。 - SiKing

8

我猜你想让线性在原点附近,对数在远处 -- 因为`symlog'是反过来的 -- 我找不到这样好看的数据,但你可以用axes_grid组合在一起:

# linear and log axes for the same plot?
# starting with the histogram example from 
# http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

# Numbers from -50 to 50, with 0.1 as step
xdomain = np.arange(-50,50, 0.1)

axMain = plt.subplot(111)
axMain.plot(xdomain, np.sin(xdomain))
axMain.set_yscale('log')
axMain.set_ylim((0.01, 0.5))
divider = make_axes_locatable(axMain)
axLin = divider.append_axes("top", size=2.0, pad=0.02, sharex=axMain)
axLin.plot(xdomain, np.sin(xdomain))

axLin.set_xscale('linear')
axLin.set_ylim((0.5, 1.5))
plt.title('Linear above, log below')

plt.show()

enter image description here


谢谢。实际上我想要的是在x轴上进行对数和线性的组合,而不是y轴。但我认为你的代码应该很容易适应。我会尽快尝试一下。我想做的是symlog所做的事情,但顺序相反。symlog在x轴上进行线性+对数运算。我想在x轴上进行对数+线性运算。 - user1318806
只要共享轴使用相同的比例,就应该没问题;是的,make_axes_locatable可以在任何方向上添加一个轴。(或两个方向上都可以。) - cphlewis

3
这个解决方案对cphlewis的回答进行了补充,以便实现平滑过渡,并且绘图似乎具有一致的刻度标记。我的修改添加了以下三行:

axLin.spines['bottom'].set_visible(False)

axLin.xaxis.set_ticks_position('top')

plt.setp(axLin.get_xticklabels(), visible=False)

总的来说,这段代码是让x轴刻度标签不可见。
# linear and log axes for the same plot?
# starting with the histogram example from 
# http://matplotlib.org/mpl_toolkits/axes_grid/users/overview.html
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np

# Numbers from -50 to 50, with 0.1 as step
xdomain = np.arange(-50,50, 0.1)

axMain = plt.subplot(111)
axMain.plot(xdomain, np.sin(xdomain))
axMain.set_yscale('log')
axMain.set_ylim((0.01, 0.5))
axMain.spines['top'].set_visible(False)
axMain.xaxis.set_ticks_position('bottom')

divider = make_axes_locatable(axMain)
axLin = divider.append_axes("top", size=2.0, pad=0, sharex=axMain)
axLin.plot(xdomain, np.sin(xdomain))
axLin.set_xscale('linear')
axLin.set_ylim((0.5, 1.5))

# Removes bottom axis line
axLin.spines['bottom'].set_visible(False)
axLin.xaxis.set_ticks_position('top')
plt.setp(axLin.get_xticklabels(), visible=False)

plt.title('Linear above, log below')

plt.show()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接