From e2c06cbb446146f7d8df248a6d0f4025da76eb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 18 May 2020 10:50:12 +0200 Subject: [PATCH] [python] matplotlib: add color argument to plot, scatter, hist, bar and arrow --- .../port/mod/matplotlib/pyplot/modpyplot.cpp | 39 ++++++++++++------- python/port/mod/matplotlib/pyplot/modpyplot.h | 2 +- .../mod/matplotlib/pyplot/modpyplot_table.c | 10 ++--- python/test/matplotlib.cpp | 5 +++ 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/python/port/mod/matplotlib/pyplot/modpyplot.cpp b/python/port/mod/matplotlib/pyplot/modpyplot.cpp index e6a78d470..196e715b6 100644 --- a/python/port/mod/matplotlib/pyplot/modpyplot.cpp +++ b/python/port/mod/matplotlib/pyplot/modpyplot.cpp @@ -50,6 +50,16 @@ static size_t extractArgumentAndValidateSize(mp_obj_t arg, size_t requiredlength return itemLength; } +// Get color from arguments if possible + +KDColor colorFromOptionalArgumentAtIndex(size_t n_args, const mp_obj_t * args, size_t colorIndex) { + if (n_args > colorIndex) { + return MicroPython::Color::Parse(args[colorIndex]); + } else { + return Palette::nextDataColor(&paletteIndex); + } +} + // Internal functions mp_obj_t modpyplot___init__() { @@ -79,15 +89,15 @@ void modpyplot_flush_used_heap() { } } -/* arrow(x,y,dx,dy) +/* arrow(x,y,dx,dy, color) * x, y, dx, dy scalars * */ mp_obj_t modpyplot_arrow(size_t n_args, const mp_obj_t *args) { - assert(n_args == 4); + assert(n_args >= 4); assert(sPlotStore != nullptr); - KDColor color = Palette::nextDataColor(&paletteIndex); + KDColor color = colorFromOptionalArgumentAtIndex(n_args, args, 4); sPlotStore->addSegment(args[0], args[1], mp_obj_float_binary_op(MP_BINARY_OP_INPLACE_ADD, mp_obj_get_float(args[0]), args[2]), mp_obj_float_binary_op(MP_BINARY_OP_INPLACE_ADD, mp_obj_get_float(args[1]), args[3]), color, true); return mp_const_none; } @@ -143,7 +153,7 @@ mp_obj_t modpyplot_axis(size_t n_args, const mp_obj_t *args) { return mp_obj_new_tuple(4, coords); } -/* bar(x, height, width, bottom) +/* bar(x, height, width, bottom, color) * 'x', 'height', 'width' and 'bottom' can either be a scalar or an array/tuple of * scalar. * 'width' default value is 0.8 @@ -184,7 +194,7 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args) { bItems[0] = mp_obj_new_float(0.0f); } - KDColor color = Palette::nextDataColor(&paletteIndex); + KDColor color = colorFromOptionalArgumentAtIndex(n_args, args, 4); for (size_t i=0; i 1 ? i : 0]; mp_obj_t iW = wItems[wLength > 1 ? i : 0]; @@ -219,7 +229,7 @@ mp_obj_t modpyplot_grid(size_t n_args, const mp_obj_t *args) { return mp_const_none; } -/* hist(x, bins) +/* hist(x, bins, color) * 'x' array * 'bins': (default value 10) * - int (number of bins) @@ -298,25 +308,26 @@ mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args) { binIndex++; } - KDColor color = Palette::nextDataColor(&paletteIndex); + KDColor color = colorFromOptionalArgumentAtIndex(n_args, args, 2); for (size_t i=0; iaddRect(edgeItems[i], edgeItems[i+1], binItems[i], mp_obj_new_float(0.0), color); } return mp_const_none; } -/* scatter(x, y) +/* scatter(x, y, color) * - x, y: list * - x, y: scalar * */ -mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y) { +mp_obj_t modpyplot_scatter(size_t n_args, const mp_obj_t *args) { assert(sPlotStore != nullptr); mp_obj_t * xItems, * yItems; - size_t length = extractArgumentsAndCheckEqualSize(x, y, &xItems, &yItems); + assert(n_args >= 2); + size_t length = extractArgumentsAndCheckEqualSize(args[0], args[1], &xItems, &yItems); - KDColor color = Palette::nextDataColor(&paletteIndex); + KDColor color = colorFromOptionalArgumentAtIndex(n_args, args, 2); for (size_t i=0; iaddDot(xItems[i], yItems[i], color); } @@ -324,7 +335,7 @@ mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y) { return mp_const_none; } -/* plot(x, y) plots the curve (x, y) +/* plot(x, y) plots the curve (x, y, color) * plot(y) plots the curve x as index array ([0,1,2...],y) * */ @@ -342,11 +353,11 @@ mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args) { xItems[i] = mp_obj_new_float((float)i); } } else { - assert(n_args == 2); + assert(n_args >= 2); length = extractArgumentsAndCheckEqualSize(args[0], args[1], &xItems, &yItems); } - KDColor color = Palette::nextDataColor(&paletteIndex); + KDColor color = colorFromOptionalArgumentAtIndex(n_args, args, 2); for (int i=0; i<(int)length-1; i++) { sPlotStore->addSegment(xItems[i], yItems[i], xItems[i+1], yItems[i+1], color, false); } diff --git a/python/port/mod/matplotlib/pyplot/modpyplot.h b/python/port/mod/matplotlib/pyplot/modpyplot.h index 8ab760f73..a32e0905e 100644 --- a/python/port/mod/matplotlib/pyplot/modpyplot.h +++ b/python/port/mod/matplotlib/pyplot/modpyplot.h @@ -10,6 +10,6 @@ mp_obj_t modpyplot_bar(size_t n_args, const mp_obj_t *args); mp_obj_t modpyplot_grid(size_t n_args, const mp_obj_t *args); mp_obj_t modpyplot_hist(size_t n_args, const mp_obj_t *args); mp_obj_t modpyplot_plot(size_t n_args, const mp_obj_t *args); -mp_obj_t modpyplot_scatter(mp_obj_t x, mp_obj_t y); +mp_obj_t modpyplot_scatter(size_t n_args, const mp_obj_t *args); mp_obj_t modpyplot_text(mp_obj_t x, mp_obj_t y, mp_obj_t s); mp_obj_t modpyplot_show(); diff --git a/python/port/mod/matplotlib/pyplot/modpyplot_table.c b/python/port/mod/matplotlib/pyplot/modpyplot_table.c index 1f4c3152b..78b7f5d2f 100644 --- a/python/port/mod/matplotlib/pyplot/modpyplot_table.c +++ b/python/port/mod/matplotlib/pyplot/modpyplot_table.c @@ -1,13 +1,13 @@ #include "modpyplot.h" STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot___init___obj, modpyplot___init__); -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_arrow_obj, 4, 4, modpyplot_arrow); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_arrow_obj, 4, 5, modpyplot_arrow); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_axis_obj, 0, 1, modpyplot_axis); -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_bar_obj, 2, 4, modpyplot_bar); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_bar_obj, 2, 5, modpyplot_bar); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_grid_obj, 0, 1, modpyplot_grid); -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_hist_obj, 1, 2, modpyplot_hist); -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_plot_obj, 1, 2, modpyplot_plot); -STATIC MP_DEFINE_CONST_FUN_OBJ_2(modpyplot_scatter_obj, modpyplot_scatter); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_hist_obj, 1, 3, modpyplot_hist); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_plot_obj, 1, 3, modpyplot_plot); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modpyplot_scatter_obj, 2, 3, modpyplot_scatter); STATIC MP_DEFINE_CONST_FUN_OBJ_0(modpyplot_show_obj, modpyplot_show); STATIC MP_DEFINE_CONST_FUN_OBJ_3(modpyplot_text_obj, modpyplot_text); diff --git a/python/test/matplotlib.cpp b/python/test/matplotlib.cpp index b673d63ca..60b642ff0 100644 --- a/python/test/matplotlib.cpp +++ b/python/test/matplotlib.cpp @@ -35,6 +35,7 @@ QUIZ_CASE(python_matplotlib_pyplot_arrow) { TestExecutionEnvironment env = init_environement(); assert_command_execution_succeeds(env, "from matplotlib.pyplot import *"); assert_command_execution_succeeds(env, "arrow(2,3,4,5)"); + assert_command_execution_succeeds(env, "arrow(2,3,4,5, \"#FF00FF\")"); assert_command_execution_succeeds(env, "show()"); deinit_environment(); } @@ -59,6 +60,7 @@ QUIZ_CASE(python_matplotlib_pyplot_bar) { assert_command_execution_succeeds(env, "bar([],[])"); assert_command_execution_succeeds(env, "bar([1,2,3],[1,2,3],2,3)"); assert_command_execution_succeeds(env, "bar([1,2,3],[1,2,3],[1,2,3],[1,2,3])"); + assert_command_execution_succeeds(env, "bar([1,2,3],[1,2,3],[1,2,3],[1,2,3], \"orange\")"); assert_command_execution_succeeds(env, "show()"); assert_command_execution_fails(env, "bar([1,2,3],[1,2,3,4],[1,2,3],[1,2,3])"); deinit_environment(); @@ -79,6 +81,7 @@ QUIZ_CASE(python_matplotlib_pyplot_hist) { assert_command_execution_succeeds(env, "hist([2,3,4,5,6],23)"); assert_command_execution_succeeds(env, "hist([2,3,4,5,6],[0,2,3])"); assert_command_execution_succeeds(env, "hist([2,3,4,5,6],[0,2,3, 4,5,6,7])"); + assert_command_execution_succeeds(env, "hist([2,3,4,5,6],[0,2,3, 4,5,6,7], (0,255,0))"); assert_command_execution_succeeds(env, "show()"); deinit_environment(); } @@ -89,6 +92,7 @@ QUIZ_CASE(python_matplotlib_pyplot_plot) { assert_command_execution_succeeds(env, "plot([2,3,4,5,6])"); assert_command_execution_succeeds(env, "plot(2,3)"); assert_command_execution_succeeds(env, "plot([2,3,4,5,6],[3,4,5,6,7])"); + assert_command_execution_succeeds(env, "plot([2,3,4,5,6],[3,4,5,6,7], \"g\")"); assert_command_execution_succeeds(env, "show()"); assert_command_execution_fails(env, "plot([2,3,4,5,6],2)"); deinit_environment(); @@ -99,6 +103,7 @@ QUIZ_CASE(python_matplotlib_pyplot_scatter) { assert_command_execution_succeeds(env, "from matplotlib.pyplot import *"); assert_command_execution_succeeds(env, "scatter(2,3)"); assert_command_execution_succeeds(env, "scatter([2,3,4,5,6],[3,4,5,6,7])"); + assert_command_execution_succeeds(env, "scatter([2,3,4,5,6],[3,4,5,6,7], (0,0,255))"); assert_command_execution_succeeds(env, "show()"); assert_command_execution_fails(env, "scatter([2,3,4,5,6],2)"); deinit_environment();