【问题标题】:Matplotlib widget used on a plot produced by another matplotlib widgetMatplotlib 小部件用于由另一个 matplotlib 小部件生成的绘图
【发布时间】:2016-11-06 19:37:04
【问题描述】:

我正在尝试使用 matplotlib LassoSelector 从散点图中选择一些点,并只为选定的点生成一个单独的图形。当我尝试在第二个绘图上使用另一个 matplotlib 小部件时,它不起作用,但没有错误或警告消息。下面是一个使用 LassoSelector 和 SpanSelector 的最小示例。

我也尝试了其他小部件; Button 小部件显示按钮,但未执行按钮按下时的操作。

import numpy as np
from matplotlib.pyplot import *
from matplotlib.widgets import SpanSelector, LassoSelector
from matplotlib.path import Path

def onselect(verts):
    global xys,data

    #get indexes of selected points
    path = Path(verts)
    xysn = xys.get_offsets()
    ind = np.nonzero([path.contains_point(xy) for xy in xysn])[0]

    #plot the second figure
    fig=figure(2)
    ax=fig.add_subplot(111)
    ax.hist(data[:,0][ind],10)

    #this should be executed when SpanSelector is used
    def action(min,max):
        print min,max

    #try to do SpanSelector (this fails)
    span=SpanSelector(ax,action,'horizontal')

    show()

#initialize a figure
fig=figure(1)
ax=fig.add_subplot(111)

#create data
data=np.array([[1,6], [4,8],[0,4],[4,2],[9,6],[10,8],[2,2],[5,5],[0,4],[4,5]])

#plot data
xys=ax.scatter(data[:,0],data[:,1])

#select point by drawing a path around them
lasso = LassoSelector(ax, onselect=onselect)

show()

【问题讨论】:

    标签: python matplotlib widget matplotlib-widget


    【解决方案1】:

    matplotlib 小部件是事件驱动的,因此请等待用户输入。您的代码的问题是您正在尝试使用新的事件处理程序SpanSelector 创建一个新图形。我不确定您是否可以根据以前的事件添加新事件,并且在 SpanSelector 注释掉的情况下,我收到以下错误,

    QCoreApplication::exec: The event loop is already running
    

    所以新事件LassoSelector 没有注册,用户输入没有被拾取(并且新图没有出现)。最好在代码开头创建所有图形并注册所有可能的事件。以下应该更接近你想要做的,

    import numpy as np
    from matplotlib.pyplot import *
    from matplotlib.widgets import SpanSelector, LassoSelector
    from matplotlib.path import Path
    
    #this should be executed when LassoSelector is used
    def onselect(verts):
        global xys,data
    
        #get indexes of selected points
        path = Path(verts)
        xysn = xys.get_offsets()
        ind = np.nonzero([path.contains_point(xy) for xy in xysn])[0]
    
        #Clear and update bar chart
        h, b = np.histogram(data[:,0][ind],10)
        for rect, bars in zip(rects, h):
            rect.set_height(bars)
        ax2.bar(mb, h, align='center')
        draw()
    
    #this should be executed when SpanSelector is used
    def action(min,max):
        print min,max
    
    #initialize figures
    fig1=figure(1)
    ax1=fig1.add_subplot(111)
    
    fig2=figure(2)
    ax2=fig2.add_subplot(111)
    
    #create data
    data=np.array([[1,6],[4,8],[0,4],[4,2],[9,6],[10,8],[2,2],[5,5],[0,4],[4,5]])
    
    #plot data
    xys=ax1.scatter(data[:,0],data[:,1])
    
    #Plot initial histogram of all data
    h, b = np.histogram(data[:,0],10)
    mb = [0.5*(b[i]+b[i+1]) for i in range(b.shape[0]-1)]
    rects = ax2.bar(mb, h, align='center')
    
    #Register lasso selector
    lasso = LassoSelector(ax1, onselect=onselect)
    
    #Register SpanSelector 
    span=SpanSelector(ax2,action,'horizontal')
    
    show()
    

    注意,为了更新条形图,它比绘图更棘手,所以我在这里使用了这个答案Dynamically updating a bar plot in matplotlib

    由于某种原因,直方图图 2 仅在您单击它时才会更新。我会考虑使用带有两个轴的单个图形,这可能更容易使用,

    fig, ax = subplots(2,1)
    ax1 = ax[0]; ax2 = ax[1]
    

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 2016-07-13
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      相关资源
      最近更新 更多