source: qesdi/geoplot/trunk/lib/geoplot/plotarea.py @ 5704

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/geoplot/trunk/lib/geoplot/plotarea.py@5704
Revision 5704, 7.7 KB checked in by pnorton, 11 years ago (diff)

Added a module to fix the import Image / from PIL import Image problem.

Line 
1"""
2plotarea.py
3===========
4
5Holds the PlotArea class. This class is used as a wrapper to various matplotlib objects.
6"""
7import re
8import os
9import pkg_resources
10import logging
11from copy import copy
12from copy import deepcopy
13
14from matplotlib.figure import Figure
15from matplotlib.image import imread
16from matplotlib.patches import Rectangle
17from matplotlib import rcParams
18import matplotlib.ticker
19from geoplot.image_import import Image
20
21from geoplot.plot_font import PlotFont
22import geoplot.config as geoplot_config
23
24config = geoplot_config.getConfig()
25
26log = logging.getLogger(__name__)
27
28REGION_SECTION = 'PlotRegions'
29PLOT_SECTION = 'PlotProperties'
30FONTS_SECTION = 'Fonts'
31
32OUTLINE_LOGO_REGION = False
33OUTLINE_COLOUR_BAR_REGION = True
34OUTLINE_METADATA_REGION = False
35OUTLINE_PLOT = False
36
37ADUSTED_TICK_FORMAT = "%1.2f"
38MAX_CBAR_TICKS = 10
39
40class PlotArea(object):
41    """
42    Contains the neccesary matplotlib object to produce the geoplot plot,
43    also knows how to draw the peripherals to the plot (colour bar,
44    logo, metadata box)
45    """
46
47    def __init__(self, width=600, height=900, dpi=100, fontSize='medium', plotTitle='',
48                 drawColourBar=True, drawLogo=True, drawMetadata=True):
49        """
50        @param width: the width of the figure in pixels
51        @type width: integer
52        @param height: the hight of the figure in pixels
53        @type height: integer
54        @param dpi: the resolution of the produced image
55        @type dpi: integer
56        @param fontSize: the font size for the figure text
57        @type fontSize: string either 'small', 'medium' 'large'
58        @param metadataList: A list of (key, vlaue) pairs containing the plot metadata
59        @type metadataList: list of (key, value) tuples
60        @param plotTitle: the title of the plot
61        @type plotTitle: string
62        """
63
64        self.width = width
65        self.height = height
66        self.dpi = dpi
67        self.plotTitle = plotTitle
68        self.drawColourBar = drawColourBar
69        self.drawLogo = drawLogo
70        self.drawMetadata = drawMetadata
71
72        #values for the metadata box
73        self.fontSize = fontSize
74
75        #initialise the fonts
76        self.axisTickFont  = config[FONTS_SECTION]['AxisTick']
77        self.plotTitleFont = config[FONTS_SECTION]['PlotTitle']
78
79        #initialise the regions
80        self.metadataRegion     = config[REGION_SECTION]['metadataRegion']
81        self.logoRegion         = config[REGION_SECTION]['logoRegion']
82        self.plotRegionShort    = config[REGION_SECTION]['plotRegionShort']
83        self.plotRegionThin     = config[REGION_SECTION]['plotRegionThin']
84        self.plotRegionFull     = config[REGION_SECTION]['plotRegionFull']
85        self.cbHorizontalRegion = config[REGION_SECTION]['cbHorizontalRegion']
86        self.cbVerticalRegion   = config[REGION_SECTION]['cbVerticalRegion']
87       
88
89    def setupArea(self, colourBarPosition):
90        """
91        Initialises the axes and fonts to be used in plotting the graph.
92
93        After calling this changing some of the plotarea properties may not correctly
94        impact the resulting graph.
95        """
96       
97        log.info("Setting up plot area")
98
99        self._setAxisTickSize()
100
101        self._setupAxes(colourBarPosition)
102
103        #set the plot title
104        plotTitleDictionary = self.plotTitleFont.getDict(self.fontSize)
105        self.axes.set_title(self.plotTitle, fontdict=plotTitleDictionary)
106
107
108    def _setAxisTickSize(self):
109        """
110        Sets the size for the axis labels and the colourBar labels.
111        """
112        tickSize = self.axisTickFont.getSize(self.fontSize)
113        rcParams['xtick.labelsize'] = tickSize
114        rcParams['ytick.labelsize'] = tickSize
115
116    def _setupAxes(self, colourBarPosition):
117        """
118        Adds the required axis to the figure object ready for the plot, the main axis is
119        where the actual map is drawn, the metadata axis for the metadata box and the
120        colourbar axis for the colourbar.
121
122        The axis are only added to the figure if they will be needed. The size of the axis
123        are set in the contstructor and taken from config.ini
124        """
125       
126        figsize=(self.width / self.dpi, self.height / self.dpi)
127        self.figure = Figure(figsize=figsize, dpi=self.dpi, facecolor='w')
128
129        #outline plot
130        if OUTLINE_PLOT == True:
131            outline = self.figure.add_axes([0.005,0.005,0.99,0.99],
132                                           frameon=True, xticks=[], yticks=[])
133
134        #need to make sure the local regions are copies as changing one of them
135        #will change the value in the config object
136        if self.drawColourBar == False:
137            pRegion = copy(self.plotRegionFull)
138        elif colourBarPosition == 'horizontal':
139            cbRegion = copy(self.cbHorizontalRegion)
140            pRegion = copy(self.plotRegionShort)
141        elif colourBarPosition == 'vertical':
142            cbRegion = copy(self.cbVerticalRegion)
143            pRegion = copy(self.plotRegionThin)
144        else:
145            raise ValueError, "unknown value for colour bar position :", self.colourBarPosition
146       
147        pRegion = list(pRegion)
148
149        # if there is no metadata or logo then make the plot taller by the hight of the
150        # metadata region
151       
152#        log.debug("DrawMetadata:" + str(drawMetadata) + \
153#                  " DrawLogo:" + str(drawLogo))
154       
155        if self.drawMetadata == False and self.drawLogo == False:
156#            log.debug("Shifting Region Up")
157            pRegion[3] += self.metadataRegion[3]
158
159        log.debug("Plot Region:" + str(pRegion))
160
161        #construct the axes obejcts for the colour bar, the plot and the metadata box
162        if self.drawColourBar == True:
163            log.debug("cbRegion , cbRegion.__class__ = %s, %s" % (cbRegion, cbRegion.__class__))
164            self.cbAxes = self.figure.add_axes(cbRegion,
165                                               frameon=OUTLINE_COLOUR_BAR_REGION,
166                                               xticks=[], yticks=[])
167
168        if self.drawMetadata == True:
169            self.metadataAxes = self.figure.add_axes(self.metadataRegion,
170                                                     frameon=OUTLINE_METADATA_REGION,
171                                                     xticks=[], yticks=[])
172
173        if self.drawLogo == True:
174            self.logoAxes = self.figure.add_axes(self.logoRegion,
175                                                 frameon=OUTLINE_LOGO_REGION,
176                                                 xticks=[], yticks=[])
177
178        self.axes = self.figure.add_axes(pRegion, frameon=True)
179
180    @staticmethod
181    def _transformListToFloats(list):
182        """
183        transforms a list of items to a list of floats, the conversion is done using the
184        float() function.
185        """
186        newList = []
187        for item in list:
188            newList.append(float(item))
189        return newList
190
191
192if __name__ == '__main__':
193
194
195    from matplotlib.backends.backend_agg import FigureCanvasAgg
196    from matplotlib.backends.backend_ps import FigureCanvasPS
197
198    import log_util
199    log_util.setupGeoplotConsoleHandler(log)
200
201    OUTLINE_LOGO_REGION = True
202    OUTLINE_COLOUR_BAR_REGION = True
203    OUTLINE_METADATA_REGION = True
204    OUTLINE_PLOT = True
205
206    from cdms_utils.cdms_compat import N
207    #800, 1200
208    # A4 at 80dpi is 935.2, 661.6
209    plot = PlotArea(800, 1200 , 80,"large", "Some Plot")
210
211    plot.setupArea(False, False, True, 'horizontal')
212
213    x = N.arange(0, 2*N.pi, 0.1)
214    plot.axes.scatter(x, N.sin(x))
215
216    fname = "out.png"
217    canvas = FigureCanvasAgg(plot.figure)
218    canvas.print_figure(fname, dpi=plot.figure.get_dpi())
219    log.debug("wrote, " + fname)
220
221    fname = "out.ps"
222    canvas = FigureCanvasPS(plot.figure)
223    canvas.print_figure(fname, dpi=plot.figure.get_dpi())
224    log.debug("wrote, " + fname)
Note: See TracBrowser for help on using the repository browser.