首页/文章/ 详情

Matlab绘图技巧

3年前浏览2829

image.png

 过冷水诚挚邀请你加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载,qq:927550334 

QQ图片20210424105303.png

    过冷水在日常工作中经常需要分析数据的合理性寻找变量之间的规律,自然而然就需要进行图像绘图,通常图像绘制过程中图像设置对数据规律的呈现是有影响的,过冷水近期就遇到了如下两个问题。

image.png 

这幅图是半等高图,大致能够看出来Z<500区间的范围,可是由于0<Z<3500值区间太大,不能够较为精确的给出我们想要区间范围,只能很模糊的给出一个范围值,比如就想清楚判断1000<Z<15000。

image.png 

这是一幅普通的不能再普通的图像,过冷水需要分析自变量和因变量数值之间正负关系,这简单,就像高中生一样需要判断这条线经过哪几个象限,一个函数入门问题,可是根据图像咋眼一看,看不出来经过哪几个象限。如果能够绘制象限图该多好!

本期过冷水就有针对性的给出图像调整方法

计算值区间调整

image.png 

syms B12 B21
S_mixture_sym =(((1176431*B12*log(B12))/(25*((283*B12)/50   581/100)) - (95611*B21^2*log(B21)^2)/(8*(B21/2   1/2)^2) - (453113*B12^2*log(B12)^2)/(40*(B12/2   1/2)^2)   (2415217*B21*log(B21))/(50*((581*B21)/100   283/50))   (453113*B12*log(B12)*(log(B12)/2   1/2))/(10*(B12/2   1/2))   (95611*B21*log(B21)*(log(B21)/2   1/2))/(2*(B21/2   1/2))   6602)^2/11   ((18822896*B12*log(B12))/(625*((283*B12)/125   1162/125)) - (1529776*B21^2*log(B21)^2)/(125*((4*B21)/5   1/5)^2) - (1812452*B12^2*log(B12)^2)/(625*(B12/5   4/5)^2)   (19321736*B21*log(B21))/(625*((1162*B21)/125   283/125))   (1812452*B12*log(B12)*(log(B12)/5   1/5))/(25*(B12/5   4/5))   (95611*B21*log(B21)*((4*log(B21))/5   4/5))/(5*((4*B21)/5   1/5))   4191)^2/11   ((18822896*B12*log(B12))/(625*((1132*B12)/125   581/250)) - (382444*B21^2*log(B21)^2)/(125*(B21/5   4/5)^2) - (7249808*B12^2*log(B12)^2)/(625*((4*B12)/5   1/5)^2)   (19321736*B21*log(B21))/(625*((581*B21)/250   1132/125))   (453113*B12*log(B12)*((4*log(B12))/5   4/5))/(25*((4*B12)/5   1/5))   (382444*B21*log(B21)*(log(B21)/5   1/5))/(5*(B21/5   4/5))   4260)^2/11   ((10587879*B12*log(B12))/(625*((283*B12)/250   5229/500)) - (7744491*B21^2*log(B21)^2)/(1000*((9*B21)/10   1/10)^2) - (4078017*B12^2*log(B12)^2)/(5000*(B12/10   9/10)^2)   (21736953*B21*log(B21))/(1250*((5229*B21)/500   283/250))   (4078017*B12*log(B12)*(log(B12)/10   1/10))/(50*(B12/10   9/10))   (95611*B21*log(B21)*((9*log(B21))/10   9/10))/(10*((9*B21)/10   1/10))   2351)^2/11   ((28234344*B12*log(B12))/(625*((566*B12)/125   1743/250)) - (1720998*B21^2*log(B21)^2)/(125*((3*B21)/5   2/5)^2) - (5437356*B12^2*log(B12)^2)/(625*((2*B12)/5   3/5)^2)   (28982604*B21*log(B21))/(625*((1743*B21)/250   566/125))   (1359339*B12*log(B12)*((2*log(B12))/5   2/5))/(25*((2*B12)/5   3/5))   (191222*B21*log(B21)*((3*log(B21))/5   3/5))/(5*((3*B21)/5   2/5))   6321)^2/11   ((28234344*B12*log(B12))/(625*((849*B12)/125   581/125)) - (1147332*B21^2*log(B21)^2)/(125*((2*B21)/5   3/5)^2) - (8156034*B12^2*log(B12)^2)/(625*((3*B12)/5   2/5)^2)   (28982604*B21*log(B21))/(625*((581*B21)/125   849/125))   (906226*B12*log(B12)*((3*log(B12))/5   3/5))/(25*((3*B12)/5   2/5))   (286833*B21*log(B21)*((2*log(B21))/5   2/5))/(5*((2*B21)/5   3/5))   6356)^2/11   ((10587879*B12*log(B12))/(625*((2547*B12)/250   581/500)) - (860499*B21^2*log(B21)^2)/(1000*(B21/10   9/10)^2) - (36702153*B12^2*log(B12)^2)/(5000*((9*B12)/10   1/10)^2)   (21736953*B21*log(B21))/(1250*((581*B21)/500   2547/250))   (453113*B12*log(B12)*((9*log(B12))/10   9/10))/(50*((9*B12)/10   1/10))   (860499*B21*log(B21)*(log(B21)/10   1/10))/(10*(B21/10   9/10))   2403)^2/11   ((24705051*B12*log(B12))/(625*((849*B12)/250   4067/500)) - (14054817*B21^2*log(B21)^2)/(1000*((7*B21)/10   3/10)^2) - (28546119*B12^2*log(B12)^2)/(5000*((3*B12)/10   7/10)^2)   (50719557*B21*log(B21))/(1250*((4067*B21)/500   849/250))   (3171791*B12*log(B12)*((3*log(B12))/10   3/10))/(50*((3*B12)/10   7/10))   (286833*B21*log(B21)*((7*log(B21))/10   7/10))/(10*((7*B21)/10   3/10))   5516)^2/11   ((24705051*B12*log(B12))/(625*((1981*B12)/250   1743/500)) - (6023493*B21^2*log(B21)^2)/(1000*((3*B21)/10   7/10)^2) - (66607611*B12^2*log(B12)^2)/(5000*((7*B12)/10   3/10)^2)   (50719557*B21*log(B21))/(1250*((1743*B21)/500   1981/250))   (1359339*B12*log(B12)*((7*log(B12))/10   7/10))/(50*((7*B12)/10   3/10))   (669277*B21*log(B21)*((3*log(B21))/10   3/10))/(10*((3*B21)/10   7/10))   5577)^2/11)^(1/2)
row=0.85:0.0001:0.90;%501组数据
rank=0.85:0.0001:0.90;%501组数据
fun=inline(SS);
for i=1:501;
    B12=row(i);
    for j=1:501;
        B21=rank(j);
        S(j,i)=feval(fun,B12,B21);
    end
end
[ROW,RANK]=meshgrid(row,rank);
[m_one,n_one,z_one]=find(S==min(min(S)));
B12=ROW(m_one,n_one);
B21=RANK(m_one,n_one);
figure 
pcolor(ROW,RANK,S);
colorbar
shading interp%伪彩色图
hold on
h3=plot3(ROW(m_one,n_one),RANK(m_one,n_one),S(m_one,n_one),'LineWidth',1.5,'Color','red')
set( h3,'Marker','*','MarkerSize',15)
str = ['min(' num2str(ROW(m_one,n_one)) ',' num2str(RANK(m_one,n_one)) ',' num2str(double(S(m_one,n_one))) ')'];
text(ROW(m_one,n_one)-(max(max(ROW))-min(min(ROW)))/4,RANK(m_one,n_one),str,'FontSize',14,'fontname','楷体','Color','red');
hold off

    图像问题主要出现在取值区间太大,特定区间界限过于模糊,所以过冷水就想能不能缩小图像取值区间,让我们计算值集中在800~1700,这个区间,当区间小了,图像颜色自然就容易分辨。How to do? 过冷水想到一个压缩数据的办法,让我么程序计算值S(i,j)(Zij)做一次if语句判断,小于800的数据赋值为800,大于1700的数据赋值为1700,这样就实现了计算数据的压缩。

image.png 

具体程序为:

syms B12 B21
row=0.85:0.0001:0.90;%501组数据
rank=0.85:0.0001:0.90;%501组数据
fun=inline(SS);
for i=1:501;
    B12=row(i);
    for j=1:501;
        B21=rank(j);
        aimS=feval(fun,B12,B21);
        if aimS >800 & aimS < 1700 
            S(j,i)=aimS;
        elseif aimS < 800
            S(j,i)=800;
        elseif aimS > 1700
            S(j,i)=1700;
        end
    end
end
 
figure 
pcolor(ROW,RANK,S);
colorbar
shading interp%伪彩色图

    使用该方法成功实现了图像区间压缩的目的,可是无法有效的判断1000<Z<1500这个范围,这是因为颜色图设置够合理,如果在1000<Z<1500用比较有代表性的颜色做指标就可以容易判断,适当的修改颜色标签:

image.png 

 经过适当修改后的最终图像:

image.png 

从图像上很容易看出想要的区间范围,这样就可以挑选合适的X,Y范围。该方法在数值运算找合适参数的问题上很实用,有需要的快尝试实用。

十字坐标绘制

image.png 

将图像转换到十字坐标系中,很容易就观测出象限情况,那么究竟怎么实现这样的目的呢?其实本质就是更改坐标系,首先先进行正常绘图

image.png 

x=linspace(-500,300,100);
y=0.3*x-70;
figure1=figure;
subplot1=subplot(1,2,1,'Parent',figure1);
hold(subplot1,'on');
a=plot(x,y,'Parent',subplot1,'LineWidth',3,'Color',[1 0 0]);
hold(subplot1,'off');
set(subplot1,'FontSize',20,'LineWidth',2);

可得到常见图像类型,现在将图像复制subplot2=subplot(1,2,2,'Parent',figure1)中:

subplot2=subplot(1,2,2,'Parent',figure1);
new_fig_handle = copyobj(a,subplot2);

image.png 

这样就可以得到要修改的图像,在subplot2中修改坐标系,对原有坐标系进行隐藏

image.png 

xL=xlim ;
yL=ylim ;
b=subplot2
xt=get(b,'xtick') ;
yt=get(b,'ytick') ;
set(b,'XTick',[],'XColor','w') ;
set(b,'YTick',[],'YColor','w') ;
extend_x = ( xL(2)-xL(1) ) * 0.1 ;
extend_y = ( yL(2)-yL(1) ) * 0.1 ;
xxL = xL   [ -extend_x extend_x] ;
yyL = yL   [ -extend_y extend_y] ;
set(b,'xlim', xxL) ;
set(b,'ylim', yyL) ;
pos = get(b,'Position') ;
box off;
x_shift = abs( yyL(1)/(yyL(2)-yyL(1)) ) ;
y_shift = abs( xxL(1)/(xxL(2)-xxL(1)) ) ;
temp_1 =  axes( 'Position', pos   [ 0 , pos(4) * x_shift , 0 , - pos(4)* x_shift*0.99999 ] ) ;
xlim(xxL) ; 
box off ;
set(temp_1,'XTick',xt,'Color','None','YTick',[]) ;
set(temp_1,'YColor','w') ;

xy轴进行从新绘制

image.png

temp_2 = axes( 'Position', pos   [ pos(3) * y_shift , 0 , -pos(3)* y_shift*0.99999 , 0 ] ) ;
ylim(yyL) ; 
box off ;
set(temp_2,'YTick',yt,'Color','None','XTick',[]) ;
set(temp_2,'XColor','w') ;

基本上已经能够看出线经过那个象限,已经达到目的,为了使得更像十字坐标系,添加十字箭头

image.png 

Base_pos = get(b,'Position') ;
arrow_pos_in_x_dircetion = Base_pos(2) - Base_pos(4) * yyL(1)/(yyL(2)-yyL(1)) ;
arrow_pos_in_y_dircetion = Base_pos(1) - Base_pos(3) * xxL(1)/(xxL(2)-xxL(1)) ;
annotation('arrow',[Base_pos(1) , Base_pos(1) Base_pos(3)] , [arrow_pos_in_x_dircetion , arrow_pos_in_x_dircetion ] , 'Color','k'); 
annotation('arrow',[arrow_pos_in_y_dircetion , arrow_pos_in_y_dircetion ] , [Base_pos(2) , Base_pos(2) Base_pos(4)] , 'Color','k');

    最终完成了坐标系的转换,完美!本期过冷水给大家分享的绘图技巧都是自己在实践应用中发现原有图像不够完美,就想看有没有更好的方法进行修改,于是就思索方法,最终给出合适的解决方案,所以想要能够提升自己的编程设计能力就需要多实践,多思索,自然而然就能够让Matlab的使用变的灵活起来。

图片

        过冷水发表于 仿真秀 平台原创文章,未经授权禁止私自转载,如需转载请需要和作者沟通表明授权声明,未授权文章皆视为侵权行为,必将追责。如果您希望加入Matlab仿真秀官方交流群进行Matlab学习、问题咨询、 Matlab相关资料下载均可加群:927550334。

精品回顾

 matlab绘制农夫过河动态图

分子动力学的原子空间运动轨迹演示编程

过冷水带你用matlab制作演示动画

python批量移动文件&重命名代码分享

过冷水和你分享 matlab读取存储各种文件的方法 文末有独家金曲分享

image.png

附件

50积分Matlab_plot.zip
MATLAB
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2021-11-15
最近编辑:3年前
过冷水
博士 | 讲师 讨论号:927550334
获赞 360粉丝 184文章 107课程 11
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