@@ -363,6 +363,16 @@ def _valid_plot_kwargs():
363
363
'Description' : 'Volume y-axis scale: "linear", "log", "symlog", or "logit"' ,
364
364
'Validator' : lambda value : _yscale_validator (value ) },
365
365
366
+ 'volume_ylim' : { 'Default' : None ,
367
+ 'Description' : 'Volume y-axis limits as tuple (min,max), i.e. (bottom,top)' ,
368
+ 'Validator' : lambda value : isinstance (value , (list ,tuple )) and len (value ) == 2
369
+ and all ([isinstance (v ,(int ,float )) for v in value ])},
370
+
371
+ 'volume_alpha' : { 'Default' : 1 , # alpha of Volume bars
372
+ 'Description' : 'opacity for Volume bar: 0.0 (transparent) to 1.0 (opaque)' ,
373
+ 'Validator' : lambda value : isinstance (value ,(int ,float )) or
374
+ all ([isinstance (v ,(int ,float )) for v in value ]) },
375
+
366
376
'warn_too_much_data' : { 'Default' : 599 ,
367
377
'Description' : 'Tolerance for data amount in plot. Default=599 rows.' +
368
378
' Values greater than \' warn_too_much_data\' will trigger a warning.' ,
@@ -452,13 +462,26 @@ def plot( data, **kwargs ):
452
462
raise ValueError ('Request for volume, but NO volume data.' )
453
463
454
464
if external_axes_mode :
455
- panels = None
465
+ panels = None
466
+ axA1 = config ['ax' ]
467
+ axA1 .set_axisbelow (config ['saxbelow' ])
456
468
if config ['volume' ]:
457
469
volumeAxes = config ['volume' ]
458
470
volumeAxes .set_axisbelow (config ['saxbelow' ])
459
471
else :
460
472
panels = _build_panels (fig , config )
461
- volumeAxes = panels .at [config ['volume_panel' ],'axes' ][0 ] if config ['volume' ] is True else None
473
+ axA1 = panels .at [config ['main_panel' ],'axes' ][0 ]
474
+ if config ['volume' ]:
475
+ if config ['volume_panel' ] == config ['main_panel' ]:
476
+ # ohlc and volume on same panel: move volume to secondary axes:
477
+ volumeAxes = panels .at [config ['volume_panel' ],'axes' ][1 ]
478
+ volumeAxes .set_zorder (axA1 .get_zorder ()- 0.1 ) # Make sure ohlc is above volume
479
+ axA1 .patch .set_visible (False ) # Let volume show through
480
+ panels .at [config ['main_panel' ],'used2nd' ] = True
481
+ else :
482
+ volumeAxes = panels .at [config ['volume_panel' ],'axes' ][0 ]
483
+ else :
484
+ volumeAxes = None
462
485
463
486
fmtstring = _determine_format_string (dates , config ['datetime_format' ])
464
487
@@ -471,20 +494,12 @@ def plot( data, **kwargs ):
471
494
formatter = IntegerIndexDateTimeFormatter (dates , fmtstring )
472
495
xdates = np .arange (len (dates ))
473
496
474
- if external_axes_mode :
475
- axA1 = config ['ax' ]
476
- axA1 .set_axisbelow (config ['saxbelow' ])
477
- else :
478
- axA1 = panels .at [config ['main_panel' ],'axes' ][0 ]
479
-
480
497
# Will have to handle widths config separately for PMOVE types ??
481
498
config ['_width_config' ] = _determine_width_config (xdates , config )
482
499
483
-
484
500
rwc = config ['return_width_config' ]
485
501
if isinstance (rwc ,dict ) and len (rwc )== 0 :
486
502
config ['return_width_config' ].update (config ['_width_config' ])
487
-
488
503
489
504
collections = None
490
505
if ptype == 'line' :
@@ -621,10 +636,15 @@ def plot( data, **kwargs ):
621
636
w = config ['_width_config' ]['volume_width' ]
622
637
lw = config ['_width_config' ]['volume_linewidth' ]
623
638
624
- adjc = _adjust_color_brightness (vcolors ,0.90 )
625
- volumeAxes .bar (xdates ,volumes ,width = w ,linewidth = lw ,color = vcolors ,ec = adjc )
626
- vymin = 0.3 * np .nanmin (volumes )
627
- vymax = 1.1 * np .nanmax (volumes )
639
+ adjc = _adjust_color_brightness (vcolors ,0.90 )
640
+ valp = config ['volume_alpha' ]
641
+ volumeAxes .bar (xdates ,volumes ,width = w ,linewidth = lw ,color = vcolors ,ec = adjc ,alpha = valp )
642
+ if config ['volume_ylim' ] is not None :
643
+ vymin = config ['volume_ylim' ][0 ]
644
+ vymax = config ['volume_ylim' ][1 ]
645
+ else :
646
+ vymin = 0.3 * np .nanmin (volumes )
647
+ vymax = 1.1 * np .nanmax (volumes )
628
648
volumeAxes .set_ylim (vymin ,vymax )
629
649
630
650
xrotation = config ['xrotation' ]
0 commit comments