Esempio n. 1
0
    def make(self, clf=True, fig=None, axes=None):
        if clf: plt.clf()
        if fig is None and axes is None: fig = plt.figure()
        if axes is None: axes = fig.add_subplot(111)

        xlim = None
        ylim = None

        for x, y, fmt, errorbar, d in self._data:
            if isinstance(x, Quantity):
                f = Quantity(unit=x.uvec) / self._xaxis
                if not f.unitless():
                    warnings.warn(
                        'The ratio of x axis unit ({}) and real unit ({}) must be unit less.'
                        .format(self._xaxis.siunit(), y.siunit()))
                f = float(f)
                sx = x.stddev() * f
                x = x.value * f
            else:
                #f = float(1 / Quantity(self._xunit))
                #x  = x * f
                sx = 0

            if isinstance(y, Quantity):
                f = Quantity(unit=y.uvec) / self._yaxis
                if not f.unitless():
                    warnings.warn(
                        'The ratio of preferred unit ({}) and real unit ({}) must be unit less.'
                        .format(self._yaxis.siunit(), y.siunit()))
                f = float(f)
                sy = y.stddev() * f
                y = y.value * f
            else:
                #f = float(1 / Quantity(self.ypreferredUnit))
                #y  = y * f
                sy = 0

            xmin = np.nanmin(x - sx)
            xmax = np.nanmax(x + sx)
            ymin = np.nanmin(y - sy)
            ymax = np.nanmax(y + sy)
            if xlim is None: xlim = [xmin, xmax]
            if ylim is None: ylim = [ymin, ymax]
            xlim[0] = min(xlim[0], xmin)
            xlim[1] = max(xlim[1], xmax)
            ylim[0] = min(ylim[0], ymin)
            ylim[1] = max(ylim[1], ymax)

            xlimraw = xlim
            ylimraw = ylim

            xerr = sx
            yerr = sy

            if errorbar:
                axes.errorbar(x, y, sy, sx, fmt=fmt, **d)
            else:
                axes.plot(x, y, fmt, **d)

        xdif = xlim[1] - xlim[0]
        ydif = ylim[1] - ylim[0]
        xlim[0] -= xdif * self._enlarge[0]
        xlim[1] += xdif * self._enlarge[1]
        ylim[0] -= ydif * self._enlarge[2]
        ylim[1] += ydif * self._enlarge[3]

        i = 0
        taken = [[0] * 2, [0] * 2, [0] * 2]
        for b in self._boxes:
            if isinstance(b, tuple):
                fitnum, b, x, y, bpos = b

            if isinstance(bpos, tuple):
                x = bpos[0] / 3
                y = bpos[1] / 2
            else:
                penalty = []
                for x in range(3):
                    for y in range(2):
                        points = 0
                        total = 0
                        for dx, dy, fmt, errorbar, d in self._data:
                            fx = float(Quantity(unit=dx.uvec) / self._xaxis)
                            fy = float(Quantity(unit=dy.uvec) / self._yaxis)
                            idx1 = (dx.value * fx >
                                    (xlim[0] + xdif * (x / 3 - 0.1)))
                            idx2 = (dx.value * fx <
                                    (xlim[0] + xdif * (x + 1.3) / 3))
                            idx3 = (dy.value * fy >
                                    (ylim[0] + ydif * (y / 2 - 0.1)))
                            idx4 = (dy.value * fy <
                                    (ylim[0] + ydif * (y + 1.2) / 2))
                            idx = idx1 * idx2 * idx3 * idx4
                            points += len(dx.value[idx]) / len(dx.value)
                            total = len(dx.value)
                        points += total * taken[x][y]
                        penalty.append((x, y, points))
                x, y, points = min(penalty, key=lambda y: y[2])
                taken[x][y] += 1

            if y == 0:
                yalign = 'bottom'
                y = ylimraw[0] + ydif * 0.05
            elif y == 1:
                yalign = 'top'
                y = ylimraw[1] - ydif * 0.05

            if x == 0:
                xalign = 'left'
                x = xlimraw[0] + xdif * 0.05
            elif x == 1:
                xalign = 'center'
                x = xlimraw[0] + 0.5 * xdif
            elif x == 2:
                xalign = 'right'
                x = xlimraw[1] - xdif * 0.05

            if self._fitcount > 1 and False:
                b = '({}) {}'.format(fitnum, b)
                fx = Quantity(unit=x.uvec) / self._xaxis
                fy = Quantity(unit=y.uvec) / self._yaxis
                if not fx.unitless():
                    warnings.warn(
                        'The ratio of preferred unit ({}) and real unit ({}) must be unit less.'
                        .format(self._xaxis.siunit(), x.siunit()))
                if not fy.unitless():
                    warnings.warn(
                        'The ratio of preferred unit ({}) and real unit ({}) must be unit less.'
                        .format(self._yaxis.siunit(), y.siunit()))
                fx = float(fx)
                fy = float(fy)
                tx = x.value * fx
                ty = y.value * fy
                tx = (min(tx) + max(tx)) / 2
                ty = max(ty)
                ty += 0.05 * ydif

                axes.text(tx,
                          ty,
                          '({})'.format(fitnum),
                          color=Plot.fitcolors[(fitnum - 1) % 6],
                          horizontalalignment='center',
                          verticalalignment='bottom')

            #plt.figtext(*xy, s=b,bbox=dict(facecolor='w', edgecolor='black', pad=10), multialignment='left', **align)
            axes.annotate(b,
                          xy=(x, y),
                          bbox=dict(facecolor='w', edgecolor='k', pad=10),
                          multialignment='left',
                          horizontalalignment=xalign,
                          verticalalignment=yalign)

        if self._grid: pylab.grid()
        axes.set_xscale(self._xscale)
        axes.set_yscale(self._yscale)
        if self._leg: pylab.legend()

        if self.makex(): axes.set_xlabel(self.makex())
        if self.makey(): axes.set_ylabel(self.makey())

        self._made = True
        axes.set_xlim(*xlimraw)
        axes.set_ylim(*ylimraw)
        return self  # cascade
