mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[python] Add an "axis" function to the matplotlib module
This commit is contained in:
committed by
Émilie Feral
parent
c99bed6922
commit
6a796f5f7c
@@ -74,11 +74,11 @@ Q(get_pixel)
|
||||
Q(set_pixel)
|
||||
|
||||
// Matplotlib QSTRs
|
||||
Q(axis)
|
||||
Q(plot)
|
||||
Q(pyplot)
|
||||
Q(show)
|
||||
|
||||
|
||||
// Turtle QSTRs
|
||||
Q(turtle)
|
||||
Q(forward)
|
||||
|
||||
@@ -1,17 +1,72 @@
|
||||
extern "C" {
|
||||
#include "modpyplot.h"
|
||||
}
|
||||
#include <assert.h>
|
||||
#include "port.h"
|
||||
#include "plot_controller.h"
|
||||
|
||||
Matplotlib::PlotController sPlotController;
|
||||
Matplotlib::PlotStore * sPlotStore = nullptr;
|
||||
Matplotlib::PlotController * sPlotController = nullptr;
|
||||
|
||||
// Internal functions
|
||||
|
||||
mp_obj_t modpyplot___init__() {
|
||||
static Matplotlib::PlotStore plotStore;
|
||||
static Matplotlib::PlotController plotController(&plotStore);
|
||||
sPlotStore = &plotStore;
|
||||
sPlotController = &plotController;
|
||||
sPlotStore->flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
void modpyplot_gc_collect() {
|
||||
if (sPlotStore != nullptr) {
|
||||
return;
|
||||
}
|
||||
MicroPython::collectRootsAtAddress(
|
||||
reinterpret_cast<char *>(&sPlotStore),
|
||||
sizeof(Matplotlib::PlotStore)
|
||||
);
|
||||
}
|
||||
|
||||
/* axis(arg)
|
||||
* - arg = [xmin, xmax, ymin, ymax]
|
||||
* - arg = True, False
|
||||
* Returns : xmin, xmax, ymin, ymax : float */
|
||||
|
||||
mp_obj_t modpyplot_axis(mp_obj_t arg) {
|
||||
mp_obj_is_type(arg, &mp_type_enumerate);
|
||||
#warning Use mp_obj_is_bool when upgrading uPy
|
||||
if (mp_obj_is_type(arg, &mp_type_bool)) {
|
||||
sPlotStore->setGrid(mp_obj_is_true(arg));
|
||||
} else {
|
||||
mp_obj_t * items;
|
||||
mp_obj_get_array_fixed_n(arg, 4, &items);
|
||||
sPlotStore->setXMin(mp_obj_get_float(items[0]));
|
||||
sPlotStore->setXMax(mp_obj_get_float(items[1]));
|
||||
sPlotStore->setYMin(mp_obj_get_float(items[2]));
|
||||
sPlotStore->setYMax(mp_obj_get_float(items[3]));
|
||||
}
|
||||
|
||||
// Build the return value
|
||||
mp_obj_t coords[4];
|
||||
coords[0] = mp_obj_new_float(sPlotStore->xMin());
|
||||
coords[1] = mp_obj_new_float(sPlotStore->xMax());
|
||||
coords[2] = mp_obj_new_float(sPlotStore->yMin());
|
||||
coords[3] = mp_obj_new_float(sPlotStore->yMax());
|
||||
return mp_obj_new_tuple(4, coords);
|
||||
}
|
||||
|
||||
mp_obj_t modpyplot_plot(mp_obj_t x, mp_obj_t y) {
|
||||
assert(sPlotStore != nullptr);
|
||||
sPlotStore->addDots(x, y);
|
||||
// Ensure x and y are arrays
|
||||
// "Push" x and y on bigger arrays
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modpyplot_show() {
|
||||
MicroPython::ExecutionEnvironment * env = MicroPython::ExecutionEnvironment::currentExecutionEnvironment();
|
||||
env->displayViewController(&sPlotController);
|
||||
env->displayViewController(sPlotController);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#include <py/obj.h>
|
||||
|
||||
mp_obj_t modpyplot___init__();
|
||||
void modpyplot_gc_collect();
|
||||
|
||||
mp_obj_t modpyplot_axis(mp_obj_t arg);
|
||||
mp_obj_t modpyplot_plot(mp_obj_t x, mp_obj_t y);
|
||||
|
||||
// axis(*args, emit=True, **kwargs)
|
||||
//mp_obj_t grid();
|
||||
//mp_obj_t scatter(mp_obj_t x, mp_obj_t y);
|
||||
//mp_obj_t bar();
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
#include "modpyplot.h"
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(modpyplot_plot_obj, modpyplot_plot);
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(modpyplot_show_obj, modpyplot_show);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot___init___obj, modpyplot___init__);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(modpyplot_axis_obj, modpyplot_axis);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(modpyplot_plot_obj, modpyplot_plot);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot_show_obj, modpyplot_show);
|
||||
|
||||
STATIC const mp_rom_map_elem_t modpyplot_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pyplot) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&modpyplot___init___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_axis), MP_ROM_PTR(&modpyplot_axis_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_plot), MP_ROM_PTR(&modpyplot_plot_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&modpyplot_show_obj) },
|
||||
};
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
#ifndef PYTHON_MATPLOTLIB_PLOT_CONTROLLER_H
|
||||
#define PYTHON_MATPLOTLIB_PLOT_CONTROLLER_H
|
||||
|
||||
//#include <escher/view_controller.h>
|
||||
#include <apps/shared/simple_interactive_curve_view_controller.h>
|
||||
#include <apps/shared/curve_view_cursor.h>
|
||||
#include "plot_view.h"
|
||||
#include "plot_store.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Matplotlib {
|
||||
|
||||
class PlotController : public Shared::SimpleInteractiveCurveViewController {
|
||||
public:
|
||||
PlotController() : Shared::SimpleInteractiveCurveViewController(nullptr, &m_cursor), m_store(), m_view(&m_store) {}
|
||||
//virtual View * view() override { return &m_view; }
|
||||
PlotController(PlotStore * store) : Shared::SimpleInteractiveCurveViewController(nullptr, &m_cursor), m_store(store), m_view(m_store) {}
|
||||
|
||||
float cursorBottomMarginRatio() override {
|
||||
return 0.0f;
|
||||
@@ -22,22 +18,16 @@ public:
|
||||
virtual void reloadBannerView() override {
|
||||
}
|
||||
|
||||
bool handleEvent(Ion::Events::Event event) override {
|
||||
printf("EVENT!!\n");
|
||||
return Shared::SimpleInteractiveCurveViewController::handleEvent(event);
|
||||
}
|
||||
|
||||
virtual bool handleEnter() override {
|
||||
printf("ENTER !!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
Shared::CurveView * curveView() override { return &m_view; }
|
||||
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return &m_store; }
|
||||
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return m_store; }
|
||||
private:
|
||||
PlotStore * m_store;
|
||||
Shared::CurveViewCursor m_cursor;
|
||||
PlotStore m_store;
|
||||
PlotView m_view;
|
||||
};
|
||||
|
||||
|
||||
@@ -1 +1,69 @@
|
||||
#include "plot_store.h"
|
||||
|
||||
namespace Matplotlib {
|
||||
|
||||
PlotStore::PlotStore() : Shared::InteractiveCurveViewRange(),
|
||||
m_grid(false)
|
||||
{
|
||||
flush();
|
||||
}
|
||||
|
||||
void PlotStore::flush() {
|
||||
m_dots = mp_obj_new_list(0, nullptr);
|
||||
}
|
||||
|
||||
void PlotStore::addDots(mp_obj_t x, mp_obj_t y) {
|
||||
mp_obj_t items[2] = {x, y};
|
||||
mp_obj_t tuple = mp_obj_new_tuple(2, items);
|
||||
mp_obj_list_append(m_dots, tuple);
|
||||
|
||||
//mp_obj_tuple_t * t = static_cast<mp_obj_tuple_t *>(MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)));
|
||||
//t->items[0] = MP_OBJ_NEW_SMALL_INT(r);
|
||||
}
|
||||
|
||||
PlotStore::Dot PlotStore::dotAtIndex(int i) {
|
||||
size_t numberOfTuples;
|
||||
mp_obj_t * tuples;
|
||||
mp_obj_list_get(m_dots, &numberOfTuples, &tuples);
|
||||
|
||||
mp_obj_t firstTuple = tuples[0];
|
||||
size_t numberOfObjects;
|
||||
mp_obj_t * objects;
|
||||
mp_obj_tuple_get(firstTuple, &numberOfObjects, &objects);
|
||||
|
||||
mp_obj_t x = objects[0];
|
||||
mp_obj_t y = objects[1];
|
||||
|
||||
size_t numberOfX;
|
||||
mp_obj_t * xValues;
|
||||
mp_obj_list_get(x, &numberOfX, &xValues);
|
||||
size_t numberOfY;
|
||||
mp_obj_t * yValues;
|
||||
mp_obj_list_get(y, &numberOfY, &yValues);
|
||||
|
||||
float goodX = mp_obj_get_float(xValues[i]);
|
||||
float goodY = mp_obj_get_float(yValues[i]);
|
||||
|
||||
return PlotStore::Dot(goodX, goodY, KDColorRed);
|
||||
}
|
||||
|
||||
int PlotStore::numberOfDots() {
|
||||
size_t numberOfTuples;
|
||||
mp_obj_t * tuples;
|
||||
mp_obj_list_get(m_dots, &numberOfTuples, &tuples);
|
||||
|
||||
mp_obj_t firstTuple = tuples[0];
|
||||
size_t numberOfObjects;
|
||||
mp_obj_t * objects;
|
||||
mp_obj_tuple_get(firstTuple, &numberOfObjects, &objects);
|
||||
|
||||
mp_obj_t x = objects[0];
|
||||
|
||||
size_t numberOfX;
|
||||
mp_obj_t * xValues;
|
||||
mp_obj_list_get(x, &numberOfX, &xValues);
|
||||
|
||||
return numberOfX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,19 +3,41 @@
|
||||
|
||||
//#include <apps/shared/curve_view_range.h>
|
||||
#include <apps/shared/interactive_curve_view_range.h>
|
||||
extern "C" {
|
||||
#include <py/runtime.h>
|
||||
}
|
||||
|
||||
namespace Matplotlib {
|
||||
|
||||
class PlotStore : public Shared::InteractiveCurveViewRange {
|
||||
public:
|
||||
PlotStore() : Shared::InteractiveCurveViewRange() {}
|
||||
/*
|
||||
float xMin() const override { return 0.0f; }
|
||||
float xMax() const override { return 1.0f; }
|
||||
float yMin() const override { return 0.0f; }
|
||||
float yMax() const override { return 1.0f; }
|
||||
*/
|
||||
PlotStore();
|
||||
void flush();
|
||||
|
||||
class Dot {
|
||||
public:
|
||||
Dot(float x, float y, KDColor color) : m_x(x), m_y(y), m_color(color) {}
|
||||
float x() const { return m_x; }
|
||||
float y() const { return m_y; }
|
||||
KDColor color() const { return m_color; }
|
||||
private:
|
||||
float m_x;
|
||||
float m_y;
|
||||
KDColor m_color;
|
||||
};
|
||||
|
||||
// TODO: Use an iterator here. It will be a lot faster
|
||||
Dot dotAtIndex(int i);
|
||||
int numberOfDots();
|
||||
|
||||
void addDots(mp_obj_t x, mp_obj_t y);
|
||||
|
||||
void setGrid(bool grid) { m_grid = grid; }
|
||||
bool grid() { return m_grid; }
|
||||
private:
|
||||
mp_obj_t m_dots;
|
||||
bool m_grid;
|
||||
|
||||
/*
|
||||
mp_obj_array_t * m_plots;
|
||||
mp_obj_array_t * m_arrows;
|
||||
|
||||
@@ -4,10 +4,17 @@ namespace Matplotlib {
|
||||
|
||||
void PlotView::drawRect(KDContext * ctx, KDRect rect) const {
|
||||
ctx->fillRect(rect, KDColorWhite);
|
||||
drawGrid(ctx, rect);
|
||||
if (m_store->grid()) {
|
||||
drawGrid(ctx, rect);
|
||||
}
|
||||
drawAxes(ctx, rect);
|
||||
drawLabelsAndGraduations(ctx, rect, Axis::Vertical, true);
|
||||
drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, true);
|
||||
|
||||
for (int i=0; i<m_store->numberOfDots(); i++) {
|
||||
PlotStore::Dot dot = m_store->dotAtIndex(i);
|
||||
drawDot(ctx, rect, dot.x(), dot.y(), dot.color());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ namespace Matplotlib {
|
||||
|
||||
class PlotView : public Shared::LabeledCurveView {
|
||||
public:
|
||||
PlotView(PlotStore * s) : Shared::LabeledCurveView(s) {}
|
||||
PlotView(PlotStore * s) : Shared::LabeledCurveView(s), m_store(s) {}
|
||||
void drawRect(KDContext * ctx, KDRect rect) const override;
|
||||
private:
|
||||
PlotStore * m_store;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
#include "py/stackctrl.h"
|
||||
#include "mphalport.h"
|
||||
#include "mod/turtle/modturtle.h"
|
||||
#include "mod/matplotlib/modpyplot.h"
|
||||
}
|
||||
|
||||
static MicroPython::ScriptProvider * sScriptProvider = nullptr;
|
||||
@@ -176,6 +177,7 @@ void gc_collect(void) {
|
||||
gc_collect_start();
|
||||
|
||||
modturtle_gc_collect();
|
||||
modpyplot_gc_collect();
|
||||
|
||||
/* get the registers.
|
||||
* regs is the also the last object on the stack so the stack is bound by
|
||||
|
||||
Reference in New Issue
Block a user