You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
plot.xts() is based on quantmod::chart_Series(). The internal structures have a lot of implicit assumptions and some duplicated code, which makes the code harder to reason about and change. For example:
There are no explicit "panels", i.e. what is added when addSeries() is called with on = NA. Instead, there is one list of "frames" that contains header and series frames. The odd numbered list elements are the header frames and the even numbered elements are the series frames.
Target: store the header and series frames in a panel object.
Everything that gets rendered is in one list of "actions". Where the action is rendered is stored in the "frame" attribute of the action.
Target: frames should contain actions that are rendered in the the frame.
There are separate lists for the ylim and x/y aspect ratio for each frame.
Target: frames should contain their ylim and x/y aspect ratio.
There are 5 separate code blocks to add y-axis grid lines and labels.
Target: the panel should control the y-axis settings.
Some functions are always called, even though they're only necessary in certain situations. For example, get_ylim() is always called but only needed when multi.panel = TRUE.
The x-axis action is part of the first series frame.
Target: the x-axis is the same for the entire plot, so it should be part of the plot object.
The main purpose for this refactor is to make it easier to implement y-axis log scaling (#103).
Refactor target design
The target design attempts to organize the plot components into their respective parts: the plot window, the window panels, and the panel data/actions.
The plot object contains the plot title/header (and optional timespan), the x-axis labels and tick marks, and a list of 'panel' objects. The main plot object contains:
Env: an environment to hold all the plot information
add_main_header(): add the main plot header
add_main_xaxis(): add the x-axis labels and ticks to the main plot
new_panel(): create a new panel and add it to the plot
get_xcoords(): get the x-coordinate values for the plot
get_panel(): get a specific panel
get_last_action_panel(): get the panel that had the last rendered action
new_environment(): create a new environment with Env as its parent
Functions that aren't intended to be called externally:
update_panels(): re-calculate the x-axis and y-axis values
render_panels(): render all the plot panels
x_grid_lines(): plot the x-axis grid lines
create_ylim(): create y-axis max/min, to handle when max(x) == min(x).
The panel object contains:
id: the numeric index of the panel in the plot's list of panels
asp: the x/y aspect ratio for the panel (relative vertical size)
ylim: the ylim of the panel when it was created
ylim_render: the ylim of the panel to use when rendering
use_fixed_ylim: when TRUE, do not update the panel ylim based on all panel series
header: the panel title
actions: a list of expressions used to render the panel
add_action(): add an action to the actions list
yaxis_expr the expression to render the y-axis min/max values, labels, and grid lines/ticks. It also contains the x-axis grid expression because we need the y-axis min/max values to know where to draw the x-axis grid lines on the panel.
The text was updated successfully, but these errors were encountered:
# xts 0.14.x (202x-xx-xx)
* `plot.xts()` now renders all panels when 'x' has more than 8 columns and
`multi.panel = TRUE`. Columns 9 and later didn't render because the default
of `plot.xts()` is 'col = 1:8'. Thanks to Ethan Smith for the report and
patch.
([#423](joshuaulrich/xts#423))
([#424](joshuaulrich/xts#424))
* `plot.xts()` no longer errors when 'ylim' is constant and negative. Thanks
to Ethan Smith for the report.
([#422](joshuaulrich/xts#422))
* Do not use `SET_TYPEOF()` in C because it is not part of the public R API.
* `merge.xts()` no longer converts 'x' or 'y' from double to integer in the C
code when they are not used in the result. This avoids an unnecessary and
confusing warning. Thanks to Jeff Ryan for the report.
# xts 0.14.0 (2024-06-05)
* `addEventLines()` and `addLegend()` now draw on multiple panels when `on` is
a vector. Thanks to Ethan Smith for the report.
([#420](joshuaulrich/xts#420))
* Replace `SET_TYPEOF()` in merge.c because it will error when it tries to
convert a REAL to an INTEGER. Thanks to Kurt Hornik for the report!
([#419](joshuaulrich/xts#419))
* Fix crash when 'j' is not an integer and in [0, 1) (e.g. `j = 0.1`). Also
throw a warning when 'j' is not an integer.
([#413](joshuaulrich/xts#413))
([#415](joshuaulrich/xts#415))
* Fix plot header when `layout()` is used to draw multiple plots on a single
device. Thanks to Dirk Eddelbuettel for the report and testing!
([#412](joshuaulrich/xts#412))
* Fix plot legend location when the y-axis is log scale.
([#407](joshuaulrich/xts#407))
# xts 0.13.2 (2024-01-21)
* Print a message when `period.apply()` is called with `FUN = mean` because it
calculates the mean for each column, not all the data in the subset like it
does for all other functions. The message says to use `FUN = colMeans` for
current behavior and `FUN = function(x) mean(x)` to calculate the mean for
all the data. This information is also included in the help files. The option
`xts.message.period.apply.mean = FALSE` suppresses the message.
([#124](joshuaulrich/xts#124))
* Fix error when `print.xts()` is called 'quote' or 'right' arguments.
([#401](joshuaulrich/xts#401))
* Fix `addPolygon()` so it renders when `observation.based = TRUE`.
([#403](joshuaulrich/xts#403))
* Print trailing zeros for index value with fractional seconds, so every index
value has the same number of characters.
([#404](joshuaulrich/xts#404))
* Add ability to log scale the y-axis in `plot.xts()`.
([#103](joshuaulrich/xts#103))
* Actually change the underlying index values when 'tclass' is changed from a
class with a timezone (e.g. POSIXct) to one without a timezone (e.g. Date).
Add a warning when this happens, with a global option to always suppress the
warning.
([#311](joshuaulrich/xts#311)).
* Significantly refactor the internals of `plot.xts()`.
([#408](joshuaulrich/xts#408))
Original design
plot.xts()
is based onquantmod::chart_Series()
. The internal structures have a lot of implicit assumptions and some duplicated code, which makes the code harder to reason about and change. For example:addSeries()
is called withon = NA
. Instead, there is one list of "frames" that contains header and series frames. The odd numbered list elements are the header frames and the even numbered elements are the series frames.get_ylim()
is always called but only needed whenmulti.panel = TRUE
.The main purpose for this refactor is to make it easier to implement y-axis log scaling (#103).
Refactor target design
The target design attempts to organize the plot components into their respective parts: the plot window, the window panels, and the panel data/actions.
The plot object contains the plot title/header (and optional timespan), the x-axis labels and tick marks, and a list of 'panel' objects. The main plot object contains:
Env
: an environment to hold all the plot informationadd_main_header()
: add the main plot headeradd_main_xaxis()
: add the x-axis labels and ticks to the main plotnew_panel()
: create a new panel and add it to the plotget_xcoords()
: get the x-coordinate values for the plotget_panel()
: get a specific panelget_last_action_panel()
: get the panel that had the last rendered actionnew_environment()
: create a new environment withEnv
as its parentupdate_panels()
: re-calculate the x-axis and y-axis valuesrender_panels()
: render all the plot panelsx_grid_lines()
: plot the x-axis grid linescreate_ylim()
: create y-axis max/min, to handle whenmax(x) == min(x)
.The panel object contains:
id
: the numeric index of the panel in the plot's list of panelsasp
: the x/y aspect ratio for the panel (relative vertical size)ylim
: the ylim of the panel when it was createdylim_render
: the ylim of the panel to use when renderinguse_fixed_ylim
: whenTRUE
, do not update the panel ylim based on all panel seriesheader
: the panel titleactions
: a list of expressions used to render the paneladd_action()
: add an action to the actions listyaxis_expr
the expression to render the y-axis min/max values, labels, and grid lines/ticks. It also contains the x-axis grid expression because we need the y-axis min/max values to know where to draw the x-axis grid lines on the panel.The text was updated successfully, but these errors were encountered: