Source code for pytomo.cdfplot_new

#!/usr/bin/env python
"Module to plot cdf from data or file. Can be called directly."

from __future__ import division, print_function

#from optparse import OptionParser
import sys
# AO 201221010 (due to error in win) =>
try:
    import numpy as np
except ImportError:
    np = None
# in case of non-interactive usage
#import matplotlib
#matplotlib.use('PDF')
try:
    import matplotlib.pyplot as plt
    from matplotlib.font_manager import FontProperties
    from matplotlib.colors import colorConverter
except ImportError:
    plt = None
# <= AO 201221010 (due to error in win)
from itertools import cycle

_VERSION = '2.0'

# possibility to place legend outside graph:
#pylab.subfigure(111)
#pylab.subplots_adjust(right=0.8) or (top=0.8)
#pylab.legend(loc=(1.1, 0.5)

[docs]class CdfFigure(object): "Hold the figure and its default properties" def __init__(self, xlabel='x', ylabel=r'P(X$\leq$x)', title='Empirical Distribution', fontsize='xx-large', legend_fontsize='large', legend_ncol=1, subplot_top=None): self._figure = plt.figure() if subplot_top: self._figure.subplotpars.top = subplot_top self._axis = self._figure.add_subplot(111) self._lines = {} self.xlabel = xlabel self.ylabel = ylabel self.title = title self.fontsize = fontsize self.legend_fontsize = legend_fontsize self.legend_ncol = legend_ncol
[docs] def savefig(self, *args, **kwargs): "Saves the figure: interface to plt.Figure.savefig" self._figure.savefig(*args, **kwargs)
[docs] def bar(self, *args, **kwargs): "Plot in the axis: interface to plt.Axes.bar" self._axis.bar(*args, **kwargs)
[docs] def plot(self, *args, **kwargs): "Plot in the axis: interface to plt.Axes.plot" self._axis.plot(*args, **kwargs)
[docs] def get_xlim(self, *args, **kwargs): "Plot in the axis: interface to plt.Axes.get_xlim()" return self._axis.get_xlim(*args, **kwargs)
[docs] def set_xlim(self, *args, **kwargs): "Plot in the axis: interface to plt.Axes.set_xlim()" self._axis.set_xlim(*args, **kwargs)
[docs] def set_ylim(self, *args, **kwargs): "Plot in the axis: interface to plt.Axes.set_ylim()" self._axis.set_ylim(*args, **kwargs)
[docs] def cdfplot(self, data_in, name='Data', finalize=False): """Plot the cdf of a data array Wrapper to call the plot method of axes """ data = sorted(filter(lambda x: x is not None, data_in)) data_len = len(data) if data_len == 0: print("no data to plot", file=sys.stderr) return cdf = np.arange(data_len + 1) / data_len # to have cdf up to 1 data.append(data[-1]) line = self._axis.plot(data, cdf, drawstyle='steps', label=name + ': %d' % len(data)) self._lines[name] = line[0] if finalize: self.adjust_plot()
[docs] def ccdfplot(self, data_in, name='Data', finalize=False): """Plot the cdf of a data array Wrapper to call the plot method of axes """ data = sorted(filter(lambda x: x is not None, data_in)) data_len = len(data) if data_len == 0: print("no data to plot", file=sys.stderr) return ccdf = 1 - np.arange(data_len + 1) / data_len # to have cdf up to 1 data.append(data[-1]) line = self._axis.plot(data, ccdf, drawstyle='steps', label=name + ': %d' % len(data)) self._lines[name] = line[0] if finalize: self.adjust_plot()
[docs] def show(self): "Show the figure, and hold to do interactive drawing" self._figure.show() self._figure.hold(True)
@staticmethod
[docs] def generate_line_properties(): "Cycle through the lines properties" colors = cycle('mgcb') line_width = 2.5 dashes = cycle([(1, 0), (8, 5)]) #self.dash_generator() linestyles = cycle(['-']) #alphas = cycle([.3, 1.]) markers = cycle(' oxv*d') while True: dash = dashes.next() yield (colors.next(), line_width, dash, linestyles.next(), markers.next()) yield (colors.next(), line_width, dash, linestyles.next(), markers.next()) dash = dashes.next() yield (colors.next(), line_width, dash, linestyles.next(), markers.next()) yield (colors.next(), line_width, dash, linestyles.next(), markers.next())
[docs] def adjust_lines(self, dashes=True, leg_loc='best'): """Put correct styles in the axes lines Should be launch when all lines are plotted Optimised for up to 8 lines in the plot """ generator = self.generate_line_properties() for key in sorted(self._lines): (color, line_width, dash, linestyle, marker) = generator.next() line = self._lines[key] line.set_color(color) line.set_lw(line_width) line.set_linestyle(linestyle) if dashes: line.set_dashes(dash) line.set_marker(marker) line.set_markersize(12) line.set_markeredgewidth(1.5) line.set_markerfacecolor('1.') line.set_markeredgecolor(color) # we want at most 15 markers per line markevery = 1 + len(line.get_xdata()) // 15 line.set_markevery(markevery) self.adjust_plot(leg_loc=leg_loc)
[docs] def adjust_plot(self, leg_loc='best'): "Adjust main plot properties (grid, ticks, legend)" self.put_labels() self.adjust_ticks() self._axis.grid(True) self._axis.legend(loc=leg_loc, ncol=self.legend_ncol)
[docs] def put_labels(self): "Put labels for axes and title" self._axis.set_xlabel(self.xlabel, size=self.fontsize) self._axis.set_ylabel(self.ylabel, size=self.fontsize) self._axis.set_title(self.title, size=self.fontsize)
[docs] def legend(self, loc='best'): "Plot legend with correct font size" font = FontProperties(size=self.legend_fontsize) self._axis.legend(loc=loc, prop=font)
[docs] def adjust_ticks(self): """Adjusts ticks sizes To call after a rescale (log...) """ self._axis.minorticks_on() for tick in self._axis.xaxis.get_major_ticks(): tick.label1.set_fontsize(self.fontsize) for tick in self._axis.yaxis.get_major_ticks(): tick.label1.set_fontsize(self.fontsize)
[docs] def setgraph_logx(self): "Set graph in xlogscale and adjusts plot (grid, ticks, legend)" self._axis.semilogx(nonposy='clip', nonposx='clip')
[docs] def setgraph_logy(self): "Set graph in xlogscale and adjusts plot (grid, ticks, legend)" self._axis.semilogy(nonposy='clip', nonposx='clip')
[docs] def setgraph_loglog(self): "Set graph in xlogscale and adjusts plot (grid, ticks, legend)" self._axis.loglog(nonposy='clip', nonposx='clip')
[docs] def cdfplotdata(self, list_data_name, **kwargs): "Method to be able to append data to the figure" cdfplotdata(list_data_name, figure=self, **kwargs)
[docs] def ccdfplotdata(self, list_data_name, **kwargs): "Method to be able to append data to the figure" cdfplotdata(list_data_name, figure=self, cdf=True, **kwargs)
[docs]def cdfplotdata(list_data_name, figure=None, xlabel='x', loc='best', fs_legend='large', title = 'Empirical Distribution', logx=True, logy=False, cdf=True, dashes=True, legend_ncol=1): "Plot the cdf of a list of names and data arrays" if not figure: figure = CdfFigure(xlabel=xlabel, title=title, legend_fontsize=fs_legend, legend_ncol=legend_ncol) else: figure.title = title figure.xlabel = xlabel figure.legend_fontsize = fs_legend figure.legend_ncol = legend_ncol if not list_data_name: print("no data to plot", file=sys.stderr) return figure for name, data in list_data_name: if cdf: figure.cdfplot(data, name=name) else: figure.ccdfplot(data, name=name) if logx and logy: figure.setgraph_loglog() elif logy: figure.setgraph_logy() elif logx: figure.setgraph_logx() figure.adjust_lines(dashes=dashes, leg_loc=loc) return figure
[docs]def cdfplot(in_file, col=0): "Plot the cdf of a column in file" data = np.loadtxt(in_file, usecols = [col]) cdfplotdata(('Data', data))
[docs]def scatter_plot(data, title='Scatterplot', xlabel='X', ylabel='Y', logx=False, logy=False): "Plot a scatter plot of data" figure = CdfFigure(title=title, xlabel=xlabel, ylabel=ylabel) x, y = zip(*data) figure.plot(x, y, linestyle='', marker='^', markersize=8, markeredgecolor='b', markerfacecolor='w') if logx and logy: figure.setgraph_loglog() elif logy: figure.setgraph_logy() elif logx: figure.setgraph_logx() figure.adjust_plot() return figure
[docs]def scatter_plot_multi(datas, title='Scatterplot', xlabel='X', ylabel='Y', logx=False, logy=False): "Plot a scatter plot of dictionary" figure = CdfFigure(title=title, xlabel=xlabel, ylabel=ylabel) markers = cycle('^xo') colors = cycle('brm') transparent = colorConverter.to_rgba('w', alpha=1) total_nb = len([x for y in datas.values() for x in y]) for label, data in sorted(datas.items()): x, y = zip(*data) figure.plot(x, y, label=(r'%s: %d (\textbf{%d\%%})' % (label, len(data), 100 *len(data) // total_nb)), linestyle='', marker=markers.next(), markersize=8, markeredgecolor=colors.next(), markerfacecolor=transparent) if logx and logy: figure.setgraph_loglog() elif logy: figure.setgraph_logy() elif logx: figure.setgraph_logx() figure.adjust_plot() return figure
[docs]def bin_plot(datas, title='Bin Plot', xlabel='X', ylabel='Y', logx=False, logy=False): "Plot a bin plot of dictionary" figure = CdfFigure(title=title, xlabel=xlabel, ylabel=ylabel) # linestyles = cycle(('-', '--')) # markers = cycle('^xo') # colors = cycle('brm') # for label, data in datas: left, width, height, yerr = zip(*datas) figure.bar(left, height, width, linewidth=0) #, yerr=yerr) # linestyle=linestyles.next(), marker=markers.next(), # markersize=6, markeredgecolor=colors.next(), # markerfacecolor='w') if logx and logy: figure.setgraph_loglog() elif logy: figure.setgraph_logy() elif logx: figure.setgraph_logx() figure.adjust_plot() return figure