2015-04-05 18 views
8

Dizinin yalnızca bir kısmını çizmek, x bölümünü sabitlemek, ancak y bölümünün otomatik ölçeklendirilmesini sağlamak istiyorum. Aşağıda gösterildiği gibi denedim, ama işe yaramıyor.Matplotlib - x ekseni ölçeğini ve autoscale y eksenini sabitleme

Herhangi bir öneriniz var mı?

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() 

cevap

5

Autoscaling her zaman bir veri dizi kullanır, bu nedenle y-ekseni X-sınırlar içinde değil, sadece ne y-veri, tam ölçüde ölçeklenir. kesinlikle en mantıklı cevabı önermektedir

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

Ben de bu fikri vardı ama alt kümesini yapma bu harika Python :) – Pygmalion

8

Joe Kington ederken o sadece gerekli verileri önerir: Eğer veri alt kümesini görüntülemek istiyorsanız

, o zaman sadece o alt kümesini çizmek için muhtemelen en kolay Çizilmiş olmalı, tüm verileri çizmek ve sadece belirli bir bölüme yakınlaştırmanın en iyi olacağı durumlar vardır. Ek olarak, yalnızca eksen nesnesini gerektiren bir "autoscale_y" işlevine sahip olmak güzel olurdu (yani, verilerin doğrudan kullanılmasını gerektiren here yanıtının aksine.)

Burada y'yi yeniden boyutlandıran bir işlev var.

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) 

Bu kesmek şeydir ve muhtemelen birçok durumda işe yaramaz, ancak basit bir arsa için, iyi çalışır: eksen görünür x bölgede olduğu verilere dayalı.

İşte bu fonksiyonu kullanarak basit bir örnek:

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

kadar basit olduğunu bilmiyordum, ancak arsa içinde axhline() varsa, başarısız olur. Onu ayarlamaya çalışacağım çünkü istediğim tam olarak bu. –

+0

I y_displayed = yd [((xd> lo =) (xd <= hi))] ile len halinde (xd) == 2 ve Xd [0] == 0.0 ve Xd [1] yerini == 1.0: y_displayed = yd # axhline işlemek için özel durum: y_displayed = yd [((xd> = lo) & (xd <= meri))] –

+0

Evet, autoscale_axis yok, büyük ihtimalle matplotlib'nin son güncellemesinde halihazırda uygulanmaktadır. Katkınız için teşekkürler, kullanıyorum ve harika çalışıyor! Bununla birlikte, tüm değer aralığını çizmek ve daha sonra yakınlaştırmak istediğinizde bile, @Joe Kinton'un çözümü sol paneldeki tüm aralığı ve sağdaki maskelenmiş değerleri çizerek daha basittir. – Hugo

İlgili konular