Esempio n. 2
0
  def make(self, clf=True, fig=None, axes=None):
    if clf: plt.clf()
    if fig is None and axes is None: fig = plt.figure()
    if axes is None: axes = fig.add_subplot(111)

    xlim = None
    ylim = None

    for x, y, fmt, errorbar, d in self._data:
      if isinstance(x, Quantity):
        f = Quantity(unit=x.uvec) / self._xaxis
        if not f.unitless():
          warnings.warn('The ratio of x axis unit ({}) and real unit ({}) must be unit less.'.format(self._xaxis.siunit(), y.siunit()))
        f = float(f)
        sx = x.stddev() * f
        x  = x.value * f
      else:
        #f = float(1 / Quantity(self._xunit))
        #x  = x * f
        sx = 0

      if isinstance(y, Quantity):
        f = Quantity(unit=y.uvec) / self._yaxis
        if not f.unitless():
          warnings.warn('The ratio of preferred unit ({}) and real unit ({}) must be unit less.'.format(self._yaxis.siunit(), y.siunit()))
        f = float(f)
        sy = y.stddev() * f
        y  = y.value * f
      else:
        #f = float(1 / Quantity(self.ypreferredUnit))
        #y  = y * f
        sy = 0

      xmin = np.nanmin(x - sx)
      xmax = np.nanmax(x + sx)
      ymin = np.nanmin(y - sy)
      ymax = np.nanmax(y + sy)
      if xlim is None: xlim = [xmin, xmax]
      if ylim is None: ylim = [ymin, ymax]
      xlim[0] = min(xlim[0], xmin)
      xlim[1] = max(xlim[1], xmax)
      ylim[0] = min(ylim[0], ymin)
      ylim[1] = max(ylim[1], ymax)

      xlimraw = xlim
      ylimraw = ylim

      xerr = sx
      yerr = sy

      if errorbar:
        axes.errorbar(x, y, sy, sx, fmt=fmt, **d)
      else:
        axes.plot(x, y, fmt, **d)

    xdif = xlim[1] - xlim[0]
    ydif = ylim[1] - ylim[0]
    xlim[0] -= xdif * self._enlarge[0]
    xlim[1] += xdif * self._enlarge[1]
    ylim[0] -= ydif * self._enlarge[2]
    ylim[1] += ydif * self._enlarge[3]


    i = 0
    taken = [ [0]*2, [0]*2, [0]*2 ]
    for b in self._boxes:
      if isinstance(b, tuple):
        fitnum, b, x, y, bpos = b
        
      if isinstance(bpos, tuple): 
        x = bpos[0] / 3
        y = bpos[1] / 2
      else:
        penalty = []
        for x in range(3):
          for y in range(2):
            points = 0 
            total = 0
            for dx, dy, fmt, errorbar, d in self._data:
              fx = float(Quantity(unit=dx.uvec) / self._xaxis)
              fy = float(Quantity(unit=dy.uvec) / self._yaxis)
              idx1 = (dx.value * fx > (xlim[0] + xdif * (x/3 - 0.1)))
              idx2 = (dx.value * fx < (xlim[0] + xdif * (x+1.3) / 3))
              idx3 = (dy.value * fy > (ylim[0] + ydif * (y/2 - 0.1)))
              idx4 = (dy.value * fy < (ylim[0] + ydif * (y+1.2) / 2))
              idx = idx1 * idx2 * idx3 * idx4
              points += len(dx.value[idx]) / len(dx.value)
              total = len(dx.value)
            points += total * taken[x][y]
            penalty.append( (x, y, points) )
        x, y, points = min(penalty, key=lambda y: y[2])
        taken[x][y] += 1

      if y == 0:
        yalign = 'bottom'
        y = ylimraw[0] + ydif * 0.05
      elif y == 1:
        yalign = 'top'
        y = ylimraw[1] - ydif * 0.05

      if x == 0:
        xalign = 'left'
        x = xlimraw[0] + xdif * 0.05
      elif x == 1:
        xalign = 'center'
        x = xlimraw[0] + 0.5 * xdif
      elif x == 2:
        xalign = 'right'
        x = xlimraw[1] - xdif * 0.05


      if self._fitcount > 1:
        b = '({}) {}'.format(fitnum, b)
        fx = Quantity(unit=x.uvec) / self._xaxis
        fy = Quantity(unit=y.uvec) / self._yaxis
        if not fx.unitless():
          warnings.warn('The ratio of preferred unit ({}) and real unit ({}) must be unit less.'.format(self._xaxis.siunit(), x.siunit()))
        if not fy.unitless():
          warnings.warn('The ratio of preferred unit ({}) and real unit ({}) must be unit less.'.format(self._yaxis.siunit(), y.siunit()))
        fx = float(fx)
        fy = float(fy)
        tx = x.value * fx
        ty = y.value * fy
        tx = (min(tx)+max(tx))/2
        ty = max(ty)
        ty += 0.05 * ydif

        axes.text(tx, ty, '({})'.format(fitnum), color=Plot.fitcolors[(fitnum-1)%6], horizontalalignment='center', verticalalignment='bottom')


      #plt.figtext(*xy, s=b,bbox=dict(facecolor='w', edgecolor='black', pad=10), multialignment='left', **align)
      axes.annotate(b, xy=(x, y), bbox=dict(facecolor='w', edgecolor='k', pad=10), multialignment='left', horizontalalignment=xalign, verticalalignment=yalign)


    if self._grid: pylab.grid()
    axes.set_xscale(self._xscale)
    axes.set_yscale(self._yscale)
    if self._leg: pylab.legend()

    if self.makex(): axes.set_xlabel(self.makex())
    if self.makey(): axes.set_ylabel(self.makey())

    self._made = True
    axes.set_xlim(*xlimraw)
    axes.set_ylim(*ylimraw)
    return self # cascade