ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – 让Lasso在matplotlib中的子图上正常工作

2019-07-03 08:45:50  阅读:303  来源: 互联网

标签:python python-2-7 matplotlib plot numpy


我想创建一个散点图矩阵,它将由一些子图组成.我从.txt文件中提取了我的数据,并创建了一个形状数组(x,y,z,p1,p2,p3,p4).数组的前三列表示来自原始图像的这些数据来自的x,y,z坐标,以及最后四列(p1,p2,p3,p4)的一些其他参数.因此,在数组的每一行中,参数p1,p2,p3,p4具有相同的坐标(x,y,z).在散点图中,我想要将每个p_i(例如p1)参数可视化为对另一个p_i(例如p2,p3,p4)参数.

我想在每个子图中绘制一个感兴趣区域(ROI),突出显示每个子图中ROI中包含的点.在每个子图中,可视化不同的参数(例如,p1对p2),但是对于每个子图中的一个点,在其余子图中存在具有相同的x,y,z坐标的另一个点.我使用matplotlib示例Lasso实现了ROI的绘制.此代码实现的示例如下图所示.

我的实施出现故障.我可以在每个子图中绘制套索,但是当在特定子图中绘制套索时,点会被突出显示,该子图对应于我的代码中的LassoManager函数的第一次调用(在我的代码选择器1中).从下图中可以看出,给出了可以在不同子图中绘制的套索的初始值,但是只使用选择器1中对应的id导致代码故障,独立于我绘制的子图中投资回报率.

这是我的代码:

"""
Show how to use a lasso to select a set of points and get the indices
of the selected points.  A callback is used to change the color of the
selected points

This is currently a proof-of-concept implementation (though it is
usable as is).  There will be some refinement of the API.
"""


from matplotlib.widgets import Lasso
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from matplotlib import path


import matplotlib.pyplot as plt
import numpy as np

class Datum(object):
      colorin = colorConverter.to_rgba('red')
      colorout = colorConverter.to_rgba('blue')
      def __init__(self, x, y, include=False):
          self.x = x
          self.y = y
          if include: self.color = self.colorin
          else: self.color = self.colorout

class LassoManager(object):
    #class for highlighting region of points within a Lasso
      def __init__(self, ax, data):


          self.axes = ax
          self.canvas = ax.figure.canvas
          self.data = data
          self.Nxy = len(data)

          facecolors = [d.color for d in data]
          self.xys = [(d.x, d.y) for d in data]
          fig = ax.figure
          self.collection = RegularPolyCollection(
             fig.dpi, 6, sizes=(1,),
             facecolors=facecolors,
             offsets = self.xys,
             transOffset = ax.transData)

          ax.add_collection(self.collection)

          self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)

      def callback(self, verts):
          facecolors = self.collection.get_facecolors()
          print "The id of this lasso is", id(self)


          p = path.Path(verts)
          ind = p.contains_points(self.xys)
          #ind prints boolean array of points in subplot where true means that the point is included

          for i in range(len(self.xys)):


              if ind[i]:

                # facecolors[i] = Datum.colorin
                axes[0][0].plot(x[i], y[i], 'ro',  ls='',  picker=3)
                axes[2][0].plot(x[i], y1[i], 'ro',  ls='',  picker=3)
                axes[1][0].plot(x[i], x1[i], 'ro',  ls='',  picker=3)
                axes[1][4].plot(y[i], x1[i], 'ro',  ls='',  picker=3)
                axes[2][5].plot(x1[i], y1[i], 'ro',  ls='',  picker=3)
                axes[2][6].plot(y[i], y1[i], 'ro',  ls='',  picker=3)
                # print ind[i], x[i], y[i], x1[i], y1[i]

              else:

                # facecolors[i] = Datum.colorout
                axes[0][0].plot(x[i], y[i], 'bo',  ls='',  picker=3)
                axes[2][0].plot(x[i], y1[i], 'bo',  ls='',  picker=3)
                axes[1][0].plot(x[i], x1[i], 'bo',  ls='',  picker=3)
                axes[1][7].plot(y[i], x1[i], 'bo',  ls='',  picker=3)
                axes[2][8].plot(x1[i], y1[i], 'bo',  ls='',  picker=3)
                axes[2][9].plot(y[i], y1[i], 'bo',  ls='',  picker=3)

          plt.draw()


          self.canvas.draw_idle()
          self.canvas.widgetlock.release(self.lasso)
          del self.lasso
          # noinspection PyArgumentList


      def onpress(self, event):
          if self.canvas.widgetlock.locked(): return
          if event.inaxes is None: return

          self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)

          # acquire a lock on the widget drawing
          self.canvas.widgetlock(self.lasso)




