Grid issue with CandlePlot

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Grid issue with CandlePlot

Kevin McClaning-2
Hello -- I've been wrestling with this problem for a couple of days and
could use some help. I started looking at the way CandlePlots are built
via the plot.candle_plot() call and by calling the CandlePlot method
directly. I'm having trouble making the grids of the plots behave
identically. Example code is:

import inspect, os
from traits.api import HasTraits
from traitsui.api import View, Item, HGroup
from chaco.api import Plot, CandlePlot, ArrayPlotData, ArrayDataSource
from enable.api import ComponentEditor

# defines
windowSize = (400,300)
windowTitle = os.path.split(__file__)[1]

class TraitedStockPlot( HasTraits ):
   '''display stock prices'''

   # one day of stock prices at 15 minute intervals
   openL = [
       51.84, 52.07, 52.02, 51.89, 51.93, 51.85, 51.80, 51.74, 51.89, 51.91,
       51.86, 51.80, 51.85, 51.70, 51.77, 51.78, 51.64, 51.58, 51.51, 51.44,
       51.48, 51.49, 51.61, 51.61, 51.54, 51.58, 51.63, ]
   highL = [
       52.10, 52.07, 52.05, 51.96, 51.96, 51.88, 51.85, 51.93, 51.90, 51.92,
       51.95, 51.88, 51.85, 51.79, 51.83, 51.80, 51.64, 51.58, 51.52, 51.48,
       51.49, 51.62, 51.63, 51.67, 51.62, 51.68, 51.63, ]
   lowL = [
       51.67, 51.99, 51.76, 51.88, 51.91, 51.74, 51.80, 51.74, 51.86, 51.86,
       51.86, 51.80, 51.75, 51.65, 51.75, 51.65, 51.58, 51.44, 51.40, 51.40,
       51.42, 51.49, 51.53, 51.53, 51.52, 51.57, 51.63, ]
   closeL = [
       52.09, 52.02, 51.87, 51.93, 51.92, 51.79, 51.84, 51.88, 51.90, 51.87,
       51.89, 51.84, 51.76, 51.77, 51.79, 51.65, 51.58, 51.50, 51.41, 51.48,
       51.48, 51.61, 51.61, 51.55, 51.62, 51.64, 51.63, ]
   volumeL = [
       114911, 182201, 192537, 133607, 12200, 34204, 10834, 70180, 9900,
24558,
       9338, 21117, 14133, 42636, 29177, 29482, 15328, 49200, 36120, 21055,
       23948, 73078, 62292, 72042, 90707, 129103, 111990, ]
   timeL = [
        930,  945, 1000, 1015, 1030, 1045, 1100, 1115, 1130, 1145, 1200,
       1215, 1230, 1245, 1300, 1315, 1330, 1345, 1400, 1415, 1430, 1445,
       1500, 1515, 1530, 1545, 1600, ]

   # calculate the average price for the intervals
   averageL = [
       (highL[ii] + lowL[ii] + openL[ii] + closeL[ii])/4
       for ii in range(len(openL)) ]

   ## generate plot via plot.candle_plot()

   myTAPD = ArrayPlotData()
   myTAPD.set_data( 'open',openL )
   myTAPD.set_data( 'low',lowL )
   myTAPD.set_data( 'high',highL )
   myTAPD.set_data( 'close',closeL )
   myTAPD.set_data( 'average',averageL )
   myTAPD.set_data( 'volume',volumeL )
   myTAPD.set_data( 'time',timeL )

   refTP = Plot( myTAPD )
   refPR = refTP.candle_plot(
       ("time", "low", "close", "average", "open", "high"),
       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,
   )

   # prettify the plot
   refTP.title = 'Stock Prices (Reference Plot)'
   refTP.x_axis.title = 'Time of Day (HHMM)'
   refTP.y_axis.title = 'OHLC'

   refTP.range2d.x_range.low = 900
   refTP.range2d.x_range.high = 1630
   refTP.range2d.y_range.low = 51.3
   refTP.range2d.y_range.high = 52.2

   ## generate plot via direct call to CandlePlot

   # generate the req'd ArrayDataSources
   openADS = ArrayDataSource( data = openL )
   highADS = ArrayDataSource(  data = highL )
   lowADS = ArrayDataSource( data = lowL )
   closeADS = ArrayDataSource( data = closeL )
   volumeADS = ArrayDataSource( data = volumeL )
   averageADS = ArrayDataSource( data = averageL )
   timeADS = ArrayDataSource( data = timeL, sort_order = 'ascending' )

   # generate the plot and set the data ranges
   testTP = Plot()
   testTP.value_range.add( highADS )
   testTP.value_range.add( lowADS )
   testTP.index_range.add( timeADS )

   # build the candle plot renderer, using the mapper from testTP
   testTCP = CandlePlot(
       index = timeADS,
       min_values = lowADS,
       bar_min = openADS,
       center_values = averageADS,
       bar_max = closeADS,
       max_values = highADS,

       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,

       value_mapper = testTP.y_mapper,
       index_mapper = testTP.x_mapper,
   )
   testTP.add( testTCP )

   # prettify the plot
   testTCP.index_range.low = 900
   testTCP.index_range.high = 1630
   testTCP.value_range.low = 51.3
   testTCP.value_range.high = 52.2

   testTP.title = 'Stock Prices (Test Plot)'
   testTP.x_axis.title = 'Time of Day (HHMM)'
   testTP.y_axis.title = 'OHLC'

   traits_view = View(
       HGroup( Item( 'refTP',
                     editor = ComponentEditor(size = windowSize),
                     show_label = False, ),
               Item( 'testTP',
                     editor = ComponentEditor(size = windowSize),
                     show_label = False, ),
       ),
       resizable = True,
       title = windowTitle,
   )

if __name__ == '__main__':
   thisTSP = TraitedStockPlot()
   thisTSP.configure_traits()

   print( '\n thisTSP.refTP.x_grid.mapper.print_traits()' )
   thisTSP.refTP.x_grid.mapper.print_traits()
   print( '\n thisTSP.testTP.x_grid.mapper.print_traits()' )
   thisTSP.testTP.x_grid.mapper.print_traits()

   print( 'Everything is OK' )

This code displays two plots side-by-side. The grid on the plot
generated using CandlePlot (on the right) isn't laid down in the correct
position. The grid changes when you resize the plot but it never ends up
correctly aligned with the rest of the plot. The trouble seems to lie in
the x_grid and y_grid mapper's screen_bounds attribute (see below). I
tried changing various padding values in different places but haven't
been able to achieve joy. Any help?

The output of the program is:

  thisTSP.refTP.x_grid.mapper.print_traits()
_bounds_initialized: False
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            349.0
low_pos:             50.0
range:               <chaco.data_range_1d.DataRan...ject at
0x000000000902CC50>
screen_bounds:       (50.0, 349.0)
stretch_data:        True

  thisTSP.testTP.x_grid.mapper.print_traits()
_bounds_initialized: True
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            299.0
low_pos:             0.0
range:               <chaco.data_range_1d.DataRan...ject at
0x00000000090A9C50>
screen_bounds:       (0.0, 299.0)
stretch_data:        True
Everything is OK

Thanks.
Kevin
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Grid issue with CandlePlot

Corran Webster
Hi Kevin,

this is a really quick answer before I get my daughters' some lunch :)

I haven't completely digested what you are trying to do, but it sounds like what you need to do is to connect the *ranges* of the mappers, rather than the entire mapper objects.

ie. (untested code!)

testTCP = CandlePlot(
       index = timeADS,
       min_values = lowADS,
       bar_min = openADS,
       center_values = averageADS,
       bar_max = closeADS,
       max_values = highADS,

       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,

       value_range = testTP.y_mapper.range,
       index_range = testTP.x_mapper.range,
   )

This should avoid any problems with screen coordinates.

-- Corran




On Sun, Dec 1, 2013 at 11:12 AM, Kevin McClaning <[hidden email]> wrote:
Hello -- I've been wrestling with this problem for a couple of days and
could use some help. I started looking at the way CandlePlots are built
via the plot.candle_plot() call and by calling the CandlePlot method
directly. I'm having trouble making the grids of the plots behave
identically. Example code is:

import inspect, os
from traits.api import HasTraits
from traitsui.api import View, Item, HGroup
from chaco.api import Plot, CandlePlot, ArrayPlotData, ArrayDataSource
from enable.api import ComponentEditor

# defines
windowSize = (400,300)
windowTitle = os.path.split(__file__)[1]

