2015-04-05 315 views
8

我想只绘制数​​组的一部分,固定x部分,但让y部分自动缩放。我尝试如下所示,但它不起作用。Matplotlib - 固定x轴缩放和自动缩放y轴

有什么建议吗?

import numpy as np 
import matplotlib.pyplot as plt 

data=[np.arange(0,101,1),300-0.1*np.arange(0,101,1)] 

plt.figure() 

plt.scatter(data[0], data[1]) 
plt.xlim([50,100]) 
plt.autoscale(enable=True, axis='y') 

plt.show() 

回答

5

自动配置功能始终使用全范围的数据的,所以y轴由y-数据中,x的限度内不只是什么的充分的程度进行缩放。

如果你想显示的数据的一个子集,那么它可能是最简单的绘制只子集:

import numpy as np 
import matplotlib.pyplot as plt 

x, y = np.arange(0,101,1) ,300 - 0.1*np.arange(0,101,1) 
mask = (x >= 50) & (x <= 100) 

fig, ax = plt.subplots() 
ax.scatter(x[mask], y[mask]) 

plt.show() 
+0

我也有过这样的想法,但我不知道这使得子集是在Python :) – Pygmalion 2015-04-06 07:49:05

8

虽然Joe Kington无疑提出了最明智的答案时,他建议,只有需要的数据被绘制,有些情况下最好绘制所有的数据并放大到某个部分。此外,具有仅需要轴对象的“自动缩放_y”功能将是很好的(即,不同于需要直接使用数据的答案here)。

这里是一个函数,基于这是在可见的X区域的数据轴:

def autoscale_y(ax,margin=0.1): 
    """This function rescales the y-axis based on the data that is visible given the current xlim of the axis. 
    ax -- a matplotlib axes object 
    margin -- the fraction of the total height of the y-data to pad the upper and lower ylims""" 

    import numpy as np 

    def get_bottom_top(line): 
     xd = line.get_xdata() 
     yd = line.get_ydata() 
     lo,hi = ax.get_xlim() 
     y_displayed = yd[((xd>lo) & (xd<hi))] 
     h = np.max(y_displayed) - np.min(y_displayed) 
     bot = np.min(y_displayed)-margin*h 
     top = np.max(y_displayed)+margin*h 
     return bot,top 

    lines = ax.get_lines() 
    bot,top = np.inf, -np.inf 

    for line in lines: 
     new_bot, new_top = get_bottom_top(line) 
     if new_bot < bot: bot = new_bot 
     if new_top > top: top = new_top 

    ax.set_ylim(bot,top) 

这是一个黑客的东西,可能不会在很多情况下工作,但对于一个简单的情节,它工作得很好。

下面是使用这个函数的简单例子:

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(-100,100,1000) 
y = x**2 + np.cos(x)*100 

fig,axs = plt.subplots(1,2,figsize=(8,5)) 

for ax in axs: 
    ax.plot(x,y) 
    ax.plot(x,y*2) 
    ax.plot(x,y*10) 
    ax.set_xlim(-10,10) 

autoscale_y(axs[1]) 

axs[0].set_title('Rescaled x-axis') 
axs[1].set_title('Rescaled x-axis\nand used "autoscale_y"') 

plt.show() 

enter image description here

+0

那么简单这是伟大的,但如果图中有axhline(),则失败。我会尽量调整它,因为这正是我想要的。 – 2016-08-26 05:14:40

+0

我取代 y_displayed =码[((XD> = LO)&(XD <= HI))] 与 如果len(XD)== 2和xD [0] == 0.0和xD [1] == 1.0:y_displayed = yd #special case处理axhline else:y_displayed = yd [((xd> = lo)&(xd <= hi))] – 2016-08-26 05:22:26

+0

是的,很遗憾没有autoscale_axis,可能它可能是已经在最新的matplotlib更新中实现。感谢您的贡献,我使用它并且非常棒!但是,即使您想要绘制整个范围的值然后放大,@Joe Kinton的解决方案通过绘制左侧面板上的所有范围和右侧面板上的蒙版值更简单。 – Hugo 2016-09-28 19:43:54