【问题标题】:Matplotlib: twinx plot hidden behind main axis backgroundMatplotlib:隐藏在主轴背景后面的 twinx 图
【发布时间】:2018-08-01 09:10:49
【问题描述】:

我正在努力展示双轴图和主轴图。这是我正在做的事情:

  1. 我创建主轴和双轴。
  2. 我将主轴的 zorder 设置为比双轴的 zorder 更高的值,因为我希望事件处理程序选择主轴的事件(即跟踪工具栏中的 Y 轴)
  3. 然后,我绘制了两个图形,位于双轴的补丁隐藏在主轴的背景后面。 (我知道这一点,因为如果我取消注释 a.patch.set_visible(False) 行,我可以看到双轴图)

但是,我想保留跟踪主轨道的 Y 轴和背景的能力,因为它们具有不同的比例。 这里有一个最小的例子:


import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

import sys
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk


root = Tk.Tk()
root.wm_title("Embedding in TK")


f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)
a.grid(True)
a.set_facecolor('grey')
aTwin = a.twinx()
aTwin.grid(False)



# PROBLEM HERE # Whenever I uncomment this, "aTwin" axis remains hidden.
# Set "a" axis zorder to higher value so that event handler tracks y axis from "a" and not from "aTwin"
a.set_zorder(aTwin.get_zorder() + 1)

#a.patch.set_visible(False) # Uncomment to show volume, but I lose the background from the main axis. I cannot use twinx axis' background/grid since they are different scales

x = np.arange(0.0, 2, 0.01)
y1 = abs(np.sin(2*np.pi*x))
y2 = 10.2*np.sin(4*np.pi*x)

aTwin.set_ylim(0, 3*max(y1))

a.plot(x, y2)
aTwin.fill_between(x, 0, y1, alpha = 0.4)
a.set_ylabel('between y1 and 0')


# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()

canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

def _quit():
    root.quit()
    root.destroy()

button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop()

提前感谢您花时间阅读此问题。 :)

【问题讨论】:

    标签: python matplotlib tkinter z-order


    【解决方案1】:

    您似乎想打开第一个轴的网格,将其补丁设置为不可见,将双轴的补丁设置为可见,并将其着色为灰色。那么把原来的轴移到前面就没有问题了。

    import numpy as np
    import matplotlib.pyplot as plt
    
    f = plt.figure(figsize=(5, 4), dpi=100)
    ax = f.add_subplot(111)
    axTwin = ax.twinx()
    
    # Turn grid of a on.
    ax.grid(True)
    axTwin.grid(False)
    
    # Set ax's patch invisible
    ax.patch.set_visible(False)
    # Set axtwin's patch visible and colorize it in grey
    axTwin.patch.set_visible(True)
    axTwin.patch.set_facecolor('grey')
    
    # move ax in front
    ax.set_zorder(axTwin.get_zorder() + 1)
    
    x = np.arange(0.0, 2, 0.01)
    y1 = abs(np.sin(2*np.pi*x))
    y2 = 10.2*np.sin(4*np.pi*x)
    
    axTwin.set_ylim(0, 3*max(y1))
    
    ax.plot(x, y2)
    axTwin.fill_between(x, 0, y1, alpha = 0.4)
    ax.set_ylabel('between y1 and 0')
    
    plt.show()
    

    【讨论】:

    • 非常感谢。那,显然解决了问题。我很困惑,以至于我没有想到这个简单的解决方案。无论如何,有没有办法在主轴的图和它的背景之间绘制双轴?
    • 我的意思是,我的理想顺序是,从上到下:正弦图 (ax)、fill_between 图(axTwin)、主轴的网格和补丁 (ax)、axTwin 的网格和补丁不活动。
    • 看来您需要在后台使用第三个轴。
    • 嗯,我明白了。好吧,再次感谢您的时间和回答:)
    猜你喜欢
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多