| Home | Trees | Indices | Help |
|
|---|
|
|
1 """This module is for producing standardized plots for:
2
3 - publications: functions starting with pub_
4
5 - presentations: functions starting with pres_
6
7 - internet: functions starting with net_
8
9 - tools functions: starting with tool_
10
11 Generally a function sets the P.rcParams to values suitable for the printing.
12 - this is probably not the most clever way of doing things, should
13 be done through the API
14
15 Some features cannot be done with P.rcParams and can be done with
16 seprarate functions.
17
18 For a description of the sizing of plot and fonts see
19 http://www.scipy.org/Cookbook/Matplotlib/LaTeX_Examples
20
21 Short help about Date ticking
22 =============================
23 To set tick locations use::
24 ax.xaxis.set_major_locator(plt.DayLocator())
25 Possible date locators are::
26 MinuteLocator: locate minutes
27 HourLocator: locate hours
28 DayLocator: locate specifed days of the month
29 WeekdayLocator: Locate days of the week, eg MO, TU
30 MonthLocator: locate months, eg 7 for july
31 YearLocator: locate years that are multiples of base
32 RRuleLocator: locate using a matplotlib.dates.rrulewrapper. The rrulewrapper is a simple wrapper around a dateutils.rrule (dateutil) which allow almost arbitrary date tick specifications. See rrule example.
33 AutoDateLocator: On autoscale, this class picks the best MultipleDateLocator to set the view limits and the tick locations.
34
35 More is found here: U{http://matplotlib.sourceforge.net/api/dates_api.html}.
36 Other non-date locators see: U{http://matplotlib.sourceforge.net/api/ticker_api.html}
37
38 And the formatting is done with::
39 ax.xaxis.set_major_formatter(plt.DateFormatter('%d'))
40 where format string is::
41 %a Locale's abbreviated weekday name.
42 %A Locale's full weekday name.
43 %b Locale's abbreviated month name.
44 %B Locale's full month name.
45 %c Locale's appropriate date and time representation.
46 %d Day of the month as a decimal number [01,31].
47 %H Hour (24-hour clock) as a decimal number [00,23].
48 %I Hour (12-hour clock) as a decimal number [01,12].
49 %j Day of the year as a decimal number [001,366].
50 %m Month as a decimal number [01,12].
51 %M Minute as a decimal number [00,59].
52 %p Locale's equivalent of either AM or PM. (1)
53 %S Second as a decimal number [00,61]. (2)
54 %U Week number of the year (Sunday as the first day of the week)
55 as a decimal number [00,53]. All days in a new year preceding
56 the first Sunday are considered to be in week 0. (3)
57 %w Weekday as a decimal number [0(Sunday),6].
58 %W Week number of the year (Monday as the first day of the week)
59 as a decimal number [00,53]. All days in a new year preceding
60 the first Monday are considered to be in week 0. (3)
61 %x Locale's appropriate date representation.
62 %X Locale's appropriate time representation.
63 %y Year without century as a decimal number [00,99].
64 %Y Year with century as a decimal number.
65 %Z Time zone characters if no time zone exists).
66 %% A literal "%" character.
67 """
68
69 import numpy as np
70 import string
71 import copy
72
73 # from matplotlib import rc
74 # rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
75 # #rc('font',**{'family':'serif','serif':['Palatino', 'Computer Modern Roman']})
76 # rc('text', usetex=True)
77
78 import matplotlib.widgets
79 import matplotlib.font_manager
80
81 import pylab as plt
82
83
84 #: in inches: 1 inch = 72.27pt (matplotlib works in inches)
85 pt_per_inch = 72.27
86
87 #: ditto
88 golden_mean = (np.sqrt(5)-1.0)/2.0 # Aesthetic ratio
89
90 #: for dashed lines
91 dashes = ['--', # : dashed line
92 '-', # : solid line
93 '-.', # : dash-dot line
94 ':'] # : dotted line
95
96
98 """This function is used to set the rcParams for publications in the
99 Journal of Glaciology.
100
101 It returns some useful constans:
102 @return: column_width, column_height, two_column_width, dashes
103 """
104 # some dimensions in latex points:
105 column_width_pt = 244.6937 #/showthe/columnwidth
106 column_width = column_width_pt/pt_per_inch
107 text_height_pt = 724.5 #/showthe/textheight
108 column_height = text_height_pt/pt_per_inch
109 text_width_pt = 506.45905 #/showthe/textwidth
110 two_column_width = text_width_pt/pt_per_inch
111
112
113 fig_size_one = [column_width,column_width*golden_mean]
114 fig_size_two = [two_column_width,two_column_width*golden_mean]
115 fig_size_full_hight_one = [column_width,column_height]
116 fig_size_full_hight_two = [two_column_width,column_height]
117
118 # figure out what font sizes you want and other parameters which are
119 # the same for all size plots:
120 font_big = 10
121 font_norm = 9
122 font_small = 7
123 line_thin = 0.1
124 line_medium = 0.3
125 line_norm = 0.5
126 params = {'backend': 'eps',
127 'font.size': font_norm,
128 'axes.labelsize': font_norm,
129 'text.fontsize': font_norm,
130 'legend.fontsize': font_norm,
131 'legend.linewidth': line_thin,
132 'xtick.labelsize': font_small,
133 'ytick.labelsize': font_small,
134 'lines.linewidth': line_norm,
135 'lines.color': 'k',
136 'grid.linewidth': line_thin,
137 'axes.linewidth': line_medium,
138 'font.family': 'sans-serif',
139 'font.serif': ['Times New Roman', 'Palatino', 'New Century Schoolbook', 'Bookman', 'Computer Modern Roman'],
140 'font.sans-serif': ['Arial', 'FreeSans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif'], #'Free Sans, Arial, Computer Modern Sans serif', #Optima, Helvetica, Avant Garde, Computer Modern Sans serif',
141 'font.monospace': ['Courier', 'Computer Modern Typewriter', 'Bitstream Vera Sans Mono'],
142 'figure.dpi': 300,
143 'savefig.dpi': 100,
144 'xtick.major.size': 3,
145 'xtick.minor.size': 1.5,
146 'ytick.major.size': 3,
147 'ytick.minor.size': 1.5,
148 'axes.titlesize': font_norm
149 }
150
151 plt.rcParams.update(params)
152 # use plt.rcdefaults() to restore defaults if needed
153
154 # # parameters which differ for different grapics
155 # param_one = {'figure.figsize': fig_size_one}
156 # param_two = {'figure.figsize': fig_size_two}
157 # param_full_hight_one = {'figure.figsize': fig_size_full_hight_one}
158 # param_full_hight_two = {'figure.figsize': fig_size_full_hight_two}
159
160
161 return column_width, column_height, two_column_width
162
163
165 """This function is used to set the rcParams for latex-beamer
166 presentations.
167
168 It returns some useful constans:
169 @return: column_width, column_height, two_column_width, dashes
170 """
171 # some dimensions in latex points:
172 column_width_pt = 307.28987 #/showthe/columnwidth
173 column_width = column_width_pt/pt_per_inch
174 text_height_pt = 200.# 249.80135 #/showthe/textheight
175 column_height = text_height_pt/pt_per_inch
176 text_width_pt = 307.28987 #/showthe/textwidth
177 two_column_width = text_width_pt/pt_per_inch
178
179
180 fig_size_one = [column_width,column_width*golden_mean]
181 fig_size_two = [two_column_width,two_column_width*golden_mean]
182 fig_size_full_hight_one = [column_width,column_height]
183 fig_size_full_hight_two = [two_column_width,column_height]
184
185 # figure out what font sizes you want and other parameters which are
186 # the same for all size plots:
187 font_big = 12
188 font_norm = 7
189 font_small = 6
190 line_thin = 1
191 line_norm = 2
192 params = {'backend': 'png',
193 'font.size': font_norm,
194 'axes.labelsize': font_norm,
195 'text.fontsize': font_norm,
196 'legend.fontsize': font_norm,
197 'legend.linewidth': line_thin,
198 'xtick.labelsize': font_norm,
199 'ytick.labelsize': font_norm,
200 'lines.linewidth': line_norm,
201 'grid.linewidth': line_thin,
202 'axes.linewidth': line_thin,
203 'font.family': 'sans-serif',
204 'font.serif': ['Times New Roman',' Palatino',' New Century Schoolbook',' Bookman',' Computer Modern Roman'],
205 'font.sans-serif': ['Arial', 'FreeSans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif'], #'Free Sans, Arial, Computer Modern Sans serif', #Optima, Helvetica, Avant Garde, Computer Modern Sans serif',
206 'font.cursive': ['Zapf Chancery'],
207 'font.monospace': ['Courier',' Computer Modern Typewriter'],
208 'figure.dpi': 300,
209 'xtick.major.size': 3,
210 'xtick.minor.size': 1,
211 'ytick.major.size': 3,
212 'ytick.minor.size': 1,
213 'savefig.dpi': 300,
214 'axes.titlesize': font_norm
215 }
216
217 # 'text.usetex': True }
218 plt.rcParams.update(params)
219 # use plt.rcdefaults() to restore defaults if needed
220
221 # # parameters which differ for different grapics
222 # param_one = {'figure.figsize': fig_size_one}
223 # param_two = {'figure.figsize': fig_size_two}
224 # param_full_hight_one = {'figure.figsize': fig_size_full_hight_one}
225 # param_full_hight_two = {'figure.figsize': fig_size_full_hight_two}
226
227 # now do some front checking
228 fp = matplotlib.font_manager.FontProperties()
229 print fp.get_family(), '\n', matplotlib.font_manager.fontManager.findfont(fp)
230
231 return column_width, column_height, two_column_width
232
233
234
235 # ----------------------------------------
236 # helper functions
237
239 """This function finishes up a plot:
240 - adjust the linewidth of the minor ticks
241 - adjust the subplots if subplot_adjust is passed
242 - it *save* it to the filename. File type is determined by the
243 extension.
244
245 It sets the ticks to the width of the axes border
246 """
247 linewidth = plt.rcParams['axes.linewidth']
248 if fig is None:
249 fig = plt.gcf()
250 axs = fig.axes
251 if subplot_adjust is None:
252 subplot_adjust = {'left': 0.13,
253 'right': 0.95,
254 'bottom': 0.1,
255 'top': 0.95,
256 'wspace': None,
257 'hspace': None}
258 fig.subplots_adjust(**subplot_adjust)
259 for ax in axs:
260 # there is no get_xticklines methode for the minor ticks (in
261 # current matplotlib), so we need to get the list of lines
262 # ourselves:
263 xminortick_lines=[]
264 for minor_ticks in ax.xaxis.minorTicks:
265 xminortick_lines.append(minor_ticks.tick1line)
266 xminortick_lines.append(minor_ticks.tick2line)
267 yminortick_lines=[]
268 for minor_ticks in ax.yaxis.minorTicks:
269 yminortick_lines.append(minor_ticks.tick1line)
270 yminortick_lines.append(minor_ticks.tick2line)
271 plt.setp(ax.get_xticklines() + ax.get_yticklines() +
272 xminortick_lines + yminortick_lines, mew=linewidth)
273
274 plt.savefig(filename)
275
277 """Removes the legend from the passed list of axes. If no
278 arguments are passed, then plt.gcf().axes is used.
279 """
280
281 if ax is None:
282 ax = plt.gcf().axes
283 # this removes the border around the legend labels:
284 # setp(legendframe, linewidth=0.0) might also be an option
285
286 for a in ax:
287 leg = a.axes.get_legend()
288 leg.draw_frame(False)
289
291 """Makes touching subplots and removes the xlabels in all but the
292 lowermost subplot.
293
294 @param fig: the figure containing the subplots. defaults to current
295 figure.
296 @param top_ticklabels: if true also do ticklabels at the top
297 """
298 if fig is None:
299 fig = plt.gcf()
300 axs = copy.copy(fig.axes[:-1])
301 if top_ticklabels:
302 axs[0].xaxis.tick_top()
303 axs = axs[1:]
304 fig.subplots_adjust(hspace=0)
305 for a in axs:
306 lab = a.get_xmajorticklabels()
307 lab.append(a.get_xminorticklabels())
308 xlab = a.xaxis.get_label()
309 plt.setp(lab, visible=False)
310 plt.setp(xlab, visible=False)
311
313 """Rotates the xlabels of ax by rotation.
314 """
315 if ax is None:
316 ax = plt.gca()
317 labels = ax.get_xticklabels()
318 plt.setp(labels, rotation=rotation)
319 # plt.setp(labels, verticalalignment='center')
320
321
323 """This function returns the extent of the axes when the figure is
324 closed. Useful for figuring out the extent on date plots without
325 hassel.
326
327 @param plot_fn: a function which does some plotting. does not
328 contain a plt.show() the arguments to plot_fn can
329 be passed in the following *args and **kwargs
330 """
331 plot_fn(*args, **kwargs)
332 xlims = []
333 ylims = []
334 def resize(event):
335 xlims = []
336 ylims = []
337 for a in plt.gcf().axes:
338 xlims.append(a.get_xlim())
339 ylims.append(a.get_ylim())
340 print xlims, ylims
341 resize(None)
342 plt.connect('draw_event', resize)
343 plt.show()
344 return xlims, ylims
345
347 """Returns the x&y coords from where you clicked. Does not respond
348 when zooming.
349
350 @param plot_fn: a function which does some plotting. does not
351 contain a plt.show() the arguments to plot_fn can
352 be passed in the following *args and **kwargs
353 @param ax: if not not current axes ought to be used. Pass the number of
354 the subplot.
355 """
356 plot_fn(*args, **kwargs)
357 xcoord = []
358 ycoord = []
359 if ax is not None:
360 plt.axes(plt.gcf().axes[ax])
361 def click(event):
362 # this is a trick to let you zoom and pan:
363 tb = plt.get_current_fig_manager().toolbar
364 # normal event inside axis. return coordinates.
365 if event.button==1 and event.inaxes and tb.mode == '':
366 print 'x,y = ', event.xdata, event.ydata
367 xcoord.append(event.xdata)
368 ycoord.append(event.ydata)
369 # otherwise it jumps about:
370 plt.gca().set_autoscale_on(False)
371 #register this function with the event handler
372 plt.connect('button_press_event', click)
373 # make different cursor
374 curs = matplotlib.widgets.Cursor(plt.gca(), color='black', useblit=True)
375 plt.show()
376 return xcoord, ycoord
377
379 """Underlays the axis in the list axs with a color rectangel.
380
381 @param x_loc: (x_min, x_max) the borders of the rectangel
382 @param color: 'g' the color
383 @param axs: [axes] default [plt.gcf().axes]
384 @param alpha: how solid the color is
385
386 @note: on twinx() plots the lines of the first plot will be covered. use
387 axs=axs[0:-1:2] when axs is the list of axes.
388 """
389 if axs is None:
390 axs = plt.gcf().axes
391 for ax in axs:
392 plt.axes(ax)
393 ylim = ax.get_ylim()
394 xlim = ax.get_xlim()
395 x_vertices = [x_loc[0], x_loc[1], x_loc[1], x_loc[0]]
396 y_vertices = [ylim[0], ylim[0], ylim[1], ylim[1]]
397 plt.fill(x_vertices, y_vertices, facecolor=color, edgecolor=color,
398 hold=True)
399 #to preserve the limits:
400 ax.set_xlim(xlim)
401 ax.set_ylim(ylim)
402
404 """Makes vertical lines at x_loc.
405
406 @param x_loc: (x_min, x_max) the borders of the rectangel
407 @param axs: [axes] default [plt.gcf().axes]
408 @param fmt: line style
409
410 @note: on twinx() plots the lines of the first plot will be covered. use
411 axs=axs[0:-1:2] when axs is the list of axes.
412 """
413 if axs is None:
414 axs = plt.gcf().axes
415 for ax in axs:
416 plt.axes(ax)
417 ylim = ax.get_ylim()
418 xlim = ax.get_xlim()
419 y_vertices = np.array([ylim[0], ylim[1]])
420 for x in x_loc:
421 x_vertices = np.array([x ,x])
422 plt.plot(x_vertices, y_vertices, fmt, hold=True)
423 #to preserve the limits:
424 ax.set_xlim(xlim)
425 ax.set_ylim(ylim)
426
428 """Adjust the ylabels such that they align when there are several
429 subplots. Only works when the x-Axis are linked.
430
431 Note: it seems that all labels need to be either ascii or
432 unicode. a mix leads to misalignment.
433
434 @param pos_factor: controls the horizontal postion. default 1 means
435 same place as outermost label. < 1 more left, > 1
436 more right
437 @param axs: a list of axes. default plt.gcf().axes
438 """
439 # we need to save it in order that the values are right
440 plt.savefig('/tmp/tmp_fig.eps')
441 if axs is None:
442 axs = plt.gcf().axes
443 axs_left = [ ax for ax in axs if ax.yaxis.label_position=='left']
444 axs_right = [ ax for ax in axs if ax.yaxis.label_position=='right']
445 labels_left = [ ax.yaxis.get_label() for ax in axs_left]
446 labels_right = [ ax.yaxis.get_label() for ax in axs_right]
447 xlims = axs[0].get_xlim()
448 loop_over = [x for x in [(axs_right, labels_right),(axs_left, labels_left)] if x!=([],[])]
449 for axs, labels in loop_over:
450 # get largest x-postion in identity coordates
451 # use ax.transAxes.inverse_xy_tup() to go to axes coord
452 x_pos = [ lab.get_position()[0] for lab in labels]
453 x_position = min(x_pos) * pos_factor
454 y_position= [ lab.get_position()[1] for lab in labels]
455 text = [ lab.get_text() for lab in labels]
456 fontsize = [ lab.get_fontsize() for lab in labels]
457 fontproperties = [ lab.get_font_properties() for lab in labels]
458 for n,ax in enumerate(axs):
459 # make the original ones disappear
460 plt.setp(labels[n], visible=False)
461 pos = ax.transAxes.inverted().transform((x_position,y_position[n]))
462 # and set new ones. for some strange reason i need only to
463 # take the x_pos transformed and not the y_pos??!
464 t = ax.text(pos[0], y_position[n], text[n], transform=ax.transAxes, rotation=90,
465 va='center', ha='center', fontsize=fontsize[n])
466 #t.set_fontproperties = fontproperties[n]
467 #, ha='center') this seem to have something to do with wonkey text alignement
468 #print t.get_horizontalalignment()
469 # print 'Text font: ' + t.get_fontname()
470 # print 'Text size: ' + str(t.get_fontsize())
471 # print 'Xlabel font: ' + plt.gca().xaxis.get_label().get_fontname()
472 # print 'Xlabel size: ' + str(plt.gca().xaxis.get_label().get_fontsize())
473 # print 'XTickLabel font: ' + plt.gca().get_xticklabels()[0].get_fontname()
474 # print 'XTickLabel size: ' + str(plt.gca().get_xticklabels()[0].get_fontsize())
475
476
477 -def tool_label_subplots(axs=None, system='abc', pos='out_right', check_axes=True, start_value=0,
478 fontsize=None):
479 """This function labels all the subplots in a figure. The labels are
480
481 @param axs: axes of the subplots to act on. the order of the list
482 determines the order of the labeling.
483 @param system: labeling system: default 'abc', 'ABC'
484 @param pos: default: outside on the right (out_right), in_top_right or (x,y) in
485 figure coordinates.
486 @param check_axes: if only one axes, then don't label. default:True
487 """
488
489 if axs is None:
490 axs = plt.gcf().axes
491 if len(axs)==1:
492 return
493 if fontsize is None:
494 fontsize = 12 #plt.rcParams['text.fontsize']#axs[-1].xaxis.get_majorticklabels()[0].get_fontsize()
495 if system=='abc':
496 labels = string.ascii_lowercase[start_value:]
497 elif system=='ABC':
498 labels = string.ascii_uppercase[start_value:]
499 if pos=='out_right':
500 pos_v = (1.02, 0)
501 elif pos=='in_top_right':
502 pos_v = (0.96, 0.9)
503 elif pos=='in_bottom_left':
504 pos_v = (0.04, 0.1)
505 else:
506 pos_v = pos
507 for n, ax in enumerate(axs):
508 ax.text(pos_v[0], pos_v[1], labels[n], transform=ax.transAxes, fontsize=fontsize)
509
511 """Removes small contours with less than num_points.
512
513 @param cs: is a contour instance
514 @param num_points: min number of points
515 """
516 for i, col in enumerate(cs.collections):
517 segs = col._segments
518 col.set_segments([seg for seg in segs if len(seg) > num_points])
519
520
522 """Sets the extents and ticks according to the entires in the corresponding lists.
523
524 @param y_extents: a list of y-extent tuples
525
526 @type y_ticks: list of lists containing B{floats}
527 @param y_ticks: the location of the yticks given for each axes.
528
529 @param axs: a list of axis (default: all axis in current figure)
530
531 @param minor: not sure
532
533 @note:
534 - the y_ticks need to be floats!
535 - set minor=False if using plt.twiny
536 """
537 if axs is None:
538 axs = plt.gcf().axes
539 for n,ax in enumerate(axs):
540 if minor:
541 ax.yaxis.set_minor_locator(
542 plt.MultipleLocator(np.diff(y_ticks[n])[0]/2))
543 ax.set_yticks(y_ticks[n])
544 ax.set_ylim(y_extents[n])
545
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 18 11:49:14 2014 | http://epydoc.sourceforge.net |