ฉันจะเชื่อมโยงแกนของแผน imshow สำหรับการซูมและการแพนได้อย่างไร

สมมติว่าฉันมีฟิกเกอร์แคนวาสที่มี 3 แปลง... 2 ภาพเป็นรูปภาพที่มีขนาดเท่ากันซึ่งลงจุดด้วย imshow และอีกภาพหนึ่งเป็นแผนย่อยประเภทอื่น ฉันต้องการที่จะเชื่อมโยงแกน x และ y ของแปลง imshow เพื่อที่ว่าเมื่อฉันซูมเข้าอันหนึ่ง (โดยใช้เครื่องมือซูมที่จัดทำโดย NavigationToolbar) ส่วนอีกอันจะซูมไปยังพิกัดเดียวกัน และเมื่อฉันแพนในอันหนึ่ง กระทะอื่นๆก็เช่นกัน

วิธีการพล็อตย่อย เช่น การกระจายและฮิสโตแกรมสามารถส่งผ่าน kwargs ที่ระบุแกนสำหรับ sharex และ sharey ได้ แต่ imshow ไม่มีการกำหนดค่าดังกล่าว

ฉันเริ่มแฮ็กวิธีแก้ปัญหานี้ด้วยการแบ่งคลาสย่อย NavigationToolbar2WxAgg (แสดงด้านล่าง)... แต่มีปัญหาหลายประการที่นี่ 1) สิ่งนี้จะเชื่อมโยงแกนของแปลงทั้งหมดในผืนผ้าใบเนื่องจากสิ่งที่ฉันทำทั้งหมดคือกำจัดการตรวจสอบสำหรับ a.in_axes() 2) สิ่งนี้ใช้ได้ดีสำหรับการแพน แต่การซูมทำให้แผนย่อยทั้งหมดซูมจากส่วนกลางเดียวกัน ไม่ใช่จากจุดเดียวกันในแต่ละแกนของมัน

ใครสามารถแนะนำวิธีแก้ปัญหาได้บ้าง

ขอบคุณมาก! -อดัม

from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
class MyNavToolbar(NavigationToolbar2WxAgg):
    def __init__(self, canvas, cpfig):
        NavigationToolbar2WxAgg.__init__(self, canvas)

    # overrided
    # As mentioned in the code below, the only difference here from overridden
    # method is that this one doesn't check a.in_axes(event) when deciding which
    # axes to start the pan in...
    def press_pan(self, event):
        'the press mouse button in pan/zoom mode callback'

        if event.button == 1:
            self._button_pressed=1
        elif  event.button == 3:
            self._button_pressed=3
        else:
            self._button_pressed=None
            return

        x, y = event.x, event.y

        # push the current view to define home if stack is empty
        if self._views.empty(): self.push_current()

        self._xypress=[]
        for i, a in enumerate(self.canvas.figure.get_axes()):
            # only difference from overridden method is that this one doesn't
            # check a.in_axes(event)
            if x is not None and y is not None and a.get_navigate():
                a.start_pan(x, y, event.button)
                self._xypress.append((a, i))
                self.canvas.mpl_disconnect(self._idDrag)
                self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.drag_pan)

    # overrided
    def press_zoom(self, event):
        'the press mouse button in zoom to rect mode callback'
        if event.button == 1:
            self._button_pressed=1
        elif  event.button == 3:
            self._button_pressed=3
        else:
            self._button_pressed=None
            return

        x, y = event.x, event.y

        # push the current view to define home if stack is empty
        if self._views.empty(): self.push_current()

        self._xypress=[]
        for i, a in enumerate(self.canvas.figure.get_axes()):
            # only difference from overridden method is that this one doesn't
            # check a.in_axes(event) 
            if x is not None and y is not None and a.get_navigate() and a.can_zoom():
                self._xypress.append(( x, y, a, i, a.viewLim.frozen(), a.transData.frozen()))

        self.press(event)

person Adam Fraser    schedule 27.05.2010    source แหล่งที่มา


คำตอบ (1)


ฉันไม่รู้ว่า sharex สามารถส่งผ่านไปยัง add_subplot...

f = plt.figure()
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212, sharex=ax1, sharey=ax1)
ax1.imshow(np.random.randn(10,10), interpolation='nearest')
ax2.imshow(np.random.randn(10,10), interpolation='nearest')
f.canvas.draw()

อย่างไรก็ตาม หากคุณพยายามทำสิ่งต่อไปนี้เพื่อตั้งค่าวัตถุแกนของคุณสำหรับการแสดงรูปภาพ

ax1.axis('image')

คุณจะได้รับ:

ValueError: adjustable must be "datalim" for shared axes

พวก matplotlib บอกฉันว่าฉันสามารถใช้ได้

ax1.set_adjustable("box-forced")
ax2.set_adjustable("box-forced")

แทน แต่มันใช้งานไม่ได้สำหรับฉันเมื่อใช้ matplotlib เวอร์ชัน 0.98.5.3 ... ฉันคิดว่ามันจะใช้กับเวอร์ชันที่ใหม่กว่า จะอัปเดตเมื่อฉันได้ยินกลับ

person Adam Fraser    schedule 27.05.2010