class TraitedStockPlot( HasTraits ):
   '''display stock prices'''

   # one day of stock prices at 15 minute intervals
   openL = [
       51.84, 52.07, 52.02, 51.89, 51.93, 51.85, 51.80, 51.74, 51.89, 51.91,
       51.86, 51.80, 51.85, 51.70, 51.77, 51.78, 51.64, 51.58, 51.51, 51.44,
       51.48, 51.49, 51.61, 51.61, 51.54, 51.58, 51.63, ]
   highL = [
       52.10, 52.07, 52.05, 51.96, 51.96, 51.88, 51.85, 51.93, 51.90, 51.92,
       51.95, 51.88, 51.85, 51.79, 51.83, 51.80, 51.64, 51.58, 51.52, 51.48,
       51.49, 51.62, 51.63, 51.67, 51.62, 51.68, 51.63, ]
   lowL = [
       51.67, 51.99, 51.76, 51.88, 51.91, 51.74, 51.80, 51.74, 51.86, 51.86,
       51.86, 51.80, 51.75, 51.65, 51.75, 51.65, 51.58, 51.44, 51.40, 51.40,
       51.42, 51.49, 51.53, 51.53, 51.52, 51.57, 51.63, ]
   closeL = [
       52.09, 52.02, 51.87, 51.93, 51.92, 51.79, 51.84, 51.88, 51.90, 51.87,
       51.89, 51.84, 51.76, 51.77, 51.79, 51.65, 51.58, 51.50, 51.41, 51.48,
       51.48, 51.61, 51.61, 51.55, 51.62, 51.64, 51.63, ]
   volumeL = [
       114911, 182201, 192537, 133607, 12200, 34204, 10834, 70180, 9900,
24558,
       9338, 21117, 14133, 42636, 29177, 29482, 15328, 49200, 36120, 21055,
       23948, 73078, 62292, 72042, 90707, 129103, 111990, ]
   timeL = [
        930,  945, 1000, 1015, 1030, 1045, 1100, 1115, 1130, 1145, 1200,
       1215, 1230, 1245, 1300, 1315, 1330, 1345, 1400, 1415, 1430, 1445,
       1500, 1515, 1530, 1545, 1600, ]

   # calculate the average price for the intervals
   averageL = [
       (highL[ii] + lowL[ii] + openL[ii] + closeL[ii])/4
       for ii in range(len(openL)) ]

   ## generate plot via plot.candle_plot()

   myTAPD = ArrayPlotData()
   myTAPD.set_data( 'open',openL )
   myTAPD.set_data( 'low',lowL )
   myTAPD.set_data( 'high',highL )
   myTAPD.set_data( 'close',closeL )
   myTAPD.set_data( 'average',averageL )
   myTAPD.set_data( 'volume',volumeL )
   myTAPD.set_data( 'time',timeL )

   refTP = Plot( myTAPD )
   refPR = refTP.candle_plot(
       ("time", "low", "close", "average", "open", "high"),
       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,
   )

   # prettify the plot
   refTP.title = 'Stock Prices (Reference Plot)'
   refTP.x_axis.title = 'Time of Day (HHMM)'
   refTP.y_axis.title = 'OHLC'

   refTP.range2d.x_range.low = 900
   refTP.range2d.x_range.high = 1630
   refTP.range2d.y_range.low = 51.3
   refTP.range2d.y_range.high = 52.2

   ## generate plot via direct call to CandlePlot

   # generate the req'd ArrayDataSources
   openADS = ArrayDataSource( data = openL )
   highADS = ArrayDataSource(  data = highL )
   lowADS = ArrayDataSource( data = lowL )
   closeADS = ArrayDataSource( data = closeL )
   volumeADS = ArrayDataSource( data = volumeL )
   averageADS = ArrayDataSource( data = averageL )
   timeADS = ArrayDataSource( data = timeL, sort_order = 'ascending' )

   # generate the plot and set the data ranges
   testTP = Plot()
   testTP.value_range.add( highADS )
   testTP.value_range.add( lowADS )
   testTP.index_range.add( timeADS )

   # build the candle plot renderer, using the mapper from testTP
   testTCP = CandlePlot(
       index = timeADS,
       min_values = lowADS,
       bar_min = openADS,
       center_values = averageADS,
       bar_max = closeADS,
       max_values = highADS,

       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,

       value_mapper = testTP.y_mapper,
       index_mapper = testTP.x_mapper,
   )
   testTP.add( testTCP )

   # prettify the plot
   testTCP.index_range.low = 900
   testTCP.index_range.high = 1630
   testTCP.value_range.low = 51.3
   testTCP.value_range.high = 52.2

   testTP.title = 'Stock Prices (Test Plot)'
   testTP.x_axis.title = 'Time of Day (HHMM)'
   testTP.y_axis.title = 'OHLC'

   traits_view = View(
       HGroup( Item( 'refTP',
                     editor = ComponentEditor(size = windowSize),
                     show_label = False, ),
               Item( 'testTP',
                     editor = ComponentEditor(size = windowSize),
                     show_label = False, ),
       ),
       resizable = True,
       title = windowTitle,
   )

