pywws.WindRose — pywws v12.11_95babb0 documentation

### Navigation

- index
- modules |
- pywws v12.11_95babb0 documentation »
- Module code »

# Source code for pywws.WindRose

    #!/usr/bin/env python

    """
    Plot a "wind rose".

    usage: python WindRose.py [options] data_dir temp_dir xml_file output_file
    options are:
    \t-h or --help\t\tdisplay this help
    data_dir is the root directory of the weather data
    temp_dir is a workspace for temporary files e.g. /tmp
    xml_file is the name of the source file that describes the plot
    output_file is the name of the image file to be created e.g. 24hrs.png
    """

    import codecs
    from datetime import datetime, timedelta
    import getopt
    import math
    import os
    import sys
    import xml.dom.minidom

    from conversions import *
    import DataStore
    import Localisation
    from Plot import BasePlotter
    from TimeZone import Local
    from WeatherStation import dew_point

    class RosePlotter(BasePlotter):
        def GetPlotList(self):
            return self.GetChildren(self.graph, 'windrose')
        def GetDefaultRows(self):
            return int(math.sqrt(self.plot_count))
        def GetDefaultPlotSize(self):
            return 600 / self.rows, 600 / self.rows
        def GetPreamble(self):
            result = """set polar
    set angles degrees
    set xtics axis nomirror
    set ytics axis nomirror
    set zeroaxis
    set grid polar 22.5
    set size square
    unset border
    """
            lmargin = eval(self.GetValue(self.graph, 'lmargin', '-1'))
            result += 'set lmargin %g\n' % (lmargin)
            lmargin = eval(self.GetValue(self.graph, 'rmargin', '-1'))
            result += 'set rmargin %g\n' % (lmargin)
            lmargin = eval(self.GetValue(self.graph, 'tmargin', '-1'))
            result += 'set tmargin %g\n' % (lmargin)
            lmargin = eval(self.GetValue(self.graph, 'bmargin', '-1'))
            result += 'set bmargin %g\n' % (lmargin)
            return result
        def PlotData(self, plot_no, plot, source):
            _ = Localisation.translation.ugettext
            # get statistics
            thresh = eval(self.GetValue(
                plot, 'threshold', '0.0, 1.54, 3.09, 5.14, 8.23, 10.8, 15.5'))
            thresh = thresh + (1000.0,)
            colour = eval(self.GetValue(plot, 'colour', str(range(len(thresh)))))
            xcalc = self.GetValue(plot, 'xcalc', 'True')
            xcalc = compile(xcalc, '<string>', 'eval')
            ycalc = self.GetValue(plot, 'ycalc', None)
            ycalc = compile(ycalc, '<string>', 'eval')
            histograms = []
            for i in range(len(thresh)):
                hist = []
                for n in range(16):
                    hist.append(0)
                histograms.append(hist)
            # x_lo & x_hi are in local time, data is indexed in UTC
            start = self.x_lo - self.utcoffset
            stop = self.x_hi - self.utcoffset
            stop = stop + timedelta(minutes=1)
            for data in source[start:stop]:
                wind_dir = data['wind_dir']
                if wind_dir == None or wind_dir >= 16:
                    continue
                if not eval(xcalc):
                    continue
                value = eval(ycalc)
                if value is None:
                    continue
                for t in range(len(thresh)):
                    if value <= thresh[t]:
                        histograms[t][wind_dir] += 1
                        break
            # evenly distribute zero speed
            total = 0
            for n in range(16):
                total += histograms[0][n]
            for n in range(16):
                histograms[0][n] = total / 16
            # integrate histograms
            for i in range(1, len(thresh)):
                for n in range(16):
                    histograms[i][n] += histograms[i-1][n]
            total = 0
            for n in range(16):
                total += histograms[-1][n]
            result = ''
            yrange = self.GetValue(plot, 'yrange', '31')
            if yrange == '*':
                # auto-ranging
                if total > 0:
                    max_petal = 100.0 * float(max(histograms[-1])) / float(total)
                else:
                    max_petal = 0.0
                if max_petal > 40.0:
                    yrange = (int(max_petal / 20.0) * 20) + 21
                elif max_petal > 30.0:
                    yrange = 41
                elif max_petal > 20.0:
                    yrange = 31
                else:
                    yrange = 21
            else:
                yrange = eval(yrange)
            result += 'set xrange [-%d:%d]\n' % (yrange, yrange)
            result += 'set yrange [-%d:%d]\n' % (yrange, yrange)
            points = [_('N'), _('S'), _('E'), _('W')]
            points = eval(self.GetValue(plot, 'points', str(points)))
            result += 'set label 1000 "%s" at 0, %d center front\n' % (points[0], yrange)
            result += 'set label 1001 "%s" at 0, -%d center front\n' % (points[1], yrange)
            result += 'set label 1002 "%s" at %d, 0 center front\n' % (points[2], yrange)
            result += 'set label 1003 "%s" at -%d, 0 center front\n' % (points[3], yrange)
            # plot segments for each speed-direction
            result += 'plot '
            for i in reversed(range(len(thresh))):
                dat_file = os.path.join(self.work_dir, 'plot_%d_%d.dat' % (plot_no, i))
                self.tmp_files.append(dat_file)
                dat = open(dat_file, 'w')
                sub_total = 0
                for n in range(16):
                    angle = 90.0 - (n * 22.5)
                    sub_total += histograms[i][n]
                    if i > 0:
                        sub_total -= histograms[i-1][n]
                    if total > 0:
                        value = 100.0 * float(histograms[i][n]) / float(total)
                    else:
                        value = 0.0
                    if i == 0:
                        dat.write('%g %g\n' % (angle - 11.24, value * 0.994))
                    else:
                        dat.write('%g %g\n' % (angle - 8.1, 0))
                    dat.write('%g %g\n' % (angle - 8.0, value * 0.997))
                    dat.write('%g %g\n' % (angle, value))
                    dat.write('%g %g\n' % (angle + 8.0, value * 0.997))
                    if i == 0:
                        dat.write('%g %g\n' % (angle + 11.24, value * 0.994))
                        dat.write('%g %g\n' % (angle + 11.25, 0))
                    else:
                        dat.write('%g %g\n' % (angle + 8.1, 0))
                dat.close()
                # plot data
                if total > 0:
                    value = 100.0 * float(sub_total) / float(total)
                else:
                    value = 0.0
                if i == 0:
                    title = '0 .. %g (%.3g%%)' % (thresh[i], value)
                elif i == len(thresh) - 1:
                    title = '> %g (%.3g%%)' % (thresh[i-1], value)
                else:
                    title = '%g .. %g (%.3g%%)' % (thresh[i-1], thresh[i], value)
                result += '"%s" using 1:2 title "%s" with filledcurve lt %d' % (
                    dat_file, title, colour[i % len(colour)])
                if i > 0:
                    result += ', \\'
                result += '\n'
            return result
    def main(argv=None):
        if argv is None:
            argv = sys.argv
        try:
            opts, args = getopt.getopt(argv[1:], "h", ['help'])
        except getopt.error, msg:
            print >>sys.stderr, 'Error: %s\n' % msg
            print >>sys.stderr, __doc__.strip()
            return 1
        # process options
        for o, a in opts:
            if o == '-h' or o == '--help':
                print __doc__.strip()
                return 0
        # check arguments
        if len(args) != 4:
            print >>sys.stderr, 'Error: 4 arguments required\n'
            print >>sys.stderr, __doc__.strip()
            return 2
        params = DataStore.params(args[0])
        Localisation.SetApplicationLanguage(params)
        return RosePlotter(
            params,
            DataStore.calib_store(args[0]), DataStore.hourly_store(args[0]),
            DataStore.daily_store(args[0]), DataStore.monthly_store(args[0]),
            args[1]
            ).DoPlot(args[2], args[3])
    if __name__ == "__main__":
        sys.exit(main())

### Navigation

- index
- modules |
- pywws v12.11_95babb0 documentation »
- Module code »