From fab55d99cbac67026d37e8105c4cd4c1dd26676e Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Fri, 4 Sep 2015 17:34:50 +0200 Subject: [PATCH 1/7] DOC: MEP to improve the Axes API --- doc/devel/MEP/MEP29.rst | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 doc/devel/MEP/MEP29.rst diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst new file mode 100644 index 000000000000..65eae661c130 --- /dev/null +++ b/doc/devel/MEP/MEP29.rst @@ -0,0 +1,59 @@ +Overhauling Axes + +What do we mean by Axes? +------------------------ + +It contains a coordinate space made of 1 or more `Axis` and we can plot in this +defined space. + +Some examples of axes: +2D Cartesian (x, y) +2D Polar (rho, theta) +3D Cartesian (x, y, z) +3D Spherical Polar +3D Cylindrical Polar + +In fact Lagrangian mechanics simplifies the multitude of axes to a generic set +of axis \vec{q}. As we depend on 2D Cartesian geometry for output to the +screen, and or paper documents etcetera, we thus need to convert from our axes to +2D Cartesian coordinates. + +So as not to rewrite all the plot methods for every axes, we need our Base Axes +class to do the conversion for us through an Axes API. + +Secondly, we need this API to convert from screen coordinates back to our Axes +coordinates so as to facilitate user interaction. + +Finally, we need to stay aware of the fact that that some coordinate systems +do not have a 1:1 mapping with screen coordinates, that we will specify extra +parameters determined at run time to control this for example four parameters +to control the extent of the 2D Cartesian screen domain; in 3d parameters to +control the rotation and zoom. + +As well as Axes 3D, Basemap should also welcome this change, with an anticipated +structure of a base mapping class with a coordinate system in lat/lon +coordinates, but with different mapping projections available for the +conversion between the Axes coordinate system and the screen. + +Towards an API +-------------- +First we define our coordinate transformation functions: +axes_to_base(self, *q) +base_to_axes(self, x, y) + +The term ``base`` could get replaced with ``screen`` but for now we keep it +simple to reflect another transformation from base coords to screen coords, +e.g. perhaps to differentiate between window and screen coords. + +We need a view state to obtain the current parameters controlling the +conversion, the main question here lies in whether this should get built into +the axes class directly, or form work as a separate "helper" class, deriving +from a ``ViewStateBase``. The choice here will determine the class hireachy, +as different 3D axes will have the same view state parameters, but different +transformation methods. We have three choices here: +1. Direct class hirearchy Base -> 3D -> 3D Specific +2. Class has the parameters class as an attribute +3. Multiple Inheritance, allowing us to mix in these parts, so: + (Base + View) -> 3D Specific + + From a520542c7b8dc4dbf6d900d39b8294325f42bab1 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Fri, 4 Sep 2015 22:57:37 +0200 Subject: [PATCH 2/7] DOC: More doc --- doc/devel/MEP/MEP29.rst | 86 ++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 19 deletions(-) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index 65eae661c130..792f1639ccd8 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -1,17 +1,41 @@ -Overhauling Axes +======================== +Overhauling the Axes API +======================== + +.. contents:: + :local: + +Abstract +======== +The axes API at the moment feels bursting at the seems with so many tweaks and +new features over the years that it has come time for a simplification. We +have many different types of Axis now, from Polar coordinates, Axes3D, and even +Basemap utilising different plotting techniques, aka projections to convert a +curved 2D space onto a flat 2D space, namely the screen and/or paper. This MEP +seeks to address this simplification process. + + +Detailed description +==================== +Before we can look at changing the system, we first need to understand the +concepts of Axes, and this we do in this section. What do we mean by Axes? ------------------------ +Before we can look into the concept of Axes, we need to first look at the +singular, at its simplest level, we think of an Axis as one dimensional, +a simple number line. It has units and it has a scale. It contains a coordinate space made of 1 or more `Axis` and we can plot in this defined space. Some examples of axes: -2D Cartesian (x, y) -2D Polar (rho, theta) -3D Cartesian (x, y, z) -3D Spherical Polar -3D Cylindrical Polar ++ 2D Cartesian (x, y) ++ 2D Polar (rho, theta) ++ 3D Cartesian (x, y, z) ++ 3D Spherical Polar ++ 3D Cylindrical Polar ++ 2D on a sphere as we have in Basemap In fact Lagrangian mechanics simplifies the multitude of axes to a generic set of axis \vec{q}. As we depend on 2D Cartesian geometry for output to the @@ -24,36 +48,60 @@ class to do the conversion for us through an Axes API. Secondly, we need this API to convert from screen coordinates back to our Axes coordinates so as to facilitate user interaction. -Finally, we need to stay aware of the fact that that some coordinate systems -do not have a 1:1 mapping with screen coordinates, that we will specify extra -parameters determined at run time to control this for example four parameters -to control the extent of the 2D Cartesian screen domain; in 3d parameters to -control the rotation and zoom. +Finally, we need to stay aware of the fact that coordinate systems do not have +a 1:1 mapping with screen coordinates, that we will specify extra parameters +determined at run time to control this, for example at present the standard 2d +axes uses four parameters to control the extent of the 2D Cartesian screen +domain, set via x_lim, and y_lim these get affected by the pan/zoom controls +of the GUI. In 3d we have more parameters to control the rotation and zoom. -As well as Axes 3D, Basemap should also welcome this change, with an anticipated -structure of a base mapping class with a coordinate system in lat/lon -coordinates, but with different mapping projections available for the +As well as Axes 3D, Basemap should also welcome this change, with an +anticipated structure of a base mapping class with a coordinate system in +lat/lon coordinates, but with different mapping projections available for the conversion between the Axes coordinate system and the screen. -Towards an API --------------- +Implementation +============== +Towards a cleaner API +--------------------- + First we define our coordinate transformation functions: axes_to_base(self, *q) base_to_axes(self, x, y) -The term ``base`` could get replaced with ``screen`` but for now we keep it -simple to reflect another transformation from base coords to screen coords, +The term ``base`` could get replaced with ``screen`` but for now we will keep +it simple to reflect another transformation from base coords to screen coords, e.g. perhaps to differentiate between window and screen coords. +To provide a common API to interface with the contained ``Axis`` classes, we +will use a dictionary to map the name of the axis to the ``Axis`` class. + We need a view state to obtain the current parameters controlling the conversion, the main question here lies in whether this should get built into the axes class directly, or form work as a separate "helper" class, deriving from a ``ViewStateBase``. The choice here will determine the class hireachy, as different 3D axes will have the same view state parameters, but different transformation methods. We have three choices here: + 1. Direct class hirearchy Base -> 3D -> 3D Specific 2. Class has the parameters class as an attribute 3. Multiple Inheritance, allowing us to mix in these parts, so: - (Base + View) -> 3D Specific + (Base + View) -> 3D Specific + +Axis, as mentioned above, an axis basically controls the number side, it has a +scale. A Cartesian axis can have a linear scale or a log scale, but how about +a polar axis, such an axis due to its periodic nature, we cannot scale. +This suggests an API for the Axis class, we have our base class which deals +with the representation and unit system, and then we have subclasses such as +``CartesianAxis``, and perhaps also ``PolarAxis``. From here we can define a +generic chain to convert between coordinate systems. The raw data first gets +scaled by the Axis, before the ``Axes`` class can convert it to base/screen +coordinates. +Backward Compatibility +====================== +So far this new refined API doesn't break the existing API as we can alias the +new API with the old terminology which we can later deprecate if desired. If +we do deprecate the old API, we would do so over a long period as I imagine +it exists pretty well ingrained in the codebase. From 686846d540538236941df10669e5bfe7173f61f7 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Sat, 5 Sep 2015 01:48:44 +0200 Subject: [PATCH 3/7] DOC: More doc for Axes API MEP --- doc/devel/MEP/MEP29.rst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index 792f1639ccd8..1fdd75eb69e0 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -66,7 +66,7 @@ Towards a cleaner API --------------------- First we define our coordinate transformation functions: -axes_to_base(self, *q) +axes_to_base(self, \*q) base_to_axes(self, x, y) The term ``base`` could get replaced with ``screen`` but for now we will keep @@ -86,7 +86,7 @@ transformation methods. We have three choices here: 1. Direct class hirearchy Base -> 3D -> 3D Specific 2. Class has the parameters class as an attribute 3. Multiple Inheritance, allowing us to mix in these parts, so: - (Base + View) -> 3D Specific + (Base + View) -> 3D Specific Axis, as mentioned above, an axis basically controls the number side, it has a scale. A Cartesian axis can have a linear scale or a log scale, but how about @@ -99,6 +99,20 @@ scaled by the Axis, before the ``Axes`` class can convert it to base/screen coordinates. +Still to think about +==================== ++ Twined axes ++ Parasite axes + +We need an API to link these more formally together as one. Imagine having +twin/parasite axes on a 3d plot. We need a more formal linking both so that +these other axes share the same view state, but also for more general +interaction like reporting the cursor location on all axes that the cursor lies +in. An AxesContainer would work for the latter but not the former. + +Perhaps we should work this part out later? + + Backward Compatibility ====================== So far this new refined API doesn't break the existing API as we can alias the From 108b0cff1ef5e98991db3a04d4b739f0369a4250 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Sat, 5 Sep 2015 03:09:29 +0200 Subject: [PATCH 4/7] DOC: Somre more stuff --- doc/devel/MEP/MEP29.rst | 16 ++++++++++++---- doc/devel/MEP/index.rst | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index 1fdd75eb69e0..cf17e47f91e5 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -62,8 +62,8 @@ conversion between the Axes coordinate system and the screen. Implementation ============== -Towards a cleaner API ---------------------- +Axes +---- First we define our coordinate transformation functions: axes_to_base(self, \*q) @@ -88,7 +88,9 @@ transformation methods. We have three choices here: 3. Multiple Inheritance, allowing us to mix in these parts, so: (Base + View) -> 3D Specific -Axis, as mentioned above, an axis basically controls the number side, it has a +Axis +---- +As mentioned above, an axis basically controls the number side, it has a scale. A Cartesian axis can have a linear scale or a log scale, but how about a polar axis, such an axis due to its periodic nature, we cannot scale. This suggests an API for the Axis class, we have our base class which deals @@ -98,6 +100,9 @@ generic chain to convert between coordinate systems. The raw data first gets scaled by the Axis, before the ``Axes`` class can convert it to base/screen coordinates. +We should note that a colorbar essentially exists as 1D Cartesian Axis, and +thus it might feel nice for it to also use this class. + Still to think about ==================== @@ -108,7 +113,10 @@ We need an API to link these more formally together as one. Imagine having twin/parasite axes on a 3d plot. We need a more formal linking both so that these other axes share the same view state, but also for more general interaction like reporting the cursor location on all axes that the cursor lies -in. An AxesContainer would work for the latter but not the former. +in. An AxesContainer would work for the latter but not the former. We also +need to think about whether we define the colorbar as part of the axes. +Logically speaking it exists as just another axis together with the spatial +ones. Perhaps we should work this part out later? diff --git a/doc/devel/MEP/index.rst b/doc/devel/MEP/index.rst index 1a14f65de440..5e5a0bfc0904 100644 --- a/doc/devel/MEP/index.rst +++ b/doc/devel/MEP/index.rst @@ -29,3 +29,4 @@ Matplotlib Enhancement Proposals MEP25 MEP26 MEP27 + MEP29 From 142de194cb25ee32f4c5b487bede422048be64bc Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Sat, 5 Sep 2015 16:48:16 +0200 Subject: [PATCH 5/7] DOC: Abstract update for MEP29 Axes refactor --- doc/devel/MEP/MEP29.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index cf17e47f91e5..dd8f8a6c7a5e 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -10,9 +10,13 @@ Abstract The axes API at the moment feels bursting at the seems with so many tweaks and new features over the years that it has come time for a simplification. We have many different types of Axis now, from Polar coordinates, Axes3D, and even -Basemap utilising different plotting techniques, aka projections to convert a -curved 2D space onto a flat 2D space, namely the screen and/or paper. This MEP -seeks to address this simplification process. +Basemap. + +This MEP will simplify the API making our existing classes simpler and pave the +way for more interesting exotic Axes, such as those found in non-Euclidean +geometry, we already implement one such gemoetry, i.e. basemap which implements +the simplest elliptic geometry, and provides various projections for which to +project this geometry onto a 2D surface (the screen/paper). Detailed description From 80a0e4c6fdab92cb92f281287c5f1027877291c8 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Sun, 13 Sep 2015 14:26:40 +0200 Subject: [PATCH 6/7] DOC: Axes MEP (29) - Colourbar --- doc/devel/MEP/MEP29.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index dd8f8a6c7a5e..83c4f420ce98 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -34,6 +34,7 @@ It contains a coordinate space made of 1 or more `Axis` and we can plot in this defined space. Some examples of axes: + + 2D Cartesian (x, y) + 2D Polar (rho, theta) + 3D Cartesian (x, y, z) @@ -64,6 +65,16 @@ anticipated structure of a base mapping class with a coordinate system in lat/lon coordinates, but with different mapping projections available for the conversion between the Axes coordinate system and the screen. +The Colourbar +------------- +An often overlooked Axis, the colour axis exists and functions in the same way +as the other spatial dimensions. This becomes easier to visualise when we look +consider the colourbar, existing as a number line just like the other axis +components. As well as conceptually similar, it also functions the same as the +other axis: we can apply different scales, such as a log scale; draw +tick-labels; ensure non-singularity of the data etcetera. + + Implementation ============== Axes From b6891dddaa93836bca5b1aee84974561343a3b53 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Tue, 15 Sep 2015 17:21:55 +0200 Subject: [PATCH 7/7] DOC: Add table overview of supported Axes --- doc/devel/MEP/MEP29.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/devel/MEP/MEP29.rst b/doc/devel/MEP/MEP29.rst index 83c4f420ce98..e770427fbe3c 100644 --- a/doc/devel/MEP/MEP29.rst +++ b/doc/devel/MEP/MEP29.rst @@ -74,6 +74,31 @@ components. As well as conceptually similar, it also functions the same as the other axis: we can apply different scales, such as a log scale; draw tick-labels; ensure non-singularity of the data etcetera. +Comparing currently supported types of axes +------------------------------------------- + ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ +| Axes | Coordinate System | Plotting coordinates | Axis.grid() works | Known Bugs | +| | (that we draw on the axis) | (passed to plot methods) | | | ++=======================+===============================+===========================+===================+===================+ +| Cartesian 2D | x, y | Same as coord system | Yes | Twin Axes | ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ +| Skewed 2D | x, y | Same as coord system | Yes, but... | MEP 22 | +| (See skewt example) | | | buggy with MEP 22 | Issue with 0 | ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ +| Polar (2D) | r, theta | Same as coord system | Yes | Lots of open bugs | ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ +| Cartesian 3D | x, y, z | Same as coord system | Yes | Lots of open bugs | ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ +| Spherical Geometry | latitude, longitude | Uses the specified 2D | No | | +| (2D plotting on the | in degrees using | projection coordinates | | | +| surface of a sphere | drawmeridians and | | | | +| aka Basemap) | drawparallels respectfully | | | | ++-----------------------+-------------------------------+---------------------------+-------------------+-------------------+ + +Note the GUI backends use the plotting coordinates when displaying the +coordinates under the mouse cursor in the statusbar. As far as I know, this +only affects Basemap, but exists as a generic that requires a generic approach. Implementation ==============