if __name__ == '__main__':
   thisTSP = TraitedStockPlot()
   thisTSP.configure_traits()

   print( '\n thisTSP.refTP.x_grid.mapper.print_traits()' )
   thisTSP.refTP.x_grid.mapper.print_traits()
   print( '\n thisTSP.testTP.x_grid.mapper.print_traits()' )
   thisTSP.testTP.x_grid.mapper.print_traits()

   print( 'Everything is OK' )

This code displays two plots side-by-side. The grid on the plot
generated using CandlePlot (on the right) isn't laid down in the correct
position. The grid changes when you resize the plot but it never ends up
correctly aligned with the rest of the plot. The trouble seems to lie in
the x_grid and y_grid mapper's screen_bounds attribute (see below). I
tried changing various padding values in different places but haven't
been able to achieve joy. Any help?

The output of the program is:

  thisTSP.refTP.x_grid.mapper.print_traits()
_bounds_initialized: False
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            349.0
low_pos:             50.0
range:               <chaco.data_range_1d.DataRan...ject at
0x000000000902CC50>
screen_bounds:       (50.0, 349.0)
stretch_data:        True

  thisTSP.testTP.x_grid.mapper.print_traits()
_bounds_initialized: True
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            299.0
low_pos:             0.0
range:               <chaco.data_range_1d.DataRan...ject at
0x00000000090A9C50>
screen_bounds:       (0.0, 299.0)
stretch_data:        True
Everything is OK

Thanks.
Kevin
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Grid issue with CandlePlot

Kevin McClaning-2
In reply to this post by Kevin McClaning-2
Corran --

Thanks for getting back to me so quickly. 

No joy. I changed the CandlePlot call to

  # build the candle plot renderer, using the mapper from testTP
  testTCP = CandlePlot(
      index = timeADS,
      min_values = lowADS,
      bar_min = openADS,
      center_values = averageADS,
      bar_max = closeADS,
      max_values = highADS,

      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,

      value_range = testTP.y_mapper.range,
      index_range = testTP.x_mapper.range,

      value_mapper = testTP.y_mapper,
      index_mapper = testTP.x_mapper,
  )
 
(adding the value_range and index_range attributes). I had to leave in the value_mapper
and index_mapper assignments because CandlePlot still needs them. However, there is no 
change in the behavior of the grid. It still changes when I resize the window but 
doesn't line up with the axis tick or with with data. 

My short-term goal is to add a parameter to CandlePlot that allows me to change
the color of each candle according to a supplied array. Along the way, I stumbled across
the problem with the grid not behaving. 

Kevin

Message: 1
Date: Sun, 1 Dec 2013 12:20:57 -0600
From: Corran Webster [hidden email]
Subject: Re: [Enthought-Dev] Grid issue with CandlePlot
To: [hidden email]
Message-ID:
	[hidden email]
Content-Type: text/plain; charset="utf-8"

Hi Kevin,

this is a really quick answer before I get my daughters' some lunch 

I haven't completely digested what you are trying to do, but it sounds like
what you need to do is to connect the *ranges* of the mappers, rather than
the entire mapper objects.

ie. (untested code!)

testTCP = CandlePlot(
       index = timeADS,
       min_values = lowADS,
       bar_min = openADS,
       center_values = averageADS,
       bar_max = closeADS,
       max_values = highADS,

       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,

       value_range = testTP.y_mapper.range,
       index_range = testTP.x_mapper.range,
   )

This should avoid any problems with screen coordinates.

-- Corran




On 12/1/2013 12:12 PM, Kevin McClaning wrote:
Hello -- I've been wrestling with this problem for a couple of days and could use some help. I started looking at the way CandlePlots are built via the plot.candle_plot() call and by calling the CandlePlot method directly. I'm having trouble making the grids of the plots behave identically. Example code is:

import inspect, os
from traits.api import HasTraits
from traitsui.api import View, Item, HGroup
from chaco.api import Plot, CandlePlot, ArrayPlotData, ArrayDataSource
from enable.api import ComponentEditor

# defines
windowSize = (400,300)
windowTitle = os.path.split(__file__)[1]

class TraitedStockPlot( HasTraits ):
  '''display stock prices'''

  # one day of stock prices at 15 minute intervals
  openL = [
      51.84, 52.07, 52.02, 51.89, 51.93, 51.85, 51.80, 51.74, 51.89, 51.91,
      51.86, 51.80, 51.85, 51.70, 51.77, 51.78, 51.64, 51.58, 51.51, 51.44,
      51.48, 51.49, 51.61, 51.61, 51.54, 51.58, 51.63, ]
  highL = [
      52.10, 52.07, 52.05, 51.96, 51.96, 51.88, 51.85, 51.93, 51.90, 51.92,
      51.95, 51.88, 51.85, 51.79, 51.83, 51.80, 51.64, 51.58, 51.52, 51.48,
      51.49, 51.62, 51.63, 51.67, 51.62, 51.68, 51.63, ]
  lowL = [
      51.67, 51.99, 51.76, 51.88, 51.91, 51.74, 51.80, 51.74, 51.86, 51.86,
      51.86, 51.80, 51.75, 51.65, 51.75, 51.65, 51.58, 51.44, 51.40, 51.40,
      51.42, 51.49, 51.53, 51.53, 51.52, 51.57, 51.63, ]
  closeL = [
      52.09, 52.02, 51.87, 51.93, 51.92, 51.79, 51.84, 51.88, 51.90, 51.87,
      51.89, 51.84, 51.76, 51.77, 51.79, 51.65, 51.58, 51.50, 51.41, 51.48,
      51.48, 51.61, 51.61, 51.55, 51.62, 51.64, 51.63, ]
  volumeL = [
      114911, 182201, 192537, 133607, 12200, 34204, 10834, 70180, 9900, 24558,
      9338, 21117, 14133, 42636, 29177, 29482, 15328, 49200, 36120, 21055,
      23948, 73078, 62292, 72042, 90707, 129103, 111990, ]
  timeL = [
       930,  945, 1000, 1015, 1030, 1045, 1100, 1115, 1130, 1145, 1200,
      1215, 1230, 1245, 1300, 1315, 1330, 1345, 1400, 1415, 1430, 1445,
      1500, 1515, 1530, 1545, 1600, ]

  # calculate the average price for the intervals
  averageL = [
      (highL[ii] + lowL[ii] + openL[ii] + closeL[ii])/4
      for ii in range(len(openL)) ]

  ## generate plot via plot.candle_plot()

  myTAPD = ArrayPlotData()
  myTAPD.set_data( 'open',openL )
  myTAPD.set_data( 'low',lowL )
  myTAPD.set_data( 'high',highL )
  myTAPD.set_data( 'close',closeL )
  myTAPD.set_data( 'average',averageL )
  myTAPD.set_data( 'volume',volumeL )
  myTAPD.set_data( 'time',timeL )

  refTP = Plot( myTAPD )
  refPR = refTP.candle_plot(
      ("time", "low", "close", "average", "open", "high"),
      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,
  )

  # prettify the plot
  refTP.title = 'Stock Prices (Reference Plot)'
  refTP.x_axis.title = 'Time of Day (HHMM)'
  refTP.y_axis.title = 'OHLC'

  refTP.range2d.x_range.low = 900
  refTP.range2d.x_range.high = 1630
  refTP.range2d.y_range.low = 51.3
  refTP.range2d.y_range.high = 52.2

  ## generate plot via direct call to CandlePlot

  # generate the req'd ArrayDataSources
  openADS = ArrayDataSource( data = openL )
  highADS = ArrayDataSource(  data = highL )
  lowADS = ArrayDataSource( data = lowL )
  closeADS = ArrayDataSource( data = closeL )
  volumeADS = ArrayDataSource( data = volumeL )
  averageADS = ArrayDataSource( data = averageL )
  timeADS = ArrayDataSource( data = timeL, sort_order = 'ascending' )

  # generate the plot and set the data ranges
  testTP = Plot()
  testTP.value_range.add( highADS )
  testTP.value_range.add( lowADS )
  testTP.index_range.add( timeADS )

  # build the candle plot renderer, using the mapper from testTP
  testTCP = CandlePlot(
      index = timeADS,
      min_values = lowADS,
      bar_min = openADS,
      center_values = averageADS,
      bar_max = closeADS,
      max_values = highADS,

      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,

      value_mapper = testTP.y_mapper,
      index_mapper = testTP.x_mapper,
  )
  testTP.add( testTCP )

  # prettify the plot
  testTCP.index_range.low = 900
  testTCP.index_range.high = 1630
  testTCP.value_range.low = 51.3
  testTCP.value_range.high = 52.2

  testTP.title = 'Stock Prices (Test Plot)'
  testTP.x_axis.title = 'Time of Day (HHMM)'
  testTP.y_axis.title = 'OHLC'

  traits_view = View(
      HGroup( Item( 'refTP',
                    editor = ComponentEditor(size = windowSize),
                    show_label = False, ),
              Item( 'testTP',
                    editor = ComponentEditor(size = windowSize),
                    show_label = False, ),
      ),
      resizable = True,
      title = windowTitle,
  )

