In [1]:
#include "random.hpp"
#include "xplot/xfigure.hpp"
#include "xplot/xmarks.hpp"
#include "xplot/xaxes.hpp"

Basic Scatter


In [2]:
std::size_t size = 10;
std::vector<double> x_data(size);
std::iota(x_data.begin(), x_data.end(), 0);
std::vector<double> y_data = randn(size);

In [3]:
xpl::linear_scale sx, sy;
auto ax_x = xpl::axis_generator(sx)
           .label("x")
           .finalize();
auto ax_y = xpl::axis_generator(sy)
           .label("y")
           .orientation("vertical")
           .side("left")
           .finalize();

In [4]:
auto scatter1 = xpl::scatter_generator(sx, sy)
               .x(x_data)
               .y(y_data)
               .finalize();

In [5]:
auto fig1 = xpl::figure_generator()
           .padding_x(0.025)
           .padding_y(0.025)
           .finalize();
fig1.add_mark(scatter1);
fig1.add_axis(ax_x);
fig1.add_axis(ax_y);
fig1.display()


Changing the marker and adding text to each point of the scatter


In [6]:
scatter1.names = std::vector<std::string>{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

In [7]:
scatter1.colors = std::vector<xtl::xoptional<std::string>>{"red"};

In [8]:
scatter1.marker = "cross";

Changing the opacity of each marker


In [9]:
scatter1.default_opacities = std::vector<double>({0.3, 0.5, 1.});

Representing additional dimensions of data

Linear Scale for Color Data


In [10]:
std::vector<double> c_data = randn(size);

In [11]:
xpl::color_scale sc;

In [12]:
auto scatter2 = xpl::scatter_generator(sx, sy, sc)
               .x(x_data)
               .y(y_data)
               .color(c_data)
               .stroke("black")
               .finalize();

In [13]:
auto ax_c = xpl::color_axis_generator(sc)
           .label("Values")
           .orientation("vertical")
           .side("right")
           .finalize();

In [14]:
auto fig2 = xpl::figure_generator()
           .padding_x(0.025)
           .fig_margin(xeus::xjson({{"top", 50}, {"bottom", 70}, {"left", 50}, {"right", 100}}))
           .finalize();
fig2.add_mark(scatter2);
fig2.add_axis(ax_x);
fig2.add_axis(ax_y);
fig2.add_axis(ax_c);
fig2.display()



In [15]:
// setting the fill to be empty
scatter2.stroke = xtl::xoptional<std::string>{};
scatter2.fill = false;

In [16]:
// Setting the fill back
scatter2.stroke = "black";
scatter2.fill = true;

Ordinal Scale for Color


In [17]:
std::vector<double> c2_data = randint(0, 5, size);

In [18]:
auto sc1 = sc;
sc1.colors = std::vector<std::string>{"DodgerBlue", "SeaGreen", "Yellow", "HotPink", "OrangeRed"};

In [19]:
auto scatter3 = xpl::scatter_generator(sx, sy, sc1)
               .x(x_data)
               .y(y_data)
               .color(c2_data)
               .stroke("black")
               .finalize();

In [20]:
auto ax2_c = xpl::color_axis_generator(sc1)
            .label("Values")
            .orientation("vertical")
            .side("right")
            .finalize();

In [21]:
auto fig3 = xpl::figure_generator()
           .padding_x(0.025)
           .fig_margin(xeus::xjson({{"top", 50}, {"bottom", 70}, {"left", 50}, {"right", 100}}))
           .finalize();
fig3.add_mark(scatter3);
fig3.add_axis(ax_x);
fig3.add_axis(ax_y);
fig3.add_axis(ax2_c);
fig3.display()



In [22]:
ax2_c.tick_format = "0.2f";
sc1.colors = std::vector<std::string>{"blue", "red", "green", "yellow", "orange"};

Setting size and opacity based on data


In [23]:
std::size_t size_o = 100;
std::vector<double> x_data_o(size);
std::iota(x_data_o.begin(), x_data_o.end(), 0);
std::vector<double> y_data_o = randn(size_o);
std::vector<double> c_data_o = randn(size_o);

In [24]:
xpl::linear_scale sx_o, sy_o;
xpl::linear_scale sc_size_o, sc_opacities;

In [26]:
auto scatter_o = xpl::scatter_generator(sx_o, sy_o, sc_size_o, sc_opacities)
                .x(x_data_o)
                .y(y_data_o)
                .size(c_data_o)
                .stroke("black")
                .default_size(128)
                .colors(std::vector<xtl::xoptional<std::string>>{"orangered"})
                .finalize();

In [27]:
xpl::axis ax_x_o(sx_o), ax_y_o(sy_o);
ax_x_o.label = "x";
ax_y_o.label = "y";
ax_y_o.orientation = "vertical";
ax_y_o.side = "left";

In [28]:
xpl::figure fig4;
fig4.padding_x = 0.025;
fig4.add_mark(scatter_o);
fig4.add_axis(ax_x_o);
fig4.add_axis(ax_y_o);
fig4.display()



In [29]:
// Changing the opacity of the scatter
scatter_o.default_opacities = std::vector<double>{0.5, 0.3, 0.1};

In [30]:
// Resetting the size for the scatter
scatter_o.size = std::vector<double>{};

In [31]:
// Resetting the opacity and setting the opacity according to the date
scatter_o.default_opacities = std::vector<double>{1.0};

Scatter Chart Interactions

Moving points in Scatter


In [32]:
std::size_t size_c = 10;
std::vector<double> x_data_c(size_c);
std::iota(x_data_c.begin(), x_data_c.end(), 0);
std::vector<double> y_data_c = randn(size_c);

In [33]:
xpl::linear_scale sx_c, sy_c;

In [37]:
auto scatter_c = xpl::scatter_generator(sx_c, sy_c)
              .x(x_data_c)
              .y(y_data_c)
              .colors(std::vector<xtl::xoptional<std::string>>{"orange"})
              .enable_move(true)
              .finalize();

In [35]:
xpl::axis ax_x_c(sx_c), ax_y_c(sy_c);
ax_x_c.label = "x";
ax_y_c.label = "y";
ax_y_c.orientation = "vertical";
ax_y_c.side = "left";

In [38]:
xpl::figure fig5;
fig5.padding_x = 0.025;
fig5.add_mark(scatter_c);
fig5.add_axis(ax_x_c);
fig5.add_axis(ax_y_c);
fig5.display()



In [39]:
#include "xwidgets/xlabel.hpp"

In [40]:
xw::label label;
label.display();



In [41]:
auto info = [&](const ::xeus::xjson& content){
    label.value = std::to_string(static_cast<double>(content["point"]["x"])) 
                + " " 
                + std::to_string(static_cast<double>(content["point"]["y"]));
};

In [42]:
scatter_c.on_drag(info);
scatter_c.on_drag_start(info);
scatter_c.on_drag_end(info);

In [43]:
// Restricting movement to only along the Y-axis
scatter_c.restrict_y = true;

Adding points to Scatter


In [ ]:
// TODO

Updating X and Y while moving the point


In [ ]:
// TODO

Custom event on end of drag


In [ ]:
// TODO

Adding tooltip and custom hover style


In [46]:
std::size_t size_tt = 50;
std::vector<double> x_data_tt(size_tt);
std::iota(x_data_tt.begin(), x_data_tt.end(), 0);
std::vector<double> y_data_tt = randn(size_tt);

In [47]:
xpl::linear_scale sx_tt, sy_tt;

In [50]:
#include "xplot/xdefault_tooltip.hpp"
xpl::tooltip def_tt;

In [51]:
def_tt.fields = std::vector<xtl::xoptional<std::string>>{"$x^2$", "y"};
def_tt.formats = std::vector<xtl::xoptional<std::string>>{"", ".2f"};

In [52]:
auto scatter_tt = xpl::scatter_generator(sx_tt, sy_tt)
                .x(x_data_tt)
                .y(y_data_tt)
                .colors(std::vector<xtl::xoptional<std::string>>{"dodgerblue"})
                .unhovered_style(::xeus::xjson::parse(R"({"opacity": "0.5"})"))
                .tooltip(def_tt)
                .finalize();

In [53]:
xpl::axis ax_x_tt(sx_tt), ax_y_tt(sy_tt);
ax_x_tt.label = "$x^2$";
ax_y_tt.label = "y";
ax_y_tt.orientation = "vertical";
ax_y_tt.side = "left";

In [54]:
xpl::figure fig6;
fig6.padding_x = 0.025;
fig6.add_mark(scatter_tt);
fig6.add_axis(ax_x_tt);
fig6.add_axis(ax_y_tt);
fig6.display()



In [55]:
// removing field names from the tooltip
def_tt.show_labels = false;

In [56]:
// changing the fields displayed in the tooltip
def_tt.fields = std::vector<xtl::xoptional<std::string>>{"y"};

In [57]:
ax_x_tt.label = "x";

In [ ]: