Module crepyscule_graphic
[hide private]
[frames] | no frames]

Source Code for Module crepyscule_graphic

  1  #!/usr/bin/env python 
  2  # -*- coding: iso-8859-1 -*- 
  3   
  4  # Copyright 2005,2008  Miguel Tremblay 
  5   
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 3 of the License, or 
  9  # (at your option) any later version. 
 10   
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15   
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not see  <http://www.gnu.org/licenses/>. 
 18  ############################################################################ 
 19   
 20  """ 
 21  Package that contains everything to plot graphics for crepyscule. 
 22  Based on U{rpy<http://rpy.sourceforge.net/>} and 
 23  U{GDD<http://www.rosuda.org/R/GDD/>} (U{R language<http://ptaff.ca/crepyscule/>}). All images are in the png format. 
 24   
 25  Project home page is U{http://ptaff.ca/crepyscule/} 
 26              
 27   - Author:      U{Miguel Tremblay<http://ptaff.ca/miguel/>} 
 28   - Date:        February 20th  2005 
 29   - Name:        crepyscule_graphic.py 
 30  """ 
 31   
 32  import sys 
 33  import time 
 34  import calendar 
 35   
 36  import numpy 
 37   
 38  import crepyscule_tools 
 39   
 40  # Set the place where to fetch languages dependant messages 
 41  import gettext 
 42  t = gettext.translation('crepyscule_graphic', sys.path[0] + '/locale') 
 43  _ = t.gettext 
 44   
 45   
 46  # Graphics element used in both day by day and month plot. 
 47  lMonthString = [_('JAN'), _('FEB'), _('MAR'), \ 
 48                  _('APR'), _('MAY'), _('JUN'),\ 
 49                  _('JUL'), _('AUG'), _('SEP'),\ 
 50                  _('OCT'), _('NOV'), _('DEC')] 
 51  nPngWidth = 640 
 52  nPngHeight =480 
 53  rlMonth = None 
 54  rX_axis = None 
 55  sColor = 'white' #'transparent' 
 56  sFirstCityColor = 'blue' 
 57  sSecondCityColor = 'limegreen' 
 58   
