Drawing wind roses (IndexError: list index out of range)

65 阅读3分钟

尝试使用下面的代码绘制风玫瑰图。几个月前代码可以运行。

import sys
from windrose import WindroseAxes
from matplotlib import pyplot as plt
import matplotlib.cm as cm
from numpy.random import random
from numpy import arange
import os
import numpy as np

def plot(prefix, spds, dirs):
    ws = np.array(spds)
    wd = np.array(dirs)

    def new_axes():
        fig = plt.figure(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='w')
        rect = [0.1, 0.1, 0.8, 0.8]
        ax = WindroseAxes(fig, rect, axisbg='w')
        fig.add_axes(ax)
        return ax, fig

    def set_legend(ax):
        l = ax.legend(axespad=-0.10, title="m/s", loc=0)
        plt.setp(l.get_texts(), fontsize=8)

    # windrose like a stacked histogram with normed (displayed in percent) results
    ax, fig = new_axes()
    ax.bar(wd, ws, normed=True, opening=0.8, edgecolor='white', bins=arange(0,max(ws),5))
    set_legend(ax)
    tokens = prefix.split("/")[-1].split("_")
    if tokens[0] == "Dust":
        title = "%s Dust" % tokens[1]
    else:
        title = tokens[0]

    plt.title(title, y=1.08)
    fig.savefig("%s-fig1.png" % prefix)

def main(folder="data"):    
    for filename in filter(lambda x:x.endswith(".csv"), os.listdir(folder)):
        path = "%s/%s" % (folder, filename)
        plot_path = "%s/plots" % folder
        if not os.path.exists(plot_path):
            os.mkdir(plot_path)
        print path
        f = open(path)
        f.readline()
        directions = []
        speeds = []
        for line in f:
            cols = line.split(",")    
            direction = cols[5]
            speed = cols[6]
            try:
                direction = int(direction)
                speed = int(speed) * 0.44704
            except:
                continue

            directions.append(direction)
            speeds.append(speed)

        plot("%s/plots/%s" % (folder, filename.split(".")[0]), speeds, directions)

if __name__ == "__main__":
    main(sys.argv[1])

但是运行时出现错误:

IndexError                                Traceback (most recent call last)

/Users/Abdulhaleem-Labban/Dropbox/windrose/process.py in <module>()
    112 
    113 if __name__ == "__main__":
--> 114     main(sys.argv[1])
    115 

IndexError: list index out of range 

数据文件名为 Dust_TabukWI_Wind.csv,示例如下:

Tabuk   YR--    MO  DA  HRMN    DIR SPD VSB MW
403750  1985    1   1   1125    240 28  0.4 32
403750  1985    1   18  1200    230 34  0.1 33
403750  1985    12  18  600     120 14  6.2 30
403750  1988    11  30  1300    340 34  0.3 32
403750  1992    12  15  900     240 31  0.3 33
403750  1992    12  15  1000    240 29  0.3 33
403750  1992    12  15  1100    240 29  0.6 33
403750  2008    1   29  1100    220 29  0.6 31
403750  2008    1   29  1200    210 34  3.1 30
403750  2008    1   29  1300    210 34  1.9 31

运行如下脚本:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__version__ = '1.4'
__author__ = 'Lionel Roubeyrie'
__mail__ = 'lionel.roubeyrie@gmail.com'
__license__ = 'CeCILL-B'

import matplotlib
import matplotlib.cm as cm
import numpy as np
from matplotlib.patches import Rectangle, Polygon
from matplotlib.ticker import ScalarFormatter, AutoLocator
from matplotlib.text import Text, FontProperties
from matplotlib.projections.polar import PolarAxes
from numpy.lib.twodim_base import histogram2d
import matplotlib.pyplot as plt
from pylab import poly_between

RESOLUTION = 100
ZBASE = -1000 #The starting zorder for all drawing, negative to have the grid on

class WindroseAxes(PolarAxes):
    """

    Create a windrose axes

    """

    def __init__(self, *args, **kwargs):
        """
        See Axes base class for args and kwargs documentation
        """

        #Uncomment to have the possibility to change the resolution directly 
        #when the instance is created
        #self.RESOLUTION = kwargs.pop('resolution', 100)
        PolarAxes.__init__(self, *args, **kwargs)
        self.set_aspect('equal', adjustable='box', anchor='C')
        self.radii_angle = 67.5
        self.cla()


    def cla(self):
        """
        Clear the current axes
        """
        PolarAxes.cla(self)

        self.theta_angles = np.arange(0, 360, 45)
        self.theta_labels = ['E', 'N-E', 'N', 'N-W', 'W', 'S-W', 'S', 'S-E']
        self.set_thetagrids(angles=self.theta_angles, labels=self.theta_labels)

        self._info = {'dir' : list(),
                      'bins' : list(),
                      'table' : list()}

        self.patches_list = list()


    def _colors(self, cmap, n):
        '''
        Returns a list of n colors based on the colormap cmap

        '''
        return [cmap(i) for i in np.linspace(0.0, 1.0, n)]


    def set_radii_angle(self, **kwargs):
        """
        Set the radii labels angle
        """

        null = kwargs.pop('labels', None)
        angle = kwargs.pop('angle', None)
        if angle is None:
            angle = self.radii_angle
        self.radii_angle = angle
        print self.get_rmax()
        radii = np.linspace(0.1, self.get_rmax(), 6)
        radii_labels = [ "%.1f%%" %r for r in radii ]
        radii_labels[0] = "" #Removing label 0
#        radii_labels = ["" for r in radii]
        null = self.set_rgrids(radii=radii, labels=radii_labels,
                               angle=self.radii_angle, **kwargs)


    def _update(self):
        self.set_rmax(rmax=np.max(np.sum(self._info['table'], axis=0)))
        self.set_radii_angle(angle=self.radii_angle)


    def legend(self, loc='lower left', **kwargs):
        """
        Sets the legend location and her properties.
        The location codes are

          'best'         : 0,
          'upper right'  : 1,
          'upper left'   : 2,
          'lower left'   :