def plot_power(self, dep_var='nobs', nobs=None, effect_size=None, alpha=0.05, ax=None, title=None, plt_kwds=None, **kwds): '''plot power with number of observations or effect size on x-axis Parameters ---------- dep_var : str in ['nobs', 'effect_size', 'alpha'] This specifies which variable is used for the horizontal axis. If dep_var='nobs' (default), then one curve is created for each value of ``effect_size``. If dep_var='effect_size' or alpha, then one curve is created for each value of ``nobs``. nobs : scalar or array_like specifies the values of the number of observations in the plot effect_size : scalar or array_like specifies the values of the effect_size in the plot alpha : float or array_like The significance level (type I error) used in the power calculation. Can only be more than a scalar, if ``dep_var='alpha'`` ax : None or axis instance If ax is None, than a matplotlib figure is created. If ax is a matplotlib axis instance, then it is reused, and the plot elements are created with it. title : str title for the axis. Use an empty string, ``''``, to avoid a title. plt_kwds : None or dict not used yet kwds : optional keywords for power function These remaining keyword arguments are used as arguments to the power function. Many power function support ``alternative`` as a keyword argument, two-sample test support ``ratio``. Returns ------- fig : matplotlib figure instance Notes ----- This works only for classes where the ``power`` method has ``effect_size``, ``nobs`` and ``alpha`` as the first three arguments. If the second argument is ``nobs1``, then the number of observations in the plot are those for the first sample. TODO: fix this for FTestPower and GofChisquarePower TODO: maybe add line variable, if we want more than nobs and effectsize ''' #if pwr_kwds is None: # pwr_kwds = {} from statsmodels.graphics import utils from statsmodels.graphics.plottools import rainbow fig, ax = utils.create_mpl_ax(ax) import matplotlib.pyplot as plt colormap = plt.cm.Dark2 #pylint: disable-msg=E1101 plt_alpha = 1 #0.75 lw = 2 if dep_var == 'nobs': colors = rainbow(len(effect_size)) colors = [ colormap(i) for i in np.linspace(0, 0.9, len(effect_size)) ] for ii, es in enumerate(effect_size): power = self.power(es, nobs, alpha, **kwds) ax.plot(nobs, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='es=%4.2F' % es) xlabel = 'Number of Observations' elif dep_var in ['effect size', 'effect_size', 'es']: colors = rainbow(len(nobs)) colors = [colormap(i) for i in np.linspace(0, 0.9, len(nobs))] for ii, n in enumerate(nobs): power = self.power(effect_size, n, alpha, **kwds) ax.plot(effect_size, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='N=%4.2F' % n) xlabel = 'Effect Size' elif dep_var in ['alpha']: # experimental nobs as defining separate lines colors = rainbow(len(nobs)) for ii, n in enumerate(nobs): power = self.power(effect_size, n, alpha, **kwds) ax.plot(alpha, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='N=%4.2F' % n) xlabel = 'alpha' else: raise ValueError('depvar not implemented') if title is None: title = 'Power of Test' ax.set_xlabel(xlabel) ax.set_title(title) ax.legend(loc='lower right') return fig
def interaction_plot(x, trace, response, func=np.mean, ax=None, plottype='b', xlabel=None, ylabel=None, colors=None, markers=None, linestyles=None, legendloc='best', legendtitle=None, **kwargs): """ Interaction plot for factor level statistics. Note. If categorial factors are supplied levels will be internally recoded to integers. This ensures matplotlib compatibility. Uses a DataFrame to calculate an `aggregate` statistic for each level of the factor or group given by `trace`. Parameters ---------- x : array_like The `x` factor levels constitute the x-axis. If a `pandas.Series` is given its name will be used in `xlabel` if `xlabel` is None. trace : array_like The `trace` factor levels will be drawn as lines in the plot. If `trace` is a `pandas.Series` its name will be used as the `legendtitle` if `legendtitle` is None. response : array_like The reponse or dependent variable. If a `pandas.Series` is given its name will be used in `ylabel` if `ylabel` is None. func : function Anything accepted by `pandas.DataFrame.aggregate`. This is applied to the response variable grouped by the trace levels. ax : axes, optional Matplotlib axes instance plottype : str {'line', 'scatter', 'both'}, optional The type of plot to return. Can be 'l', 's', or 'b' xlabel : str, optional Label to use for `x`. Default is 'X'. If `x` is a `pandas.Series` it will use the series names. ylabel : str, optional Label to use for `response`. Default is 'func of response'. If `response` is a `pandas.Series` it will use the series names. colors : list, optional If given, must have length == number of levels in trace. markers : list, optional If given, must have length == number of levels in trace linestyles : list, optional If given, must have length == number of levels in trace. legendloc : {None, str, int} Location passed to the legend command. legendtitle : {None, str} Title of the legend. **kwargs These will be passed to the plot command used either plot or scatter. If you want to control the overall plotting options, use kwargs. Returns ------- Figure The figure given by `ax.figure` or a new instance. Examples -------- >>> import numpy as np >>> np.random.seed(12345) >>> weight = np.random.randint(1,4,size=60) >>> duration = np.random.randint(1,3,size=60) >>> days = np.log(np.random.randint(1,30, size=60)) >>> fig = interaction_plot(weight, duration, days, ... colors=['red','blue'], markers=['D','^'], ms=10) >>> import matplotlib.pyplot as plt >>> plt.show() .. plot:: import numpy as np from statsmodels.graphics.factorplots import interaction_plot np.random.seed(12345) weight = np.random.randint(1,4,size=60) duration = np.random.randint(1,3,size=60) days = np.log(np.random.randint(1,30, size=60)) fig = interaction_plot(weight, duration, days, colors=['red','blue'], markers=['D','^'], ms=10) import matplotlib.pyplot as plt #plt.show() """ from pandas import DataFrame fig, ax = utils.create_mpl_ax(ax) response_name = ylabel or getattr(response, 'name', 'response') ylabel = '%s of %s' % (func.__name__, response_name) xlabel = xlabel or getattr(x, 'name', 'X') legendtitle = legendtitle or getattr(trace, 'name', 'Trace') ax.set_ylabel(ylabel) ax.set_xlabel(xlabel) x_values = x_levels = None if isinstance(x[0], str): x_levels = [l for l in np.unique(x)] x_values = lrange(len(x_levels)) x = _recode(x, dict(zip(x_levels, x_values))) data = DataFrame(dict(x=x, trace=trace, response=response)) plot_data = data.groupby(['trace', 'x']).aggregate(func).reset_index() # return data # check plot args n_trace = len(plot_data['trace'].unique()) linestyles = ['-'] * n_trace if linestyles is None else linestyles markers = ['.'] * n_trace if markers is None else markers colors = rainbow(n_trace) if colors is None else colors if len(linestyles) != n_trace: raise ValueError("Must be a linestyle for each trace level") if len(markers) != n_trace: raise ValueError("Must be a marker for each trace level") if len(colors) != n_trace: raise ValueError("Must be a color for each trace level") if plottype == 'both' or plottype == 'b': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], marker=markers[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'line' or plottype == 'l': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'scatter' or plottype == 's': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.scatter(group['x'], group['response'], color=colors[i], label=label, marker=markers[i], **kwargs) else: raise ValueError("Plot type %s not understood" % plottype) ax.legend(loc=legendloc, title=legendtitle) ax.margins(.1) if all([x_levels, x_values]): ax.set_xticks(x_values) ax.set_xticklabels(x_levels) return fig
linestyles = ['-'] * n_trace if markers: try: assert len(markers) == n_trace except AssertionError, err: raise ValueError("Must be a linestyle for each trace level") else: # set a default markers = ['.'] * n_trace if colors: try: assert len(colors) == n_trace except AssertionError, err: raise ValueError("Must be a linestyle for each trace level") else: # set a default #TODO: how to get n_trace different colors? colors = rainbow(n_trace) if plottype == 'both' or plottype == 'b': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], marker=markers[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'line' or plottype == 'l': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'scatter' or plottype == 's':
def plot_power(self, dep_var='nobs', nobs=None, effect_size=None, alpha=0.05, ax=None, title=None, plt_kwds=None, **kwds): '''plot power with number of observations or effect size on x-axis Parameters ---------- dep_var : string in ['nobs', 'effect_size', 'alpha'] This specifies which variable is used for the horizontal axis. If dep_var='nobs' (default), then one curve is created for each value of ``effect_size``. If dep_var='effect_size' or alpha, then one curve is created for each value of ``nobs``. nobs : scalar or array_like specifies the values of the number of observations in the plot effect_size : scalar or array_like specifies the values of the effect_size in the plot alpha : float or array_like The significance level (type I error) used in the power calculation. Can only be more than a scalar, if ``dep_var='alpha'`` ax : None or axis instance If ax is None, than a matplotlib figure is created. If ax is a matplotlib axis instance, then it is reused, and the plot elements are created with it. title : string title for the axis. Use an empty string, ``''``, to avoid a title. plt_kwds : None or dict not used yet kwds : optional keywords for power function These remaining keyword arguments are used as arguments to the power function. Many power function support ``alternative`` as a keyword argument, two-sample test support ``ratio``. Returns ------- fig : matplotlib figure instance Notes ----- This works only for classes where the ``power`` method has ``effect_size``, ``nobs`` and ``alpha`` as the first three arguments. If the second argument is ``nobs1``, then the number of observations in the plot are those for the first sample. TODO: fix this for FTestPower and GofChisquarePower TODO: maybe add line variable, if we want more than nobs and effectsize ''' #if pwr_kwds is None: # pwr_kwds = {} from statsmodels.graphics import utils from statsmodels.graphics.plottools import rainbow fig, ax = utils.create_mpl_ax(ax) import matplotlib.pyplot as plt colormap = plt.cm.Dark2 #pylint: disable-msg=E1101 plt_alpha = 1 #0.75 lw = 2 if dep_var == 'nobs': colors = rainbow(len(effect_size)) colors = [colormap(i) for i in np.linspace(0, 0.9, len(effect_size))] for ii, es in enumerate(effect_size): power = self.power(es, nobs, alpha, **kwds) ax.plot(nobs, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='es=%4.2F' % es) xlabel = 'Number of Observations' elif dep_var in ['effect size', 'effect_size', 'es']: colors = rainbow(len(nobs)) colors = [colormap(i) for i in np.linspace(0, 0.9, len(nobs))] for ii, n in enumerate(nobs): power = self.power(effect_size, n, alpha, **kwds) ax.plot(effect_size, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='N=%4.2F' % n) xlabel = 'Effect Size' elif dep_var in ['alpha']: # experimental nobs as defining separate lines colors = rainbow(len(nobs)) for ii, n in enumerate(nobs): power = self.power(effect_size, n, alpha, **kwds) ax.plot(alpha, power, lw=lw, alpha=plt_alpha, color=colors[ii], label='N=%4.2F' % n) xlabel = 'alpha' else: raise ValueError('depvar not implemented') if title is None: title = 'Power of Test' ax.set_xlabel(xlabel) ax.set_title(title) ax.legend(loc='lower right') return fig
def interaction_plot(x, trace, response, func=np.mean, ax=None, plottype='b', xlabel=None, ylabel=None, colors=None, markers=None, linestyles=None, legendloc='best', legendtitle=None, **kwargs): """ Interaction plot for factor level statistics. Note. If categorial factors are supplied levels will be internally recoded to integers. This ensures matplotlib compatiblity. uses pandas.DataFrame to calculate an `aggregate` statistic for each level of the factor or group given by `trace`. Parameters ---------- x : array-like The `x` factor levels constitute the x-axis. If a `pandas.Series` is given its name will be used in `xlabel` if `xlabel` is None. trace : array-like The `trace` factor levels will be drawn as lines in the plot. If `trace` is a `pandas.Series` its name will be used as the `legendtitle` if `legendtitle` is None. response : array-like The reponse or dependent variable. If a `pandas.Series` is given its name will be used in `ylabel` if `ylabel` is None. func : function Anything accepted by `pandas.DataFrame.aggregate`. This is applied to the response variable grouped by the trace levels. plottype : str {'line', 'scatter', 'both'}, optional The type of plot to return. Can be 'l', 's', or 'b' ax : axes, optional Matplotlib axes instance xlabel : str, optional Label to use for `x`. Default is 'X'. If `x` is a `pandas.Series` it will use the series names. ylabel : str, optional Label to use for `response`. Default is 'func of response'. If `response` is a `pandas.Series` it will use the series names. colors : list, optional If given, must have length == number of levels in trace. linestyles : list, optional If given, must have length == number of levels in trace. markers : list, optional If given, must have length == number of lovels in trace kwargs These will be passed to the plot command used either plot or scatter. If you want to control the overall plotting options, use kwargs. Returns ------- fig : Figure The figure given by `ax.figure` or a new instance. Examples -------- >>> import numpy as np >>> np.random.seed(12345) >>> weight = np.random.randint(1,4,size=60) >>> duration = np.random.randint(1,3,size=60) >>> days = np.log(np.random.randint(1,30, size=60)) >>> fig = interaction_plot(weight, duration, days, ... colors=['red','blue'], markers=['D','^'], ms=10) >>> import matplotlib.pyplot as plt >>> plt.show() .. plot:: import numpy as np from statsmodels.graphics.factorplots import interaction_plot np.random.seed(12345) weight = np.random.randint(1,4,size=60) duration = np.random.randint(1,3,size=60) days = np.log(np.random.randint(1,30, size=60)) fig = interaction_plot(weight, duration, days, colors=['red','blue'], markers=['D','^'], ms=10) import matplotlib.pyplot as plt #plt.show() """ from pandas import DataFrame fig, ax = utils.create_mpl_ax(ax) response_name = ylabel or getattr(response, 'name', 'response') ylabel = '%s of %s' % (func.__name__, response_name) xlabel = xlabel or getattr(x, 'name', 'X') legendtitle = legendtitle or getattr(trace, 'name', 'Trace') ax.set_ylabel(ylabel) ax.set_xlabel(xlabel) x_values = x_levels = None if isinstance(x[0], str): x_levels = [l for l in np.unique(x)] x_values = lrange(len(x_levels)) x = _recode(x, dict(zip(x_levels, x_values))) data = DataFrame(dict(x=x, trace=trace, response=response)) plot_data = data.groupby(['trace', 'x']).aggregate(func).reset_index() # return data # check plot args n_trace = len(plot_data['trace'].unique()) linestyles = ['-'] * n_trace if linestyles is None else linestyles markers = ['.'] * n_trace if markers is None else markers colors = rainbow(n_trace) if colors is None else colors if len(linestyles) != n_trace: raise ValueError("Must be a linestyle for each trace level") if len(markers) != n_trace: raise ValueError("Must be a marker for each trace level") if len(colors) != n_trace: raise ValueError("Must be a color for each trace level") if plottype == 'both' or plottype == 'b': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], marker=markers[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'line' or plottype == 'l': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.plot(group['x'], group['response'], color=colors[i], label=label, linestyle=linestyles[i], **kwargs) elif plottype == 'scatter' or plottype == 's': for i, (values, group) in enumerate(plot_data.groupby(['trace'])): # trace label label = str(group['trace'].values[0]) ax.scatter(group['x'], group['response'], color=colors[i], label=label, marker=markers[i], **kwargs) else: raise ValueError("Plot type %s not understood" % plottype) ax.legend(loc=legendloc, title=legendtitle) ax.margins(.1) if all([x_levels, x_values]): ax.set_xticks(x_values) ax.set_xticklabels(x_levels) return fig