-
Notifications
You must be signed in to change notification settings - Fork 11
Plot with dashed lines #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
f0457c9
36a5ee9
4218dab
29f3054
34167fd
0b8b2ee
dcaeb78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,6 +95,10 @@ class Axis : public Drawable { | |
| /// the number of ticks displayed on the y axis | ||
| int m_ny_ticks; | ||
|
|
||
| /// the length of maximum yticks char length | ||
| int m_max_ytick_char_len = 0; | ||
| std::string m_max_ytick_char = ""; | ||
|
|
||
| /// the length (in pixels) of each tick | ||
| float m_tick_len; | ||
|
|
||
|
|
@@ -219,6 +223,22 @@ class Axis : public Drawable { | |
| /// gets the number of ticks on this axis | ||
| Vector<int, 2> get_ticks() const { return {m_nx_ticks, m_ny_ticks}; } | ||
|
|
||
| /// get the number of maximum yticks length (in pixels) | ||
| int max_ytick_pixels() const { | ||
| /// Convertion from length * font_size to pixels | ||
| /// The scale factor, i.e., 1.25, is for Roboto font (https://bugbox.clickteam.com/threads/82514-Useful-Roboto-Font-Size-Pixel-Heights!) | ||
| return int(this->max_ytick_char_len() * m_style.font_size() / 1.25); | ||
| } | ||
|
|
||
| // get the number of maximum char length of yticks | ||
| int max_ytick_char_len() const { return m_max_ytick_char_len; } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // get default font size | ||
| float font_size() const { return m_style.font_size(); } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove this too as is not needed. |
||
|
|
||
| // get maximum char | ||
| std::string max_ytick_char() const { return m_max_ytick_char; } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and remove this |
||
|
|
||
| private: | ||
| /// Create a new Geometry on this axis and return a shared pointer to it. | ||
| /// | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -37,6 +37,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||||
| #include "frontend/Axis.hpp" | ||||||
| #include "frontend/Geometry.hpp" | ||||||
| #include "frontend/Line.hpp" | ||||||
| #include <iostream> | ||||||
| #include <cstring> | ||||||
|
|
||||||
| namespace trase { | ||||||
|
|
||||||
|
|
@@ -96,18 +98,28 @@ template <typename Backend> void Axis::draw_common_ticks(Backend &backend) { | |||||
|
|
||||||
| backend.text_align(ALIGN_RIGHT | ALIGN_MIDDLE); | ||||||
|
|
||||||
| size_t max_char_len = this->max_ytick_char_len(); | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| // y ticks | ||||||
| for (std::size_t i = 0; i < m_tick_info.y_pos.size(); ++i) { | ||||||
|
|
||||||
| const float pos = m_tick_info.y_pos[i]; | ||||||
| const float val = m_tick_info.y_val[i]; | ||||||
|
|
||||||
| backend.move_to(vfloat2_t(m_pixels.bmin[0] - m_tick_len / 2, pos)); | ||||||
| backend.line_to(vfloat2_t(m_pixels.bmin[0], pos)); | ||||||
| std::snprintf(buffer, sizeof(buffer), "%.*g", m_sig_digits + 1, val); | ||||||
|
|
||||||
| if (strlen(buffer) > max_char_len) { | ||||||
| max_char_len = strlen(buffer); | ||||||
| m_max_ytick_char = std::string(buffer); | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. think |
||||||
| } | ||||||
|
|
||||||
| backend.text(vfloat2_t(m_pixels.bmin[0] - m_tick_len / 2, pos), buffer, | ||||||
| NULL); | ||||||
| } | ||||||
|
|
||||||
| m_max_ytick_char_len = max_char_len; | ||||||
|
|
||||||
| backend.stroke_color(RGBA(0, 0, 0, 255)); | ||||||
| backend.stroke_width(m_style.line_width() / 2); | ||||||
| backend.stroke(); | ||||||
|
|
@@ -167,8 +179,7 @@ template <typename Backend> void Axis::draw_common_ylabel(Backend &backend) { | |||||
| } | ||||||
|
|
||||||
| backend.text_align(ALIGN_CENTER | ALIGN_BOTTOM); | ||||||
| const vfloat2_t point = vfloat2_t( | ||||||
| m_pixels.bmin[0] - 0.05f * (m_pixels.bmax[0] - m_pixels.bmin[0]), | ||||||
| const vfloat2_t point = vfloat2_t(m_pixels.bmin[0] - this->max_ytick_pixels(), | ||||||
| 0.5f * (m_pixels.bmax[1] + m_pixels.bmin[1])); | ||||||
| backend.translate(point); | ||||||
| backend.rotate(-pi / 2.0f); | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,3 +137,36 @@ TEST_CASE("set number of ticks", "[axis]") { | |
| CHECK(ax->get_ticks()[0] == 10); | ||
| CHECK(ax->get_ticks()[1] == 10); | ||
| } | ||
|
|
||
|
|
||
| TEST_CASE("ylabel position: case 1", "[axis]") { | ||
| std::vector<double> predicted_data = { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rename these vectors x and y and use these below rather than creating another pair of vectors |
||
| -13.8881, -13.8671, -13.8361, -13.7881, -13.7681, -13.7381, -12.6881, -12.661, -12.6481 | ||
| }; | ||
| std::vector<double> exp_data = { | ||
| -13.8881, -13.8671, -13.8361, -13.7881, -13.7681, -13.7381, -12.6881, -12.661, -12.6481 | ||
| }; | ||
|
|
||
| auto fig = figure(); | ||
| auto ax = fig->axis(); | ||
| int predicted_size = predicted_data.size(); | ||
| int exp_size = exp_data.size(); | ||
|
|
||
| std::vector<float> x(predicted_size); | ||
| std::vector<float> y(exp_size); | ||
| for (int i = 0; i < predicted_size; ++i) { | ||
| x[i] = predicted_data[i]; | ||
| } | ||
| for (int i = 0; i < exp_size; ++i) { | ||
| y[i] = exp_data[i]; | ||
| } | ||
|
|
||
| auto data = create_data().x(x).y(y); | ||
| auto plt = ax->points(data); | ||
|
|
||
| ax->xlabel("Pred. Target"); | ||
| ax->ylabel("Exp. Target"); | ||
|
|
||
| DummyDraw::draw("axis", fig); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| /* | ||
| Copyright (c) 2018, University of Oxford. | ||
| All rights reserved. | ||
|
|
||
| University of Oxford means the Chancellor, Masters and Scholars of the | ||
| University of Oxford, having an administrative office at Wellington | ||
| Square, Oxford OX1 2JD, UK. | ||
|
|
||
| This file is part of the Oxford RSE C++ Template project. | ||
|
|
||
| Redistribution and use in source and binary forms, with or without | ||
| modification, are permitted provided that the following conditions are met: | ||
| * Redistributions of source code must retain the above copyright notice, this | ||
| list of conditions and the following disclaimer. | ||
| * Redistributions in binary form must reproduce the above copyright notice, | ||
| this list of conditions and the following disclaimer in the documentation | ||
| and/or other materials provided with the distribution. | ||
| * Neither the name of the copyright holder nor the names of its | ||
| contributors may be used to endorse or promote products derived from | ||
| this software without specific prior written permission. | ||
|
|
||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
|
|
||
| #include "catch.hpp" | ||
|
|
||
| #include "DummyDraw.hpp" | ||
|
|
||
| #include "trase.hpp" | ||
| #include <fstream> | ||
| #include <random> | ||
|
|
||
| using namespace trase; | ||
|
|
||
| TEST_CASE("Lines creation", "[lines]") { | ||
| // create figure and axis | ||
| auto fig = figure(); | ||
| auto ax = fig->axis(); | ||
|
|
||
| // create x and y vectors | ||
| const int n = 100; | ||
| std::vector<float> x(n); | ||
| std::vector<float> y(n); | ||
| const float k = 1.f; | ||
| auto logistic = [k](const float x) { return 1.f / (1.f + std::exp(-k * x)); }; | ||
| for (int i = 0; i < n; ++i) { | ||
| x[i] = -6.f + 12.f * static_cast<float>(i) / n; | ||
| y[i] = logistic(x[i]); | ||
| } | ||
|
|
||
| // create a trase dataset and then plot it using a line geometry | ||
| auto data = create_data().x(x).y(y); | ||
| auto plt = ax->line(data); | ||
|
|
||
| // set line color = red and line width = 10 | ||
| plt->style().color(RGBA(255, 0, 0)).line_width(10).line_style("dashed"); | ||
|
|
||
| // label axis | ||
| ax->xlabel("x"); | ||
| ax->ylabel("y"); | ||
|
|
||
| DummyDraw::draw("lines", fig); | ||
| } | ||
|
|
||
| TEST_CASE("Hybrids lines creation", "[lines]") { | ||
|
|
||
| auto fig = figure(); | ||
| auto ax = fig->axis(); | ||
|
|
||
| { | ||
| auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{0, 1}); | ||
| auto plt = ax->line(data); | ||
| plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("solid"); | ||
| } | ||
|
|
||
| { | ||
| auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{0.5, 1.5}); | ||
| auto plt = ax->line(data); | ||
| plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("dashed"); | ||
| } | ||
|
|
||
| { | ||
| auto data = create_data().x(std::vector<float>{0, 1}).y(std::vector<float>{-0.5, 0.5}); | ||
| auto plt = ax->line(data); | ||
| plt->style().color(RGBA(255, 0, 0)).line_width(5).line_style("dotted"); | ||
| } | ||
|
|
||
| ax->xlabel("Pred. Target"); | ||
| ax->ylabel("Exp. Target"); | ||
|
|
||
| DummyDraw::draw("lines", fig); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This calculation should really be done by the
Styleclass, but since the calculation is still not correct please put it inline inAxis::draw_common_ylabelalong with a TODO comment