def plot_bar_from_counter(counter, ax=None): """" This function creates a bar plot from a counter. :param counter: This is a counter object, a dictionary with the item as the key and the frequency as the value :param ax: an axis of matplotlib :return: the axis wit the object in it """ if ax is None: fig = plt.figure() ax = fig.add_subplot(111) frequencies = counter.values() names = counter.keys() x_coordinates = np.arange(len(counter)) rects = ax.bar(x_coordinates, frequencies, align='center') for i, v in enumerate(frequencies): ax.text(v, i, str(v), color='black', fontweight='bold') ax.xaxis.set_major_locator(plt.FixedLocator(x_coordinates)) ax.xaxis.set_major_formatter(plt.FixedFormatter(names)) ax.set_title("Histogram of BVA %s iterations" % '{0:,}'.format(iterations)) autolabel(rects, ax) return ax
def generate_xticks(self, all_days, monthsamp=1): """ generate xticks all_days: array of times (days since 01-0-0) """ dd = pl.num2date(all_days) xticks = [] xticklabels = [] last_month = dd[0].month last_year = dd[0].year xticks.append(all_days[0]) strmon = get_month_string(dd[0].month) if self.yearonly: xticklabels.append(str(dd[0].year)) else: xticklabels.append(strmon + '\n' + str(dd[0].year)) for d in dd: if (d.month != last_month) | (d.year != last_year): xticks.append(pl.date2num(d)) # save tick location mstr = get_month_string(d.month) if self.yearonly: xticklabels.append(str(d.year)) else: if (d.year != last_year): xticklabels.append(mstr + '\n' + str(d.year)) else: xticklabels.append(mstr + '\n' + '') last_month = d.month last_year = d.year if self.transpose: scal = self.rescaley else: scal = self.rescalex xticks = np.asarray(xticks) # /// remap to image coordinates ny, nx = np.shape(self.hov) w = (xticks - pl.date2num(self.t_min)) / ( pl.date2num(self.t_max) - pl.date2num(self.t_min) ) # weights for positions on x-axis xticks = w * nx * scal xticks = list(xticks) # here we have monthly ticks which we can now subsample xticks = xticks[::monthsamp] xticklabels = xticklabels[::monthsamp] self.x_major_locator = pl.FixedLocator(xticks) self.x_major_formatter = pl.FixedFormatter(xticklabels)
def plot(self, xticks=None, xlabel=None, ylabel=None, title='', grid=True, climits=None, figsize=None, origin=None, xtickrotation=0, cmap='jet', showcolorbar=True, ax=None, show_uncertainties=False, norm_uncertainties=False, input=None, showxticks=True, nclasses=11, lat_tick=np.arange(-90., 90 + 30., 30.), monthsamp=1, yearonly=True): """ Generates a Hovmoeller plot Two different options are available to generate the plot. The plot can be either based on calculation from the Hovmoeller class itself. This requires that self.hov was calculated already using e.g. time_to_lat(). The second option is, that a Data object is provided by the *input* variable. In this case, the zonal mean is calculated from the Data object all required processing is done in this routine. input : Data C{Data} object that is used for the generation of the hovmoeller plot grid : bool plot tick grid in hovmoeller plot ylabel : str ylabel for plot title : str title for the plot climits : list limits for the colorbar; [vmin,vmax] cmap : str colormap to be used xtickrotation : float rotation of xticklabels 0 ... 90 showcolorbar : bool show colorbar in plot ax : axis axis to plot to. If not specified (default), then a new figure will be created showxticks : bool show the xticks in the Hovmoeller plot nclasses : int number of classes for colorbar lat_tick : ndarray tick labels for latitude (default: every 30 degree) monthsamp : int sampling interval for months yearonly : bool if True, then only the years are shown as labels in the timeseries input is expected to have dimensions [nlat,ntime] and can be precalculated using Data.get_zonal_mean().T input is expected to be a Data object! """ if input is not None: if self.hov is not None: raise ValueError( 'If precalculated dat is provided as input, the data MUST not be calculated already by the class!' ) else: #//////////////////////////////////////////////// # HOVMOELLER PLOT FROM DATA OBJECT #//////////////////////////////////////////////// input1 = input.get_zonal_mean(return_object=True) input1.adjust_time(day=1) # , month=1) nlat, nt = input1.data.shape if nt != len(self.time): print input1.shape print nt, len(self.time) raise ValueError('inconsistent time shape!') self.hov = input1.data self.yearonly = yearonly #/// check if latitudes are in increasing order ? lats = input1.lat * 1. if np.all(np.diff(lats) >= 0): f_invert = False else: f_invert = True # change sequence of data! lats = lats[::-1] if not np.all(np.diff(lats) >= 0): raise ValueError( 'Latitudes can not be put into ascending order!') #/// monthly ticks /// # convert times to monthly; apply date conversions to ensure # that generate_monthly_timeseries() can work following the # python convention data_days = generate_monthly_timeseries( pl.date2num(input1.date)) all_days = np.unique(data_days) if showxticks: self.generate_xticks(all_days, monthsamp=monthsamp) # use only ticks that are within the current latitudes mlat = (lat_tick >= lats.min()) & (lat_tick <= lats.max()) lat_tick1 = lat_tick[mlat] # interpolate the tick grid to the data grid # index positions lat_pos = np.interp(lat_tick1, lats, np.arange(len(lats))) if f_invert: # invert position back #lat_tick = lat_tick[::-1] lat_pos = lat_pos[::-1] yticklabels = np.asarray(map(str, lat_tick1)) if self.transpose: scal = self.rescalex else: scal = self.rescaley yticks = lat_pos * scal self.y_major_locator = pl.FixedLocator(yticks) self.y_major_formatter = pl.FixedFormatter(yticklabels) ylabel = 'latitude' if climits is None: raise ValueError('Hovmoeller, please specify climits') if xlabel is None: self.xlabel = 'x-label' else: self.xlabel = xlabel if figsize is None: if self.transpose: figsize = (6, 11) else: figsize = (12, 4) if ylabel is None: self.ylabel = 'y-label' else: self.ylabel = ylabel self.title = title if ax is None: self.fig = pl.figure(figsize=figsize) self.ax = self.fig.add_subplot(111) else: self.ax = ax self.fig = self.ax.figure if self.transpose: arr = self.hov.repeat(self.rescalex, axis=0).repeat(self.rescaley, axis=1) self.im = self.ax.imshow(arr.T, interpolation='Nearest', origin=origin, vmin=climits[0], vmax=climits[1], cmap=pyplot.get_cmap(cmap, nclasses)) else: # rescale array for visualization arr = self.hov.repeat(self.rescaley, axis=0).repeat(self.rescalex, axis=1) self.im = self.ax.imshow(arr, interpolation='Nearest', origin=origin, cmap=pyplot.get_cmap(cmap, nclasses), vmin=climits[0], vmax=climits[1]) if (show_uncertainties) & (self.hov_var is not None): arr1 = self.hov_var.repeat(self.rescaley, axis=0).repeat(self.rescalex, axis=1) if norm_uncertainties: # normalized by variance arr1 = arr / arr1 self.ax.contour(arr1, linestyles='-', colors='black') if xlabel is not None: self.ax.set_xlabel(self.xlabel) if ylabel is not None: self.ax.set_ylabel(self.ylabel) self.ax.set_title(self.title) #/// ticks if self.transpose: self.ax.yaxis.set_major_locator(self.x_major_locator) self.ax.yaxis.set_major_formatter(self.x_major_formatter) self.ax.xaxis.set_major_locator(self.y_major_locator) self.ax.xaxis.set_major_formatter(self.y_major_formatter) else: self.ax.yaxis.set_major_locator(self.y_major_locator) self.ax.yaxis.set_major_formatter(self.y_major_formatter) if showxticks: self.ax.xaxis.set_major_locator(self.x_major_locator) self.ax.xaxis.set_major_formatter(self.x_major_formatter) if showxticks: # pl.xticks(rotation=xtickrotation) for t in self.ax.get_xticklabels(): t.set_rotation(xtickrotation) else: self.ax.set_xticks([]) if xticks is not None: nx = 2 set_label(nx) if grid: # show grid self.ax.grid(color='white', linewidth=1, linestyle='-') #/// colorbar if showcolorbar: if self.transpose: self.fig.colorbar(self.im, orientation='vertical', shrink=0.5) else: # only do import here, as it does not work otherwise (todo) from plots import add_nice_legend add_nice_legend(self.ax, self.im, pyplot.get_cmap(cmap, nclasses))