@@ -216,7 +216,8 @@ def add_title(self, title, width=None, height=None, fontsize=11):
216
216
"""
217
217
pass
218
218
219
- def add_graph (self , data , title = None , template = None , width = None , height = None ):
219
+ def add_graph (self , data , title = None , template = None , width = None , height = None , min_y = None , max_y = None ,
220
+ xticks_spacing = None , customize_func = None , customize_kwargs = None ):
220
221
r"""
221
222
Add a graph item to the current sheet.
222
223
Note that the current method only add a new item to the list of items to be generated.
@@ -241,6 +242,18 @@ def add_graph(self, data, title=None, template=None, width=None, height=None):
241
242
height : int, optional
242
243
height of the title item. The current default value is used if None
243
244
(see :py:obj:`~ExcelReport.set_item_default_size`). Defaults to None.
245
+ min_y: int, optional
246
+ minimum value for the Y axis.
247
+ max_y: int, optional
248
+ maximum value for the Y axis.
249
+ xticks_spacing: int, optional
250
+ space interval between two ticks along the X axis.
251
+ customize_func: function, optional
252
+ user defined function to personalize the graph.
253
+ The function must take the Chart object as first argument.
254
+ All keyword arguments defined in customize_kwargs are passed to the function at call.
255
+ customize_kwargs: dict, optional
256
+ keywords arguments passed to the function `customize_func` at call.
244
257
245
258
Examples
246
259
--------
@@ -262,6 +275,14 @@ def add_graph(self, data, title=None, template=None, width=None, height=None):
262
275
>>> sheet_be.template = 'Line_Marker'
263
276
>>> sheet_be.add_graph(demo.deaths['Belgium'], 'Deaths')
264
277
278
+ Specify the mininum and maximum values for the Y axis
279
+
280
+ >>> sheet_be.add_graph(demo.population['Belgium'], 'Population (min/max Y axis = 5/6 millions)', min_y=5e6, max_y=6e6)
281
+
282
+ Specify the interval between two ticks (X axis)
283
+
284
+ >>> sheet_be.add_graph(demo.population['Belgium'], 'Population (every 2 years)', xticks_spacing=2)
285
+
265
286
Dumping the report Excel file
266
287
267
288
>>> # do not forget to call 'to_excel' to create the report file
@@ -270,7 +291,8 @@ def add_graph(self, data, title=None, template=None, width=None, height=None):
270
291
pass
271
292
272
293
def add_graphs (self , array_per_title , axis_per_loop_variable , template = None , width = None , height = None ,
273
- graphs_per_row = 1 ):
294
+ graphs_per_row = 1 , min_y = None , max_y = None , xticks_spacing = None , customize_func = None ,
295
+ customize_kwargs = None ):
274
296
r"""
275
297
Add multiple graph items to the current sheet. This method is mainly useful when multiple
276
298
graphs are generated by iterating over one or several axes of an array (see examples below).
@@ -295,7 +317,18 @@ def add_graphs(self, array_per_title, axis_per_loop_variable, template=None, wid
295
317
(see :py:obj:`~ExcelReport.set_item_default_size`). Defaults to None.
296
318
graphs_per_row: int, optional
297
319
Number of graphs per row. Defaults to 1.
298
-
320
+ min_y: int, optional
321
+ minimum value for the Y axis.
322
+ max_y: int, optional
323
+ maximum value for the Y axis.
324
+ xticks_spacing: int, optiona
9E88
l
325
+ space interval between two ticks along the X axis.
326
+ customize_func: function, optional
327
+ user defined function to personalize the graph.
328
+ The function must take the Chart object as first argument.
329
+ All keyword arguments defined in customize_kwargs are passed to the function at call.
330
+ customize_kwargs: dict, optional
331
+ keywords arguments passed to the function `customize_func` at call.
299
332
300
333
Examples
301
334
--------
@@ -311,6 +344,18 @@ def add_graphs(self, array_per_title, axis_per_loop_variable, template=None, wid
311
344
... {'gender': population.gender, 'year': population.time},
312
345
... template='line', width=450, height=250, graphs_per_row=2)
313
346
347
+ Specify the mininum and maximum values for the Y axis
348
+
349
+ >>> sheet_population.add_graphs({'Population of {gender} by country for the year {year}': population},
350
+ ... {'gender': population.gender, 'year': population.time},
351
+ ... template='line', width=450, height=250, graphs_per_row=2, min_y=0, max_y=50e6)
352
+
353
+ Specify the interval between two ticks (X axis)
354
+
355
+ >>> sheet_population.add_graphs({'Population of {gender} by country for the year {year}': population},
356
+ ... {'gender': population.gender, 'year': population.time},
357
+ ... template='line', width=450, height=250, graphs_per_row=2, xticks_spacing=2)
358
+
314
359
>>> # do not forget to call 'to_excel' to create the report file
315
360
>>> report.to_excel('Demography_Report.xlsx')
316
361
"""
@@ -499,7 +544,7 @@ def to_excel(self, filepath, data_sheet_name='__data__', overwrite=True):
499
544
500
545
501
546
if xw is not None :
502
- from xlwings .constants import LegendPosition , HAlign , VAlign , ChartType , RowCol
547
+ from xlwings .constants import LegendPosition , HAlign , VAlign , ChartType , RowCol , AxisType , Constants
503
548
from larray .inout .xw_excel import open_excel
504
549
505
550
class ItemSize (object ):
@@ -571,7 +616,8 @@ class ExcelGraphItem(ItemSize):
571
616
572
617
_default_size = ItemSize (427 , 230 )
573
618
574
- def __init__ (self , data , title , template , top , left , width , height ):
619
+ def __init__ (self , data , title , template , top , left , width , height , min_y , max_y ,
620
+ xticks_spacing , customize_func , customize_kwargs ):
575
621
ItemSize .__init__ (self , width , height )
576
622
self .top = top
577
623
self .left = left
@@ -583,6 +629,14 @@ def __init__(self, data, title, template, top, left, width, height):
583
629
if template is not None and not os .path .isfile (template ):
584
630
raise ValueError (f"Could not find template file { template } " )
585
631
self .template = template
632
+ self .min_y = min_y
633
+ self .max_y = max_y
634
+ self .xticks_spacing = xticks_spacing
635
+ if customize_func is not None and not callable (customize_func ):
636
+ raise TypeError (f"Expected a function for the argument 'customize_func'. "
637
+ f"Got object of type { type (customize_func ).__name__ } instead." )
638
+ self .customize_func = customize_func
639
+ self .customize_kwargs = customize_kwargs
586
640
587
641
def dump (self , sheet , data_sheet , row ):
588
642
data_range = data_sheet .Range
@@ -604,12 +658,28 @@ def dump(self, sheet, data_sheet, row):
604
658
source = data_range (data_cells (row , 1 ), data_cells (last_row , last_col ))
605
659
obj_chart .SetSourceData (source )
606
660
obj_chart .ChartType = ChartType .xlLine
661
+ # title
607
662
if self .title is not None :
608
663
obj_chart .HasTitle = True
609
664
obj_chart .ChartTitle .Caption = self .title
665
+ # legend
610
666
obj_chart .Legend .Position = LegendPosition .xlLegendPositionBottom
667
+ # template
611
668
if self .template is not None :
612
669
obj_chart .ApplyChartTemplate (self .template )
670
+ # min - max on Y axis
671
+ if self .min_y is not None :
672
+ obj_chart .Axes (AxisType .xlValue ).MinimumScale = self .min_y
673
+ if self .max_y is not None :
674
+ obj_chart .Axes (AxisType .xlValue ).MaximumScale = self .max_y
675
+ # xticks_spacing
676
+ if self .xticks_spacing is not None :
677
+ obj_chart .Axes (AxisType .xlCategory ).TickLabelSpacing = self .xticks_spacing
678
+ obj_chart .Axes (AxisType .xlCategory ).TickMarkSpacing = self .xticks_spacing
679
+ obj_chart .Axes (AxisType .xlCategory ).TickLabelPosition = Constants .xlLow
680
+ # user's function (to apply on remaining kwargs)
681
+ if self .customize_func is not None :
682
+ self .customize_func (obj_chart , ** self .customize_kwargs )
613
683
# flagflip
614
684
if nb_series > 1 and nb_xticks == 1 :
615
685
obj_chart .PlotBy = RowCol .xlRows
@@ -643,7 +713,8 @@ def add_title(self, title, width=None, height=None, fontsize=11):
643
713
self .items .append (ExcelTitleItem (title , fontsize , self .top , 0 , width , height ))
644
714
self .top += height
645
715
646
- def add_graph (self , data , title = None , template = None , width = None , height = None ):
716
+ def add_graph (self , data , title = None , template = None , width = None , height = None , min_y = None , max_y = None ,
717
+ xticks_spacing = None , customize_func = None , customize_kwargs = None ):
647
718
if width is None :
648
719
width = self .default_items_size ['graph' ].width
649
720
if height is None :
@@ -653,13 +724,15 @@ def add_graph(self, data, title=None, template=None, width=None, height=None):
653
724
template = self .template
654
725
if self .graphs_per_row is not None and self .position_in_row > self .graphs_per_row :
655
726
self .newline ()
656
- self .items .append (ExcelGraphItem (data , title , template , self .top , self .left , width , height ))
727
+ self .items .append (ExcelGraphItem (data , title , template , self .top , self .left , width , height ,
728
+ min_y , max_y , xticks_spacing , customize_func , customize_kwargs ))
657
729
self .left += width
658
730
self .curline_height = max (self .curline_height , height )
659
731
self .position_in_row += 1
660
732
661
733
def add_graphs (self , array_per_title , axis_per_loop_variable , template = None , width = None , height = None ,
662
- graphs_per_row = 1 ):
734
+ graphs_per_row = 1 , min_y = None , max_y = None , xticks_spacing = None , customize_func = None ,
735
+ customize_kwargs = None ):
663
736
loop_variable_names = axis_per_loop_variable .keys ()
664
737
axes = tuple (axis_per_loop_variable .values ())
665
738
titles = array_per_title .keys ()
@@ -673,7 +746,8 @@ def add_graphs(self, array_per_title, axis_per_loop_variable, template=None, wid
673
746
loop_variables_dict = dict (zip (loop_variable_names , loop_variable_values ))
674
747
for title_template , array_chunk in zip (titles , arrays_chunk ):
675
748
title = title_template .format (** loop_variables_dict )
676
- self .add_graph (array_chunk , title , template , width , height )
749
+ self .add_graph (array_chunk , title , template , width , height , min_y , max_y , xticks_spacing ,
750
+ customize_func , customize_kwargs )
677
751
if graphs_per_row is not None :
678
752
self .graphs_per_row = previous_graphs_per_row
679
753
0 commit comments