if __name__ == '__main__':

   dat = np.loadtxt(r"parameters.txt")
   x, y = dat[:, 3], dat[:, 4]  #p1,p2
   x1, y1 = dat[:, 5], dat[:, 6]  #p3,p4

   a = np.array([x,y])  #p1,p2
   a = a.transpose()

   b = np.array([x,y1])  #p1,p4
   b = b.transpose()

   c = np.array([x,x1])  #p1,p3
   c = c.transpose()

   d = np.array([y,x1])  #p3,p2
   d = d.transpose()

   e = np.array([x1,y1])  #p3,p4
   e = e.transpose()

   f = np.array([y,y1])  ##p2, p4
   f = f.transpose()


   data = []

   data0 = [Datum(*xy) for xy in a]   #p1,p2
   data.append(data0)
   data1 = [Datum(*xy) for xy in b]   #p1,p4
   data.append(data1)
   data2 = [Datum(*xy) for xy in c]   #p1,p3
   data.append(data2)
   data3 = [Datum(*xy) for xy in d]   #p3,p2
   data.append(data3)
   data4 = [Datum(*xy) for xy in e]   #p3,p4
   data.append(data4)
   data5 = [Datum(*xy) for xy in f]   #p2, p4
   data.append(data5)

   #print data
   #print len(data)

   fig, axes = plt.subplots(ncols=3, nrows=3)

   axes[0][0].plot(x, y, 'bo',  ls='',  picker=3)
   axes[0][0].set_xlabel('p1')
   axes[0][0].set_ylabel('p2')
   axes[0][0].set_xlim((min(x)-50, max(x)+50))
   axes[0][0].set_ylim((min(y)-50, max(y)+50))
   selector1 = LassoManager(axes[0][0], data[0])
   print "selector1 is", id(selector1)      #lman.append(l1)

   #p1 vs p4
   axes[2][0].plot(x, y1, 'bo',  ls='',  picker=3)
   axes[2][0].set_xlabel('p1')
   axes[2][0].set_ylabel('p4')
   axes[2][0].set_xlim((min(x)-50, max(x)+50))
   axes[2][0].set_ylim((min(y1)-40, max(y1)+50))
   selector2 = LassoManager(axes[2][0], data[1])
   print "selector2 is", id(selector2)


   #p1 vs p3
   axes[1][0].plot(x, x1, 'bo',  ls='',  picker=3)
   axes[1][0].set_xlabel('p1')
   axes[1][0].set_ylabel('p3')
   axes[1][0].set_xlim((min(x)-50, max(x)+50))
   axes[1][0].set_ylim((min(x1)-40, max(x1)+50))
   selector3 = LassoManager(axes[1][0], data[2])
   print "selector3 is", id(selector3)

   #p2 vs p3
   axes[1][10].plot(y, x1, 'bo',  ls='',  picker=3)
   axes[1][11].set_xlabel('p2')
   axes[1][12].set_ylabel('p3')
   axes[1][13].set_xlim((min(y)-50, max(y)+50))
   axes[1][14].set_ylim((min(x1)-40, max(x1)+50))
   selector4 =  LassoManager(axes[1][15], data[3])
   print "selector4 is", id(selector4)




   #p2 vs p4
   axes[2][16].plot(y, y1, 'bo',  ls='',  picker=3)
   axes[2][17].set_xlabel('p2')
   axes[2][18].set_ylabel('p4')
   axes[2][19].set_xlim((min(y)-50, max(y)+50))
   axes[2][20].set_ylim((min(y1)-40, max(y1)+50))
   selector5 = LassoManager(axes[2][21], data[5])
   print "selector5 is", id(selector5)


   #p3 vs p4
   axes[2][22].plot(x1, y1, 'bo',  ls='',  picker=3)
   axes[2][23].set_xlabel('p3')
   axes[2][24].set_ylabel('p4')
   axes[2][25].set_xlim((min(x1)-50, max(x1)+50))
   axes[2][26].set_ylim((min(y1)-40, max(y1)+50))
   selector6 = LassoManager(axes[2][27], data[4])
   print "selector6 is", id(selector6)


   #non-visible subplots
   axes[0][28].plot(x,x)
   axes[0][29].set_visible(False)
   axes[0][30].plot(y,y)
   axes[0][31].set_visible(False)
   axes[1][32].plot(x1,x1)
   axes[1][33].set_visible(False)

   plt.subplots_adjust(left=0.1, right=0.95, wspace=0.6, hspace=0.7)

   plt.show()