if __name__ == '__main__':
  thisTSP = TraitedStockPlot()
  thisTSP.configure_traits()

  print( '\n thisTSP.refTP.x_grid.mapper.print_traits()' )
  thisTSP.refTP.x_grid.mapper.print_traits()
  print( '\n thisTSP.testTP.x_grid.mapper.print_traits()' )
  thisTSP.testTP.x_grid.mapper.print_traits()

  print( 'Everything is OK' )

This code displays two plots side-by-side. The grid on the plot generated using CandlePlot (on the right) isn't laid down in the correct position. The grid changes when you resize the plot but it never ends up correctly aligned with the rest of the plot. The trouble seems to lie in the x_grid and y_grid mapper's screen_bounds attribute (see below). I tried changing various padding values in different places but haven't been able to achieve joy. Any help?

The output of the program is:

 thisTSP.refTP.x_grid.mapper.print_traits()
_bounds_initialized: False
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            349.0
low_pos:             50.0
range:               <chaco.data_range_1d.DataRan...ject at 0x000000000902CC50>
screen_bounds:       (50.0, 349.0)
stretch_data:        True

 thisTSP.testTP.x_grid.mapper.print_traits()
_bounds_initialized: True
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            299.0
low_pos:             0.0
range:               <chaco.data_range_1d.DataRan...ject at 0x00000000090A9C50>
screen_bounds:       (0.0, 299.0)
stretch_data:        True
Everything is OK

Thanks.
Kevin


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Grid issue with CandlePlot

Corran Webster
Hi Kevin,

you need to avoid using mappers entirely:


On Tue, Dec 3, 2013 at 6:52 AM, Kevin McClaning <[hidden email]> wrote:
Corran --

Thanks for getting back to me so quickly. 

No joy. I changed the CandlePlot call to

  # build the candle plot renderer, using the mapper from testTP
  testTCP = CandlePlot(
      index = timeADS,
      min_values = lowADS,
      bar_min = openADS,
      center_values = averageADS,
      bar_max = closeADS,
      max_values = highADS,

      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,

      value_range = testTP.y_mapper.range,
      index_range = testTP.x_mapper.range,

      value_mapper = testTP.y_mapper,
      index_mapper = testTP.x_mapper,
  )
 

Try something like:

   from chaco.api import LinearMapper

    testTCP = CandlePlot(
      index = timeADS,
      min_values = lowADS,
      bar_min = openADS,
      center_values = averageADS,
      bar_max = closeADS,
      max_values = highADS,

      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,
      
      value_mapper = LinearMapper(range=testTP.value_range),
      index_mapper = LinearMapper(range=testTP.index_range),
   )

I think this will do what you want.
(adding the value_range and index_range attributes). I had to leave in the value_mapper
and index_mapper assignments because CandlePlot still needs them. However, there is no 
change in the behavior of the grid. It still changes when I resize the window but 
doesn't line up with the axis tick or with with data. 
Is there a reason that you don't have the second CandlePlot in a separate Plot and are creating it manually?

The way I would normally do something like this would be to create two Plots, set their index and value ranges to the same object, and then create candle plots in the Plots via the usual Plot candle method.
 
