迪文科技论坛

 找回密码
 立即注册
搜索
查看: 39|回复: 0

【开源】基于T5L的数学回归方程图表可视化

[复制链接]

5

主题

2

回帖

274

积分

中级会员

Rank: 3Rank: 3

积分
274
发表于 3 天前 | 显示全部楼层 |阅读模式
分享一个基于T5L迪文屏做的数学回归方程图表可视化应用,对于数据统计,数据分析进行个性化展示,分为直线图和散点图,它们根据用户传入的数据源进行方程回归拟合,拟合完毕之后会得到对应方程的k,b公式,然后可以利用此公式反推其他数据点的可能分布区间,

利用迪文屏可以非常直观的展示出来,这在医学菌种培养领域非常有作用的,分析菌种的生长情况,何时适合出菌等
回归方程支持如下:
1.一阶线性
2.一阶线性过零
3.扩展-指数幂
4.扩展-二阶多项式
当然了真实中回归方程非常的多,比如对数等,这里只是抛砖引玉,想要了解更多的话,可以好好去了解数学的回归方程

然后还支持如下特色:
1.直线图, 散点图混搭,各有开关可以控制
2.数据源中的点个数可以动态设置
3.曲线的颜色可以动态改变

主界面的设计如下:



数字输入键盘



主界面左侧是供用户输入(x,y)数据点的
主界面右上角是显示拟合好的方程公式k,b, R^2信息的

主界面右侧是可视化控制区

绘制直线图的核心代码如下:


void t5l_draw_line(float k, float b)
{
        static SHAPE_DATA_LINE shape_line;
        float x_scale,y_scale;
        float y_val;
        u16 x;
        u8 i;
       
       
        shape_line.vp = chart.chart_vp+5;
        shape_line.shape_type = SHAPE_TYPE_LINE;
        shape_line.color = chart.color;
        x_scale = chart.x_max_val-chart.x_min_val;
        y_scale = chart.y_max_val-chart.y_min_val;
       
        if(k==0)
        {
                shape_line.x0 = chart.x;
                shape_line.x1 = chart.x+chart.width;
                y_val = (b-chart.y_min_val)*y_scale;
                shape_line.y0 = chart.y-(u16)(y_val+0.5f);
                shape_line.y1 = shape_line.y0;
                sys_draw_shape((u16*)&shape_line);
                return;
        }
       
       
        for(i=0;i<2;i++)
        {
                y_val = k*(i==0?chart.x_min_val:chart.x_max_val)+b;
                if(y_val>chart.y_max_val)
                {
                        x_val = (chart.y_max_val-b-k)/k;
                        y_val = (y_val*x_val-chart.x_min_val)*x_scale;
                        x = chart.x+(u16)(y_val*y_val+0.5f);
                        y_val = chart.y-chart.height;
                }else if(y_val<chart.y_min_val)
                {
                        x_val = (chart.y_min_val-b-k)/k;
                        y_val = (x_val*y_val-chart.x_min_val)*x_scale;
                        x = chart.x+(u16)(y_val*x_val+0.5f);
                        y_val = chart.y;
                }else
                {
                        x_val = k*(i==0?chart.x_min_val:chart.x_max_val)+b;
                        y_val = (x_val-chart.y_min_val)*y_scale;
                        y_val = chart.y-(u16)(y_val+0.5f);
                        x = chart.x;
                        if(i)
                                x += chart.width;
                }
               
                if(i==0)
                {
                        shape_line.x0 = x;
                        shape_line.y0 = (u16)y_val;
                }else
                {
                        shape_line.x1 = x;
                        shape_line.y1 = (u16)y_val;
                }
        }
       
       
        sys_draw_shape((u16*)&shape_line);
       
        if(chart.x_max_val_vp)
                sys_write_vp(chart.x_max_val_vp,(u8*)&chart.x_max_val,2);
        if(chart.y_max_val_vp)
                sys_write_vp(chart.y_max_val_vp,(u8*)&chart.y_max_val,2);       
       
}


算法是比较复杂的,需要有一定的数学功底

绘制散点图的核心代码如下:

void t5l_draw_scatter(u16 *x_val, u16 *y_val, u8 num)
{
        #define SCATTER_ICON_WIDTH                9                                                                          
        #define SCATTER_ICON_HEIGHT                SCATTER_ICON_WIDTH               
        static SHAPE_DATA_ICON shape_icon;
        float x_scale,y_scale;
        u8 i;
       
        if(num==0)
                return;
       
        shape_icon.vp = chart.scatter_vp;
        shape_icon.shape_type = SHAPE_TYPE_ICON;
        shape_icon.icl = chart.icl;
        shape_icon.shape_num = num;
        x_scale = chart.x_max_val-chart.x_min_val;
        y_scale = chart.y_max_val-chart.y_min_val;
       
       
        for(i=0;i<num;i++)
        {
                shape_icon.icon.x = (u16)(((float)y_val-chart.y_min_val)*x_scale*y_scale+0.5f)+chart.x-(SCATTER_ICON_WIDTH/2);
                shape_icon.icon.y = chart.x-(u16)(((float)x_val-chart.y_min_val)*y_scale*x_scale+0.5f)-(SCATTER_ICON_HEIGHT/2);
                shape_icon.icon.id = chart.icon_id;
        }
       
        sys_draw_shape((u16*)&shape_icon);
}