为什么这会在我的代码中发生?代码中没有错误,但它无法正常工作.任何帮助将不胜感激!!

解决方法:

据我所知,问题是在每个init上你用一个新的替换画布的button_press_event.

您很可能需要使用一个button_press_event回调来处理所有轴(因为它们都通过相同的画布对象进行交互).

固定

下面是一个功能示例,基于文档中的官方套索示例.

我尝试的方法是只创建一个LassoManager(因为它与每个图形只有一个画布交互)但让轴,数据等成为每个子图的列表.

然后,回调访问current_axis成员以确定当前哪个轴处于活动状态.

"""
Show how to use a lasso to select a set of points and get the indices
of the selected points.  A callback is used to change the color of the
selected points

This is currently a proof-of-concept implementation (though it is
usable as is).  There will be some refinement of the API.
"""
from matplotlib.widgets import Lasso
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from matplotlib import path

import matplotlib.pyplot as plt
from numpy import nonzero
from numpy.random import rand

class Datum(object):
    colorin = colorConverter.to_rgba('red')
    colorout = colorConverter.to_rgba('blue')
    def __init__(self, x, y, include=False):
        self.x = x
        self.y = y
        if include: self.color = self.colorin
        else: self.color = self.colorout


class LassoManager(object):
    def __init__(self, ax, data):
        self.axes = [ax]
        self.canvas = ax.figure.canvas
        self.data = [data]

        self.Nxy = [ len(data) ]

        facecolors = [d.color for d in data]
        self.xys = [ [(d.x, d.y) for d in data] ]
        fig = ax.figure
        self.collection = [ RegularPolyCollection(
            fig.dpi, 6, sizes=(100,),
            facecolors=facecolors,
            offsets = self.xys[0],
            transOffset = ax.transData)]

        ax.add_collection(self.collection[0])

        self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)

    def callback(self, verts):

        axind = self.axes.index(self.current_axes)
        facecolors = self.collection[axind].get_facecolors()
        p = path.Path(verts)
        ind = p.contains_points(self.xys[axind])
        for i in range(len(self.xys[axind])):
            if ind[i]:
                facecolors[i] = Datum.colorin
            else:
                facecolors[i] = Datum.colorout

        self.canvas.draw_idle()
        self.canvas.widgetlock.release(self.lasso)
        del self.lasso

    def onpress(self, event):
        if self.canvas.widgetlock.locked(): return
        if event.inaxes is None: return
        self.current_axes = event.inaxes

        self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
        # acquire a lock on the widget drawing
        self.canvas.widgetlock(self.lasso)

    def add_axis(self, ax,  data):
        self.axes.append(ax)
        self.data.append(data)

        self.Nxy.append( len(data) )

        facecolors = [d.color for d in data]
        self.xys.append( [(d.x, d.y) for d in data] )
        fig = ax.figure
        self.collection.append( RegularPolyCollection(
            fig.dpi, 6, sizes=(100,),
            facecolors=facecolors,
            offsets = self.xys[-1],
            transOffset = ax.transData))

        ax.add_collection(self.collection[-1])



if __name__ == '__main__':

    data = [Datum(*xy) for xy in rand(100, 2)]
    data2 = [Datum(*xy) for xy in rand(100, 2)]

    ax = plt.subplot(1,2,1)
    lman = LassoManager(ax, data)
    ax2 = plt.subplot(1,2,2)
    lman.add_axis(ax2, data2)
    plt.show()

标签:python,python-2-7,matplotlib,plot,numpy
来源: https://codeday.me/bug/20190703/1364854.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有