如何在MATLAB中制作带有虚线边框的圆圈图?

时间:2014-10-20 17:16:59

标签: matlab colors plot 2d

所以我有这个代码来获得纬度函数的地球上的径向引力:

G=6.6e-11; 

M=5.976e24; 

N=1000;

r=6371000; 

w=2*pi/(24*3600); 

for i=1:1:360
  Theta=i*pi/180;
  x(i)=i;
  Vi(i)=-G*M/(r*r);
  Phii(i)=r*w*w*sin(Theta)*sin(Theta);
  gr(i)=Vi(i)+Phii(i);
end

plot(x,gr)

运行良好。我想制作一个由边界点(代表角度(i))组成的圆形图,它根据gr的值改变颜色(我想设置gr的值范围,这样如果得到的值落在一个具体类别,该点将具有特定的颜色)。 我对MATLAB真的很陌生。有没有办法做到这一点?

提前致谢。

1 个答案:

答案 0 :(得分:3)

这是我要做的基本算法:

  1. 确定要在绘图中表示的颜色数量。
  2. 创建一个颜色贴图,其中包含您想要计算的多个点。
  3. 确定一个线性增加的向量,该向量从gr的最小值到gr的最大值变化,其中包含您在步骤#2中确定的点数
  4. 对于gr中的每个点:

    一个。在步骤#3中确定哪个点产生该点与矢量的最近距离

    湾用它来索引你想要的颜色。

    ℃。将您的角度转换为笛卡尔坐标,然后使用步骤4b中找到的颜色绘制此点。

  5. 让我们详细解决每一点。


    步骤#1 - 确定您想要的颜色数量

    这很简单。只需确定您想要的颜色数量。现在,让我们假设您需要20种颜色,所以:

    num_colours = 20;
    

    步骤#2 - 创建颜色映射

    我们可以做的是创建一个20 x 3矩阵,其中每行确定一个RGB元组,表示每种颜色占据的红色,绿色和蓝色的数量。 MATLAB具有内置的彩色地图,可以帮助您实现这一目标。以下是MATLAB的所有可用颜色图:

    每个颜色贴图都有一个特殊变量,您可以在其中提供整数,并且它将返回与您提供的数字一样多的行的二维矩阵。每行给出一个RGB三元组,分别表示红色,绿色和蓝色的比例。该矩阵从颜色图(顶行)的开头到结尾(底行)不等。您所要做的就是使用我上面显示的图中所示的任何名称来创建该类型的颜色映射。例如,如果您想获得15分的bones颜色贴图,只需执行以下操作:

    colour_map = bones(15);
    

    如果您想获得25分的jet色彩图,只需执行以下操作:

    colour_map = jet(25);
    

    ....你明白了吗?我喜欢hsv所以让我们使用HSV颜色贴图。你可以使用你想要的任何颜色图,但为了这个例子,让我们坚持使用HSV。

    因此:

    colour_map = hsv(num_colours);
    

    步骤#3 - 获得线性增加的向量

    您希望某些颜色映射到特定范围,这就是此步骤很重要的原因。给定gr中的值,我们想要确定我们要选择哪种颜色,您需要做的就是确定gr中哪个值最接近步骤#中此向量中的值3。因此,您可以使用linspace为您执行此操作:

    bin_vector = linspace(min(gr), max(gr), num_colours);
    

    这将创建一个num_colours 1D数组,此数组的开头以gr的最小值开始,并且最大值变为gr的最大值,每个值均等间隔这样我们就生成了一个num_colours数组。

    步骤#4 - 把它全部带回家

    现在,对于gr中的每个点,我们需要确定哪个点在步骤#3中最接近该向量,然后我们用它来计算出我们想要的颜色,然后我们需要转换我们进入笛卡尔坐标的角度,然后绘制这一点。

    为了便于说明,我将假设您的半径为1.您可以通过简单地x来确定如何获得ycos(theta)坐标和sin(theta),其中theta是您正在检查的角度。由于您的gr阵列有360个插槽,因此我假设每个插槽的分辨率为1度。因此,您可以在for循环中轻松完成此操作。请务必使用hold on,因为我们会多次拨打plot,而且每次拨打plot时我们都不想覆盖该地块。你希望所有的积分留在情节中。

    没有进一步的麻烦:

    figure; %// Create blank figure
    hold on; %// Remember all points
    
    %// For each point in our array...
    for idx = 1 : 360
    
        %// Find the closest slot between gr and our vector in Step #3
        [~,min_idx] = min(abs(gr(idx) - bin_vector));
    
        %// Grab this colour
        clr = colour_map(min_idx,:);
    
        %// Plot the point with this colour
        plot(cosd(idx), sind(idx), '.', 'Color', clr, 'MarkerSize', 10);
    end
    

    注意cosdsind接受作为输入参数,而cossin接受弧度< / strong>即可。另外,请注意我也改变了点的大小,使其更大。使用上面的逻辑和gr中的数组,这就是我得到的:

    enter image description here

    如果您希望半径变大,您所要做的就是将每个cosdsind项与半径相乘。因此,您可以这样做:

    radius = 2;
    
    for idx = 1 : 360
        ... %// Insert colour code here 
        ...
        ...
    
        %// Now plot
        plot(radius*cosd(idx), radius*sind(idx), '.', 'Color', clr, 'MarkerSize', 10);
    end
    

    只需保留相同的代码,但对于plot命令,只需将每个xy值乘以半径即可。


    效率方面的次要说明

    您计算gr数组的方式是使用低效的for循环。在某些情况下(比如我的上面)你需要使用for循环,但是对于简单的计算,没有必要。如果你矢量化它的创建,它会更好。因此,您可以摆脱for循环来计算gr数组,如下所示:

    x = 1 : 360;
    Theta = x*pi/180;
    Phii = r*w*w*sin(Theta).*sin(Theta);
    Vi = -G*M/(r*r);
    gr = Vi + Phii;
    

    x只是一个从1到360的向量,并且在第一行完成。此外,Vi只是一个包含单个值的数组,如果您知道标量和数组之间的操作如何工作,您可以使用此单个值进行添加,并且它将添加每个值这么多你的阵列。因此,无需为Vi创建数组。另外,看看我如何计算Phii。我使用逐个元素的操作,Theta现在是一个数组。您希望创建一个数组Phii,该数组采用Theta的相应值,并将该公式应用于Theta中的每个值,以生成Phii


    希望这会有所帮助。祝你好运!