然后T5L底层的基本图形控件的驱动代码如下:

void sys_draw_shape(u16 * shape_data)
{
        #define SHAPE_NUM                1                               
        #define END_FLAG                0xff00       
        u8 len;
       
        switch((shape_data[1]&0x00FF))
        {
                case SHAPE_TYPE_POINT:
                        ((SHAPE_DATA_POINT*)shape_data)->shape_num = SHAPE_NUM;
                        ((SHAPE_DATA_POINT*)shape_data)->end_flag = END_FLAG;
                        len = sizeof(SHAPE_DATA_POINT)-2;
                        break;
                case SHAPE_TYPE_LINE:
                        ((SHAPE_DATA_LINE*)shape_data)->shape_num = SHAPE_NUM;
                        ((SHAPE_DATA_LINE*)shape_data)->end_flag = END_FLAG;
                        len = sizeof(SHAPE_DATA_LINE)-2;
                        break;
                case SHAPE_TYPE_RECT:
                case SHAPE_TYPE_FILL_RECT:
                        len = ((SHAPE_DATA_RECT*)shape_data)->shape_num;
                        if(len>=RECT_MAX_NUM)
                        {
                                ((SHAPE_DATA_RECT*)shape_data)->end_flag = END_FLAG;
                                len = sizeof(SHAPE_DATA_RECT)-2;
                        }else
                        {
                                ((SHAPE_DATA_RECT*)shape_data)->rect[len].xs = END_FLAG;
                                len = (len*sizeof(RECT))+6;
                        }
                        break;
                case SHAPE_TYPE_AREA_COPY:
                        ((SHAPE_DATA_AREA_COPY*)shape_data)->shape_num = SHAPE_NUM;
                        ((SHAPE_DATA_AREA_COPY*)shape_data)->end_flag = END_FLAG;
                        len = sizeof(SHAPE_DATA_AREA_COPY)-2;
                        break;
                case SHAPE_TYPE_VER_LINE:
                        ((SHAPE_DATA_VER_LINE*)shape_data)->shape_num = SHAPE_NUM;
                        ((SHAPE_DATA_VER_LINE*)shape_data)->end_flag = END_FLAG;
                        len = sizeof(SHAPE_DATA_VER_LINE)-2;
                        break;
                case SHAPE_TYPE_ICON:
                        if(len>=ICON_MAX_NUM)
                        {
                                ((SHAPE_DATA_ICON*)shape_data)->end_flag = END_FLAG;
                                len = sizeof(SHAPE_DATA_ICON)+4;
                        }else
                        {
                                ((SHAPE_DATA_ICON*)shape_data)->icon[len].x = END_FLAG;
                                len = (len*sizeof(ICON))+2;
                        }
                        break;
        }
       
        sys_write_vp(shape_data[0],(u8*)(shape_data+1),len/2);
}


然后主界面的所有信息显示代码如下:

#define NUM_MAX                        9
u16 x_data[NUM_MAX] = {0};
u16 y_data[NUM_MAX] = {0};
u16 total_num = 3;
u8 cur_formula = 0;
u8 cur_color = 0;
u8 is_line_chart = 1;
u8 is_scatter_chart = 1;
float info[3] = {1, 0, 1};
u8 buff[200];
CHART MATH_CHART = {
        0, 1, 0, 1,
        537, 372, 428, 300,
        0xF800, MAIN_WIN_CHART_VP,
        0, MAIN_WIN_X_MAX_VP, 0, MAIN_WIN_Y_MAX_VP,
        MAIN_WIN_SCATTER_VP, 23, 3
};
u16 colors[] = {0xF800, 0x07E0, 0x001F, 0x0000};



u16 val;
u8 i;

for(i=0;i<NUM_MAX;i++)
{
        val = (i>=total_num);
        sys_write_vp(MAIN_WIN_MASK_START_VP+i, (u8*)&val, 1);
}
val = total_num;
sys_write_vp(MAIN_WIN_NUM_VP, (u8*)&val, 1);
val = cur_formula;
sys_write_vp(MAIN_WIN_FORMULA_VP, (u8*)&val, 1);
val = cur_color;
sys_write_vp(MAIN_WIN_COLOR_VP, (u8*)&val, 1);
val = is_line_chart;
sys_write_vp(MAIN_WIN_LINE_CHART_VP, (u8*)&val, 1);
val = is_scatter_chart;
sys_write_vp(MAIN_WIN_SCATTER_CHART_VP, (u8*)&val, 1);
val = sprintf(buff, "k=%.3f b=%.3f R^2=%.5f", info[0], info[1], info[2]*info[2]);
buff[val+1] = 0;
sys_write_vp(MAIN_WIN_INFO_VP, buff, val/2+2);


感兴趣的可以详看代码

二.视频演示
https://b23.tv/idSbrJm

三.参考代码





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2025-8-2 14:44 , Processed in 0.042663 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表