My short-term goal is to add a parameter to CandlePlot that allows me to change
the color of each candle according to a supplied array. Along the way, I stumbled across
the problem with the grid not behaving. 
This would be very nice to have if performance is reasonable.  Please consider making a pull-request to Chaco if you get something working to your satisfaction.

-- Corran

 
Kevin

Message: 1
Date: Sun, 1 Dec 2013 12:20:57 -0600
From: Corran Webster [hidden email]
Subject: Re: [Enthought-Dev] Grid issue with CandlePlot
To: [hidden email]
Message-ID:
	[hidden email]
Content-Type: text/plain; charset="utf-8"

Hi Kevin,

this is a really quick answer before I get my daughters' some lunch 

I haven't completely digested what you are trying to do, but it sounds like
what you need to do is to connect the *ranges* of the mappers, rather than
the entire mapper objects.

ie. (untested code!)

testTCP = CandlePlot(
       index = timeADS,
       min_values = lowADS,
       bar_min = openADS,
       center_values = averageADS,
       bar_max = closeADS,
       max_values = highADS,

       color = "lightgray",
       bar_line_color = "black",
       stem_color = "blue",
       center_color = "red",
       center_width = 2,

       value_range = testTP.y_mapper.range,
       index_range = testTP.x_mapper.range,
   )

This should avoid any problems with screen coordinates.

-- Corran




On 12/1/2013 12:12 PM, Kevin McClaning wrote:
Hello -- I've been wrestling with this problem for a couple of days and could use some help. I started looking at the way CandlePlots are built via the plot.candle_plot() call and by calling the CandlePlot method directly. I'm having trouble making the grids of the plots behave identically. Example code is:

import inspect, os
from traits.api import HasTraits
from traitsui.api import View, Item, HGroup
from chaco.api import Plot, CandlePlot, ArrayPlotData, ArrayDataSource
from enable.api import ComponentEditor

# defines
windowSize = (400,300)
windowTitle = os.path.split(__file__)[1]