59 -def init_time_values(lDateISO8601):
60 """ 61 Set the value of time used by the graphs. 62 Declare the import here because a lot of output are written when it 63 is done and we do not want to have it every time crepyscule is invoked, 64 only when this module is called. 65 66 @type lDateISO8601: liste 67 @param lDateISO8601: Create the X axis based on the values of the list. 68 Values are one year date in iso8601 format. 69 """ 70 global lMonthString, nPngWidth, nPngHeight 71 global rlMonth, sColor, rX_axis 72 global rpy, r 73 import rpy 74 from rpy import r 75 r.library("GDD") 76 77 if rX_axis == None: 78 rpy.set_default_mode(rpy.NO_CONVERSION) 79 rX_axis = r.strptime(lDateISO8601, "%Y-%m-%d") 80 rlRange_year = r.range(rX_axis) # X 81 rlMonth = r.seq(rlRange_year[0], rlRange_year[1], by="months")
82
83 -def plot_altitude(tToday, lSunAltitude, lDateISO8601, sFilename,\ 84 sBackgroundColor, lSunAltitude2=None):
85 """ 86 Plot the altitude of the sun during a year. 87 88 @type tToday: tuple 89 @param tToday: Tuple as returned by the function time.gmtime. 90 @type lSunAltitude: list 91 @param lSunAltitude: list of Sun altitude for the first place. 92 @type lDateISO8601: list 93 @param lDateISO8601: List of strings for one year in iso8601 format. 94 @type sFilename: string 95 @param sFilename: Filename to save the graph. Filename is transformed like 96 'file.png' to 'file_alt.png'. 97 @type sBackgroundColor: string 98 @param sBackgroundColor: Color that will be used for the background 99 color for the generated graphics. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} 100 @type lSunAltitude2: list 101 @param lSunAltitude2: list of Sun altitude for the second place. 102 """ 103 104 init_time_values(lDateISO8601) 105 sFilenameAltitude = crepyscule_tools.remove_extension(sFilename) +\ 106 '_alt.png' 107 sTitlePlot = _("Maximum altitude of the sun") 108 109 r.GDD(sFilenameAltitude, type='png', w = nPngWidth, h = nPngHeight,\ 110 bg='white', ps=8) 111 112 r.par(las=1) 113 114 r.plot(rX_axis, lSunAltitude, ylim=[0, 90], xaxs='i', 115 lty=0, type='l', bg='blue',\ 116 xlab='Date', ylab=_('Altitude (degrees)'), main=sTitlePlot, 117 xaxt='n', yaxt='n') 118 lUsr = r.par("usr") 119 120 121 ## Axis 122 r.axis(2, range(0,91,5)) # Y 123 r.axis(1, at=rlMonth, labels=lMonthString) 124 ### Grid 125 rXdomain = r.c(lUsr[0], lUsr[1]) 126 for i in range(0, 91, 5): 127 rYdomain = r.c(i,i) 128 r.lines(rXdomain, rYdomain, col='gray70') # Horizontal lines 129 rYdomain = r.c(lUsr[2], lUsr[3]) 130 for rnMonth in rlMonth: 131 rXdomain = r.c(rnMonth, rnMonth) 132 r.lines(rXdomain, rYdomain, col='gray70') # Vertical lines 133 r.lines( r.c(rlMonth[0], rlMonth[0]), rYdomain, col='black') 134 # Draw altitude 135 r.lines(rX_axis, lSunAltitude, col=sFirstCityColor, lwd=2) 136 137 if lSunAltitude2 != None: 138 r.lines(rX_axis, lSunAltitude2, col=sSecondCityColor, lwd=2) 139 else: 140 fAltitude = lSunAltitude[tToday[7]] 141 __draw_today(tToday, fAltitude, round(fAltitude), 45) 142 143 r.dev_off() 144 print "filename", sFilenameAltitude
145
146 -def __draw_today_sun(tToday, fSunriseTime, fSunsetTime):
147 """ 148 Add information about current day on the graphics of sunset and sunrise. 149 Draw a vertical line for the current date. 150 Draw a circle at the place where this vertical line cross each of the 151 three lines (sunset, sunrise, total day light). 152 Write the value of at these circles. 153 154 @type tToday: tuple 155 @param tToday: Tuple as returned by the function time.gmtime. 156 @type fSunsetTime: float 157 @param fSunsetTime: Time of sunset. 158 @type fSunriseTime: float 159 @param fSunriseTime: Time of sunrise. 160 """ 161 lUsr = r.par('usr') 162 if fSunsetTime > fSunriseTime: 163 fTotalTime = fSunsetTime - fSunriseTime 164 else: 165 fTotalTime = fSunriseTime - fSunsetTime 166 167 # Ugly, ugly way to get a date. Try to be more elegant. Please. 168 rToday = r.strptime(time.strftime("%Y-%m-%d", tToday), "%Y-%m-%d") 169 cTimeToday = time.mktime(tToday) 170 171 # Vertical line #################### 172 rXdomain = r.c(rToday, rToday) 173 rYdomain = r.c(lUsr[2], lUsr[3]) 174 r.lines(rXdomain, rYdomain, col='gray20', lty='dashed') 175 # Circles. Text only use ctime... ############ 176 r.points(cTimeToday, fSunsetTime, lwd=2, pch=19) 177 r.points(cTimeToday, fSunriseTime, lwd=2, pch=19) 178 r.points(cTimeToday, fTotalTime, lwd=2, pch=19) 179 # Text ######### 180 tSunrise = crepyscule_tools.tranform_decimal_hour_in_minutes(\ 181 fSunriseTime) 182 tSunset = crepyscule_tools.tranform_decimal_hour_in_minutes(\ 183 fSunsetTime) 184 tTotalTime = crepyscule_tools.tranform_decimal_hour_in_minutes(\ 185 fTotalTime) 186 sSunrise = tSunrise[0] + ':' + tSunrise[1] 187 sSunset = tSunset[0] + ':' + tSunset[1] 188 sTotalTime = tTotalTime[0] + ':' + tTotalTime[1] 189 190 # Position of text for sunrise time 191 # Standard position is BELOW 192 ABOVE = 3 193 BELOW = 1 194 nPosTotal = nPosSunrise = nPosSunset = BELOW 195 if fSunriseTime < 1 : 196 nPosSunrise = ABOVE 197 fDiffTotalSunrise = fTotalTime - fSunriseTime 198 if fDiffTotalSunrise > 0 and fDiffTotalSunrise < 2: 199 nPosTotal = ABOVE 200 elif fDiffTotalSunrise < 0 and abs(fDiffTotalSunrise) < 2: 201 nPosSunrise = ABOVE 202 203 r.text(cTimeToday, fSunriseTime, labels=sSunrise, pos=nPosSunrise, \ 204 xpd=r.TRUE) 205 r.text(cTimeToday, fSunsetTime, labels=sSunset, pos=nPosSunset, \ 206 xpd=r.TRUE) 207 r.text(cTimeToday, fTotalTime, labels=sTotalTime, pos=nPosTotal, \ 208 xpd=r.TRUE)
209
210 -def __draw_today(tToday, fTodayValue, sLabel, fMiddleOfGraph):
211 """ 212 Draw a line in the graphic for the value of the current day. 213 NOT for sunrise/sunset. See L{__draw_today_sun} in this case. 214 X{private} 215 216 @type tToday: tuple 217 @param tToday: Tuple as returned by the function time.gmtime. 218 @type fTodayValue: float 219 @param fTodayValue: Value to be mark on the curve. 220 @type sLabel: string 221 @param sLabel: Label to be written at the position of the mark. 222 @type fMiddleOfGraph: float 223 @param fMiddleOfGraph: Middle of the Y axis. Used to know if the label 224 goes over or under the bullet on the curve. 225 """ 226 227 lUsr = r.par('usr') 228 rToday = r.strptime(time.strftime("%Y-%m-%d", tToday), "%Y-%m-%d") 229 cTimeToday = time.mktime(tToday) 230 231 232 # Vertical line #################### 233 rXdomain = r.c(rToday, rToday) 234 rYdomain = r.c(lUsr[2], lUsr[3]) 235 r.lines(rXdomain, rYdomain, col='gray20', lty='dashed') 236 # Circles. Text only use ctime... ############ 237 r.points(cTimeToday, fTodayValue, lwd=2, pch=19) 238 # Position of text for sunrise time 239 # Standard position is BELOW 240 ABOVE = 3 241 BELOW = 1 242 if fTodayValue < fMiddleOfGraph : 243 nPos = ABOVE 244 else: 245 nPos = BELOW 246 247 r.text(cTimeToday, fTodayValue, labels=sLabel, pos=nPos, \ 248 xpd=r.TRUE)
249 250
251 -def plot_sunset_sunrise(lSunrise, lSunset, lDaylength, lDateISO8601,\ 252 sFilename, tToday, sBackgroundColor, \ 253 lSunrise2=None, lSunset2=None, lDaylength2=None):
254 """ 255 Plot the sunset and the sunrise of one year. 256 257 @type lSunrise: list 258 @param lSunrise: List of sunrise values for one year for the first place. 259 @type lSunset: list 260 @param lSunset: List of sunset values for one year for the first place. 261 @type lDaylength: list 262 @param lDaylength: List of day length for each day of the year. 263 @type lDateISO8601: list 264 @param lDateISO8601: List of strings for one year in iso8601 format. 265 @type sFilename: string 266 @param sFilename: Filename to save the graph. 267 @type tToday: tuple 268 @param tToday: Tuple as returned by the function time.gmtime. 269 @type sBackgroundColor: string 270 @param sBackgroundColor: Color that will be used for the background 271 color for the generated graphics. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} 272 @type lSunrise2: list 273 @param lSunrise2: List of sunrise values for one year for the second place. 274 @type lSunset2: list 275 @param lSunset2: List of sunset values for one year for the second place. 276 @type lDaylength2 list 277 @param lDaylength2: List of day length for each day of the year for the 278 second place. 279 """ 280 init_time_values(lDateISO8601) 281 sTitle = _("Sunrise, sunset and daylight") 282 283 r.GDD(sFilename, type='png', w = nPngWidth, h = nPngHeight,\ 284 bg=sBackgroundColor, ps=8) 285 if len(lSunrise) != len(lSunset) != len(lDateISO8601): 286 print _("List must have the same length!") 287 print _("Sunrise: %d \n Sunset: %d \n Date: %d") % \ 288 (len(lSunrise), len(lSunset), len(lDateISO8601)) 289 return 290 291 # Use the current julian day to get sunrise/sunset for today 292 fTodaySunriseTime = lSunrise[tToday[7]-1] 293 fTodaySunsetTime = lSunset[tToday[7]-1] 294 295 # Bugs of Sun.py patch 296 (nIndiceStartSunset, nIndiceEndSunset) = crepyscule_tools.\ 297 check_value_over_24(lSunset) 298 (nIndiceStartSunrise, nIndiceEndSunrise) = crepyscule_tools.\ 299 check_value_under_0(lSunrise) 300 (npSunrise, npSunset) = crepyscule_tools.\ 301 correct_sun_bugs(lSunrise, lSunset) 302 303 if lSunrise2 != None and lSunset2 != None: 304 (nIndiceStartSunset2, nIndiceEndSunset2) = \ 305 crepyscule_tools.check_value_over_24(lSunset2) 306 (nIndiceStartSunrise2, nIndiceEndSunrise2) = \ 307 crepyscule_tools.check_value_under_0(lSunrise2) 308 309 (npSunrise2, npSunset2) = crepyscule_tools.\ 310 correct_sun_bugs(lSunrise2, lSunset2) 311 312 r.par(las=1) 313 sYLabel = _("Time of day") 314 315 r.plot(rX_axis, lSunrise, ylim=[1, 23.5], xaxs='i', \ 316 lty=0, type='l',\ 317 xlab='Date', ylab=sYLabel, main=sTitle, xaxt='n', yaxt='n') 318 lUsr = r.par("usr") 319 ## Axis 320 r.axis(2, range(0,24)) # Y 321 r.axis(1, at=rlMonth, labels=lMonthString) 322 323 ### Grid 324 rXdomain = r.c(lUsr[0], lUsr[1]) 325 for i in range(1, 25): 326 rYdomain = r.c(i,i) 327 r.lines(rXdomain, rYdomain, col='gray70') # Horizontal lines 328 rYdomain = r.c(lUsr[2], lUsr[3]) 329 for rnMonth in rlMonth: 330 rXdomain = r.c(rnMonth, rnMonth) 331 r.lines(rXdomain, rYdomain, col='gray70') # Vertical lines 332 r.lines( r.c(rlMonth[0], rlMonth[0]), rYdomain, col='black') 333 334 draw_sunrise_sunset(npSunrise, npSunset, lDaylength,\ 335 nIndiceStartSunrise, nIndiceEndSunrise,\ 336 nIndiceStartSunset, nIndiceEndSunset, lDateISO8601) 337 338 if lSunrise2 == None: 339 __draw_today_sun(tToday, fTodaySunriseTime,fTodaySunsetTime) 340 341 else: 342 draw_sunrise_sunset(npSunrise2, npSunset2, lDaylength2, \ 343 nIndiceStartSunrise2, nIndiceEndSunrise2,\ 344 nIndiceStartSunset2, nIndiceEndSunset2,\ 345 lDateISO8601,\ 346 sColorSunrise='maroon', sColorSunset='saddlebrown',\ 347 sColorTotalTime='purple') 348 349 350 r.dev_off()
351
352 -def plot_monthly(lMonthLight, sFilename):
353 """ 354 DEPRECATED 355 Plot a graphical with total hour of light for each month. Was used 356 for debugging and development phase. Probably won't work. Code source 357 is left here in case someone wants to use it. If it is your case, please 358 U{contact the author<mailto:miguel.tremblay@ptaff.ca>}. 359 360 @type lMonthLight: list 361 @param lMonthLight: list containing the sum of day light for each month. 362 @type sFilename: string 363 @param sFilename: Filename to save the graph. Filename is transformed like 364 'file.png' to 'file_month.png'. 365 """ 366 init_time_values(lDateISO8601) 367 368 sFilenameMonth = remove_extension(sFilename) + '_month.png' 369 r.png(sFilenameMonth, nPngWidth, nPngHeight, bg=sColor) 370 r.par(las=1) 371 rMidPoint = r.barplot(lMonthLight, names=lMonthString, \ 372 col='red', ylim=[0,max(lMonthLight)+100]) 373 lUsr = r.par('usr') 374 # Print the total number of hours on top of each bar 375 for i in range(0,len(rMidPoint)): 376 if int(lMonthLight[i]) != 0: 377 lrange = calendar.monthrange(2005, i+1) 378 r.axis(1, at=rMidPoint[i], \ 379 labels=round(lMonthLight[i]/lrange[1],1), tick=0,\ 380 pos=lMonthLight[i]+(lUsr[3].as_py(rpy.BASIC_CONVERSION))/10) 381 # Write the total number of hours 382 sTotalHour = str(int(numpy.array(lMonthLight).sum())) + \ 383 _(" hours of light in all year") 384 r.text((lUsr[0].as_py(rpy.BASIC_CONVERSION)+\ 385 lUsr[1].as_py(rpy.BASIC_CONVERSION))/2, \ 386 lUsr[3], labels=sTotalHour, pos=1) 387 r.dev_off()
388 389 390
391 -def draw_sunrise_sunset(npSunrise, npSunset, npSunTime,\ 392 nIndiceStartSunrise, nIndiceEndSunrise, \ 393 nIndiceStartSunset, nIndiceEndSunset, \ 394 lDateISO8601, sLty='solid', 395 sColorSunrise='orange', sColorSunset='red', \ 396 sColorTotalTime='blue'):
397 """ 398 Draw sunrise and sunset lines on the graphics. This function is empiric. 399 It has been developed by trials and errors, there is not much to 400 understand. 401 402 There is only two complex case that are handled: when the sunrise (sunset) 403 curve goes under (over) zero (24) value during one segment. In this case, 404 there is 3 curves that are created corresponding to the value of 405 rX_axis1, rX_axis2 and rX_axis3. 406 407 @type npSunrise: numpy.array 408 @param npSunrise: Array of sunrise values for one year to be displayed. 409 @type npSunset: numpy.array 410 @param npSunset: Array of sunset values for one year to be displayed. 411 @type nIndiceStartSunrise: int 412 @param nIndiceStartSunrise: Indice where the sunrise goes under the zero 413 value. If there is no such place, zero is given. 414 @type nIndiceEndSunrise: int 415 @param nIndiceEndSunrise: Indice where the sunrise goes over zero if it 416 ever goes under it. If it does not occurs, the length of the array 417 (365 or 366) is given. 418 @type nIndiceStartSunset: int 419 @param nIndiceStartSunset: Indice where the sunrise goes over 24 420 value. If there is no such place, zero is given. 421 @type nIndiceEndSunset: int 422 @param nIndiceEndSunset: Indice where the sunset goes under 24 if it 423 ever goes over it. If it does not occurs, the length of the array 424 (365 or 366) is given. 425 @type lDateISO8601: list 426 @param lDateISO8601: List of strings for one year in iso8601 format. 427 @type sLty: string 428 @param sLty: R Line style. See help for 'lty' in the 'par' documentation 429 in R 430 @type sColorSunrise: string 431 @param sColorSunrise: Color of sunrise curve. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} for possible values. 432 @type sColorSunset: string 433 @param sColorSunset: Color of sunset curve. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} for possible values. 434 @type sColorTotalTime: string 435 @param sColorTotalTime: Color of total time of day curve. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} for possible values. 436 437 """ 438 #### 439 # Sunrise 440 if nIndiceStartSunrise == 0: 441 r.lines(rX_axis, npSunrise, type='l', col=sColorSunrise, lwd=2, lty=sLty) 442 elif nIndiceStartSunrise < nIndiceEndSunrise: # Northern hemisphere 443 rX_axis1 = r.strptime(lDateISO8601[0:nIndiceStartSunrise], "%Y-%m-%d") 444 rX_axis2 = r.strptime(lDateISO8601[nIndiceStartSunrise:nIndiceEndSunrise], \ 445 "%Y-%m-%d") 446 rX_axis3 = r.strptime(lDateISO8601[nIndiceEndSunrise:], "%Y-%m-%d") 447 r.lines(rX_axis1, npSunrise[0:nIndiceStartSunrise], \ 448 type='l', col=sColorSunrise, lwd=2, lty=sLty) 449 r.lines(rX_axis2, npSunrise[nIndiceStartSunrise:nIndiceEndSunrise], type='l',\ 450 col=sColorSunrise, lwd=2, lty='dashed') 451 r.lines(rX_axis3, npSunrise[nIndiceEndSunrise:], type='l', col=sColorSunrise, lwd=2, lty=sLty) 452 else : # Southern hemisphere 453 rX_axis1 = r.strptime(lDateISO8601[0:nIndiceEndSunrise], "%Y-%m-%d") 454 rX_axis2 = r.strptime(lDateISO8601[nIndiceEndSunrise:nIndiceStartSunrise], \ 455 "%Y-%m-%d") 456 rX_axis3 = r.strptime(lDateISO8601[nIndiceStartSunrise:], "%Y-%m-%d") 457 r.lines(rX_axis1, npSunrise[0:nIndiceEndSunrise], \ 458 type='l', col=sColorSunrise, lwd=2, lty='dashed') 459 r.lines(rX_axis2, npSunrise[nIndiceEndSunrise:nIndiceStartSunrise], type='l',\ 460 col=sColorSunrise, lwd=2, lty=sLty) 461 r.lines(rX_axis3, npSunrise[nIndiceStartSunrise:], type='l', \ 462 col=sColorSunrise, lwd=2, lty='dashed') 463 # Sunset 464 if nIndiceStartSunset == 0: 465 r.lines(rX_axis, npSunset, type='l', col=sColorSunset, lwd=2, lty=sLty) 466 elif nIndiceStartSunset < nIndiceEndSunset: # Northern hemisphere 467 rX_axis1 = r.strptime(lDateISO8601[0:nIndiceStartSunset], "%Y-%m-%d") 468 rX_axis2 = r.strptime(lDateISO8601[nIndiceStartSunset:nIndiceEndSunset], \ 469 "%Y-%m-%d") 470 rX_axis3 = r.strptime(lDateISO8601[nIndiceEndSunset:], "%Y-%m-%d") 471 r.lines(rX_axis1, npSunset[0:nIndiceStartSunset], \ 472 type='l', col=sColorSunset, lwd=2, lty=sLty) 473 r.lines(rX_axis2, npSunset[nIndiceStartSunset:nIndiceEndSunset], type='l',\ 474 col=sColorSunset, lwd=2, lty='dashed') 475 r.lines(rX_axis3, npSunset[nIndiceEndSunset:], type='l', col=sColorSunset, lwd=2, lty=sLty) 476 else : # Southern hemisphere 477 rX_axis1 = r.strptime(lDateISO8601[0:nIndiceEndSunset], "%Y-%m-%d") 478 rX_axis2 = r.strptime(lDateISO8601[nIndiceEndSunset:nIndiceStartSunset], \ 479 "%Y-%m-%d") 480 rX_axis3 = r.strptime(lDateISO8601[nIndiceStartSunset:], "%Y-%m-%d") 481 r.lines(rX_axis1, npSunset[0:nIndiceEndSunset], \ 482 type='l', col=sColorSunset, lwd=2, lty='dashed') 483 r.lines(rX_axis2, npSunset[nIndiceEndSunset:nIndiceStartSunset], type='l',\ 484 col=sColorSunset, lwd=2, lty=sLty) 485 r.lines(rX_axis3, npSunset[nIndiceStartSunset:], type='l', \ 486 col=sColorSunset, lwd=2, lty='dashed') 487 488 r.lines(rX_axis, npSunTime, type='l', col=sColorTotalTime, lwd=2, lty=sLty)
489 490
491 -def plot_daylight_differences(lSunrise1, lSunset1, lDaylength1, lDateISO8601,\ 492 sFilename, tToday, \ 493 sBackgroundColor, \ 494 lSunrise2=None, lSunset2=None, lDaylength2=None):
495 """ 496 Plot the difference of daylight time between consecutive days. 497 498 @type lSunrise1: list 499 @param lSunrise1: List of sunrise values for one year for the first place. 500 @type lSunset1: list 501 @param lSunset1: List of sunset values for one year for the first place. 502 @type lDaylength1: list 503 @param lDaylength1: List of day length for each day of the year. 504 @type lDateISO8601: list 505 @param lDateISO8601: List of strings for one year in iso8601 format. 506 @type sFilename: string 507 @param sFilename: Filename to save the graph. Filename is transformed like 508 'file.png' to 'file_delta_t.png'. 509 @type tToday: tuple 510 @param tToday: Tuple as returned by the function time.gmtime. 511 @type sBackgroundColor: string 512 @param sBackgroundColor: Color that will be used for the background 513 color for the generated graphics. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} 514 @type lSunrise2: list 515 @param lSunrise2: List of sunrise values for one year for the second place. 516 @type lSunset2: list 517 @param lSunset2: List of sunset values for one year for the second place. 518 @type lDaylength2 list 519 @param lDaylength2: List of day length for each day of the year for the 520 second place. 521 """ 522 init_time_values(lDateISO8601) 523 524 # Use the current julian day to get sunrise/sunset for today 525 fTodaySunriseTime = lSunrise1[tToday[7]-1] 526 fTodaySunsetTime = lSunset1[tToday[7]-1] 527 528 sFilenameTimeDifference = crepyscule_tools.\ 529 remove_extension(sFilename) +\ 530 '_delta_t.png' 531 532 sTitle = _("Daily variation of daylight") 533 534 r.library("GDD") 535 r.GDD(sFilenameTimeDifference, type='png', w = nPngWidth, \ 536 h = nPngHeight, bg=sBackgroundColor, ps=8) 537 538 lDiffSunTime = crepyscule_tools.get_daylight_variation(lDaylength1) 539 lDiffSunTime2 = [] 540 if lSunrise2 != None and lSunset2 != None: 541 lDiffSunTime2 = crepyscule_tools.get_daylight_variation(lDaylength2) 542 543 # Labeling on Y axis 544 nYMax = int(round(max(lDiffSunTime+lDiffSunTime2)+0.5)) 545 nYMin = int(round(min(lDiffSunTime+lDiffSunTime2)-0.5)) 546 npbsMax = max(nYMax, abs(nYMin)) 547 # Zero must be have a tick 548 lYAxisDivisionUp = numpy.arange(0, npbsMax+(nYMax-nYMin)/10.0,\ 549 (nYMax-nYMin)/10.0).tolist() 550 lYAxisDivisionDown = numpy.arange(0, -npbsMax-(nYMax-nYMin)/10.0, \ 551 -(nYMax-nYMin)/10.0).tolist() 552 # Remove the 0 from one of the 2 arrays 553 lYAxisDivisionDown.pop(0) 554 # use a list to append the numpy 555 npYAxisDivision = numpy.array(lYAxisDivisionDown + \ 556 lYAxisDivisionUp) 557 558 r.par(mar=r.c(5,7,4,2)) # Put more space at the left of Y axis 559 r.par(las=1) 560 r.plot(rX_axis, lDiffSunTime, ylim=[nYMin, nYMax], xaxs='i', \ 561 lty=0, type='l',\ 562 xlab='Date', ylab='', main=sTitle, xaxt='n', yaxt='n') 563 564 # Y label 565 sYLabel = _("Daily variation (minute)") 566 r.par(las=0) # Put text vertical 567 r.mtext(sYLabel, side=2, line=6) 568 r.par(las=1) 569 570 lUsr = r.par("usr") 571 572 ## Axis 573 r.axis(2, npYAxisDivision, labels=numpy.around(npYAxisDivision,2)) # Y 574 r.axis(1, at=rlMonth, labels=lMonthString) 575 ### Grid 576 rXdomain = r.c(lUsr[0], lUsr[1]) 577 for i in npYAxisDivision: 578 rYdomain = r.c(i,i) 579 r.lines(rXdomain, rYdomain, col='gray70') # Horizontal lines 580 rYdomain = r.c(lUsr[2], lUsr[3]) 581 for rnMonth in rlMonth: 582 rXdomain = r.c(rnMonth, rnMonth) 583 r.lines(rXdomain, rYdomain, col='gray70') # Vertical lines 584 r.lines( r.c(rlMonth[0], rlMonth[0]), rYdomain, col='black') 585 r.lines(rX_axis, lDiffSunTime, type='l', col=sFirstCityColor, lwd=1) 586 # Draw the line for the second city... 587 if lSunrise2 != None and lSunset2 != None: 588 r.lines(rX_axis, lDiffSunTime2, type='l', col=sSecondCityColor, lwd=1) 589 else: # Or the difference for today 590 fDiffToday = lDiffSunTime[tToday[7]-1] 591 fDiffTodayMinutes = round(fDiffToday,2) 592 __draw_today(tToday, fDiffToday, fDiffTodayMinutes, 0) 593 594 r.dev_off() 595 print "filename", sFilenameTimeDifference
596 597
598 -def plot_max_solar_flux(lDateISO8601, sFilename, tToday, sBackgroundColor, \ 599 fLat1, fLat2=None):
600 """ 601 Plot the maximal solar flux in W/m^2 for all year. 602 603 @type lDateISO8601: list 604 @param lDateISO8601: List of strings for one year in iso8601 format. 605 @type sFilename: string 606 @param sFilename: Filename to save the graph. Filename is transformed like 607 'file.png' to 'file_sf.png'. 608 """ 609 init_time_values(lDateISO8601) 610 611 # GDD and filename stuff 612 sFilenameSolarFlux = crepyscule_tools.\ 613 remove_extension(sFilename) +\ 614 '_sf.png' 615 sTitle = _("Daily maximal solar flux in Watt/m") + "²" 616 r.library("GDD") 617 r.GDD(sFilenameSolarFlux, type='png', w = nPngWidth, \ 618 h = nPngHeight, bg=sBackgroundColor, ps=8) 619 620 621 # Get the solar flux for all the year for the first latitude 622 nYear = int(lDateISO8601[0][0:4]) 623 lFlux1 = crepyscule_tools.get_one_year_max_sf(nYear, fLat1) 624 lFlux2 = [0] # Initialization to a value to avoid an error for nYMax 625 if fLat2 != None: # Draw the other line 626 lFlux2 = crepyscule_tools.get_one_year_max_sf(nYear, fLat2) 627 628 # Labeling on Y axis 629 sYLabel = _("Solar flux (Watt/m") + "²)" 630 nYMax = int(max(max(lFlux1),max(lFlux2))) 631 632 # Try 10 horizontal lines 633 if nYMax > 500: 634 nVerticalIncrement = 100 635 else: 636 nVerticalIncrement = 50 637 638 # Plot the fluxes 639 r.par(las=1) 640 r.plot(rX_axis, lFlux1, ylim=[0, nYMax], xaxs='i', yaxs='r',\ 641 lty=0, type='l',\ 642 xlab='Date', ylab=sYLabel, main=sTitle, xaxt='n', yaxt='n') 643 lUsr = r.par("usr") 644 r.axis(1, at=rlMonth, labels=lMonthString) 645 r.axis(2, at=range(0, nYMax, nVerticalIncrement)) 646 ### Grid 647 rXdomain = r.c(lUsr[0], lUsr[1]) 648 for i in range(0, nYMax, nVerticalIncrement): 649 rYdomain = r.c(i,i) 650 r.lines(rXdomain, rYdomain, col='gray70') # Horizontal lines 651 rYdomain = r.c(lUsr[2], lUsr[3]) 652 for rnMonth in rlMonth: 653 rXdomain = r.c(rnMonth, rnMonth) 654 r.lines(rXdomain, rYdomain, col='gray70') # Vertical lines 655 r.lines( r.c(rlMonth[0], rlMonth[0]), rYdomain, col='black') 656 657 r.lines(rX_axis, lFlux1, col='red') 658 if fLat2 != None: 659 r.lines(rX_axis, lFlux2, col='orange') 660 else: # Draw the value for today 661 fTodayValue = lFlux1[tToday[7]-1] 662 sLabel = str(int(round(fTodayValue))) 663 npFlux1 = numpy.array(lFlux1) 664 fMiddleOfGraph = npFlux1.mean() 665 __draw_today(tToday, fTodayValue, sLabel, fMiddleOfGraph) 666 667 r.dev_off() 668 669 print 'filename', sFilenameSolarFlux
670 671
672 -def plot_twilight_length(sFilename, tToday, sBackgroundColor, \ 673 fLat1, dTwilightLength1, fLat2=None, \ 674 dTwilightLength2=None):
675 """ 676 Plot the twilight length in minutes for all year. 677 678 @type sFilename: string 679 @param sFilename: Filename to save the graph. Filename is transformed like 680 'file.png' to 'file_ss.png'. 681 @type tToday: tuple 682 @param tToday: Tuple as returned by the function time.gmtime. 683 @type sBackgroundColor: string 684 @param sBackgroundColor: Color that will be used for the background 685 color for the generated graphics. See U{Chart of R colors<http://research.stowers-institute.org/efg/R/Color/Chart/>} 686 @type fLat1: float 687 @param fLat1: Latitude in decimal for the first place. 688 @type dTwilightLength1: dictionnary 689 @param dTwilightLength1: dictionnary containing the date in ISO 8601 format and 690 sunset speed for this first place. 691 @type fLat2: float 692 @param fLat2: Latitude in decimal for the second place. 693 @type dTwilightLength2: dictionnary 694 @param dTwilightLength2: dictionnary containing the date in ISO 8601 format and 695 sunset speed for this second place. 696 697 698 """ 699 lDateISO8601 = dTwilightLength1.keys() 700 lDateISO8601.sort() 701 702 # Put everything in order 703 lLength1 = [] 704 for sDay in lDateISO8601: 705 lLength1.append(dTwilightLength1[sDay]) 706 if dTwilightLength2 is not None: 707 lLength2 = [] 708 for sDay in lDateISO8601: 709 lLength2.append(dTwilightLength2[sDay]) 710 else: 711 lLength2 = [0] 712 713 init_time_values(lDateISO8601) 714 715 # GDD and filename stuff 716 sFilenameTwilightLength = crepyscule_tools.\ 717 remove_extension(sFilename) +\ 718 '_tl.png' 719 sTitle = _("Twilight length") 720 r.library("GDD") 721 r.GDD(sFilenameTwilightLength, type='png', w = nPngWidth, \ 722 h = nPngHeight, bg=sBackgroundColor, ps=8) 723 724 725 # Get the sunset length for all the year for the first latitude 726 nYear = int(lDateISO8601[0][0:4]) 727 728 # Labeling on Y axis 729 sYLabel = _("Twilight length (minute)") 730 fYMax = max(max(lLength1),max(lLength2)) 731 732 # Horizontal lines 733 nVerticalIncrement = fYMax/10 734 if fYMax > 50: 735 nVerticalIncrement = 10 736 else: 737 nVerticalIncrement = 5 738 739 # Plot the fluxes 740 r.par(las=1) 741 r.plot(rX_axis, lLength1, ylim=[0, fYMax], xaxs='i', yaxs='r',\ 742 lty=0, type='l',\ 743 xlab='Date', ylab=sYLabel, main=sTitle, xaxt='n', yaxt='n') 744 lUsr = r.par("usr") 745 r.axis(1, at=rlMonth, labels=lMonthString) 746 r.axis(2, at=numpy.arange(0, fYMax, nVerticalIncrement)) 747 ### Grid 748 rXdomain = r.c(lUsr[0], lUsr[1]) 749 for i in numpy.arange(0, fYMax, nVerticalIncrement): 750 rYdomain = r.c(i,i) 751 r.lines(rXdomain, rYdomain, col='gray70') # Horizontal lines 752 rYdomain = r.c(lUsr[2], lUsr[3]) 753 for rnMonth in rlMonth: 754 rXdomain = r.c(rnMonth, rnMonth) 755 r.lines(rXdomain, rYdomain, col='gray70') # Vertical lines 756 r.lines( r.c(rlMonth[0], rlMonth[0]), rYdomain, col='black') 757 758 r.lines(rX_axis, lLength1, col='red') 759 if fLat2 != None: 760 r.lines(rX_axis, lLength2, col='orange') 761 else: # Draw the value for today 762 fTodayValue = lLength1[tToday[7]-1] 763 sLabel = str(round(fTodayValue,2)) 764 npLength1 = numpy.array(lLength1) 765 fMiddleOfGraph = npLength1.mean() 766 __draw_today(tToday, fTodayValue, sLabel, fMiddleOfGraph) 767 768 r.dev_off() 769 770 print 'filename', sFilenameTwilightLength
771