class TraitedStockPlot( HasTraits ):
  '''display stock prices'''

  # one day of stock prices at 15 minute intervals
  openL = [
      51.84, 52.07, 52.02, 51.89, 51.93, 51.85, 51.80, 51.74, 51.89, 51.91,
      51.86, 51.80, 51.85, 51.70, 51.77, 51.78, 51.64, 51.58, 51.51, 51.44,
      51.48, 51.49, 51.61, 51.61, 51.54, 51.58, 51.63, ]
  highL = [
      52.10, 52.07, 52.05, 51.96, 51.96, 51.88, 51.85, 51.93, 51.90, 51.92,
      51.95, 51.88, 51.85, 51.79, 51.83, 51.80, 51.64, 51.58, 51.52, 51.48,
      51.49, 51.62, 51.63, 51.67, 51.62, 51.68, 51.63, ]
  lowL = [
      51.67, 51.99, 51.76, 51.88, 51.91, 51.74, 51.80, 51.74, 51.86, 51.86,
      51.86, 51.80, 51.75, 51.65, 51.75, 51.65, 51.58, 51.44, 51.40, 51.40,
      51.42, 51.49, 51.53, 51.53, 51.52, 51.57, 51.63, ]
  closeL = [
      52.09, 52.02, 51.87, 51.93, 51.92, 51.79, 51.84, 51.88, 51.90, 51.87,
      51.89, 51.84, 51.76, 51.77, 51.79, 51.65, 51.58, 51.50, 51.41, 51.48,
      51.48, 51.61, 51.61, 51.55, 51.62, 51.64, 51.63, ]
  volumeL = [
      114911, 182201, 192537, 133607, 12200, 34204, 10834, 70180, 9900, 24558,
      9338, 21117, 14133, 42636, 29177, 29482, 15328, 49200, 36120, 21055,
      23948, 73078, 62292, 72042, 90707, 129103, 111990, ]
  timeL = [
       930,  945, 1000, 1015, 1030, 1045, 1100, 1115, 1130, 1145, 1200,
      1215, 1230, 1245, 1300, 1315, 1330, 1345, 1400, 1415, 1430, 1445,
      1500, 1515, 1530, 1545, 1600, ]

  # calculate the average price for the intervals
  averageL = [
      (highL[ii] + lowL[ii] + openL[ii] + closeL[ii])/4
      for ii in range(len(openL)) ]

  ## generate plot via plot.candle_plot()

  myTAPD = ArrayPlotData()
  myTAPD.set_data( 'open',openL )
  myTAPD.set_data( 'low',lowL )
  myTAPD.set_data( 'high',highL )
  myTAPD.set_data( 'close',closeL )
  myTAPD.set_data( 'average',averageL )
  myTAPD.set_data( 'volume',volumeL )
  myTAPD.set_data( 'time',timeL )

  refTP = Plot( myTAPD )
  refPR = refTP.candle_plot(
      ("time", "low", "close", "average", "open", "high"),
      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,
  )

  # prettify the plot
  refTP.title = 'Stock Prices (Reference Plot)'
  refTP.x_axis.title = 'Time of Day (HHMM)'
  refTP.y_axis.title = 'OHLC'

  refTP.range2d.x_range.low = 900
  refTP.range2d.x_range.high = 1630
  refTP.range2d.y_range.low = 51.3
  refTP.range2d.y_range.high = 52.2

  ## generate plot via direct call to CandlePlot

  # generate the req'd ArrayDataSources
  openADS = ArrayDataSource( data = openL )
  highADS = ArrayDataSource(  data = highL )
  lowADS = ArrayDataSource( data = lowL )
  closeADS = ArrayDataSource( data = closeL )
  volumeADS = ArrayDataSource( data = volumeL )
  averageADS = ArrayDataSource( data = averageL )
  timeADS = ArrayDataSource( data = timeL, sort_order = 'ascending' )

  # generate the plot and set the data ranges
  testTP = Plot()
  testTP.value_range.add( highADS )
  testTP.value_range.add( lowADS )
  testTP.index_range.add( timeADS )

  # build the candle plot renderer, using the mapper from testTP
  testTCP = CandlePlot(
      index = timeADS,
      min_values = lowADS,
      bar_min = openADS,
      center_values = averageADS,
      bar_max = closeADS,
      max_values = highADS,

      color = "lightgray",
      bar_line_color = "black",
      stem_color = "blue",
      center_color = "red",
      center_width = 2,

      value_mapper = testTP.y_mapper,
      index_mapper = testTP.x_mapper,
  )
  testTP.add( testTCP )

  # prettify the plot
  testTCP.index_range.low = 900
  testTCP.index_range.high = 1630
  testTCP.value_range.low = 51.3
  testTCP.value_range.high = 52.2

  testTP.title = 'Stock Prices (Test Plot)'
  testTP.x_axis.title = 'Time of Day (HHMM)'
  testTP.y_axis.title = 'OHLC'

  traits_view = View(
      HGroup( Item( 'refTP',
                    editor = ComponentEditor(size = windowSize),
                    show_label = False, ),
              Item( 'testTP',
                    editor = ComponentEditor(size = windowSize),
                    show_label = False, ),
      ),
      resizable = True,
      title = windowTitle,
  )

if __name__ == '__main__':
  thisTSP = TraitedStockPlot()
  thisTSP.configure_traits()

  print( '\n thisTSP.refTP.x_grid.mapper.print_traits()' )
  thisTSP.refTP.x_grid.mapper.print_traits()
  print( '\n thisTSP.testTP.x_grid.mapper.print_traits()' )
  thisTSP.testTP.x_grid.mapper.print_traits()

  print( 'Everything is OK' )

This code displays two plots side-by-side. The grid on the plot generated using CandlePlot (on the right) isn't laid down in the correct position. The grid changes when you resize the plot but it never ends up correctly aligned with the rest of the plot. The trouble seems to lie in the x_grid and y_grid mapper's screen_bounds attribute (see below). I tried changing various padding values in different places but haven't been able to achieve joy. Any help?

The output of the program is:

 thisTSP.refTP.x_grid.mapper.print_traits()
_bounds_initialized: False
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            349.0
low_pos:             50.0
range:               <chaco.data_range_1d.DataRan...ject at 0x000000000902CC50>
screen_bounds:       (50.0, 349.0)
stretch_data:        True

 thisTSP.testTP.x_grid.mapper.print_traits()
_bounds_initialized: True
_cache_valid:        True
_null_data_range:    False
_null_screen_range:  False
_scale:              0.4095890410958904
domain_limits:       (None, None)
high_pos:            299.0
low_pos:             0.0
range:               <chaco.data_range_1d.DataRan...ject at 0x00000000090A9C50>
screen_bounds:       (0.0, 299.0)
stretch_data:        True
Everything is OK

Thanks.
Kevin


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev