尝试将颜色贴图应用于MATLAB中的条形图

时间:2017-11-07 02:44:44

标签: matlab

我有一组数据,我试图将其绘制为直方图。另外,我想根据x轴位置为各个条纹着色。 CData,这里描述似乎做了我想要的但我无法让它发挥作用。

这是我的代码:

h = bar(new_edge,N,'hist','FaceColor','flat');
hold on

for n = 1:length(N)
    if (x - x/1.09) - (x-1) > 0
        probability(n) = 1 - ((x-x/1.09) - (x-1))/((x - 1/1.09)+(x/0.91 - x)); 
    else
        probability(n) = 1;
    end

    color_num = 30;
    cm = jet(color_num);
    min = 0.5450;
    max = 1;

    color_map_index = floor(1 + (probability(n) - min)/(max-min)*(color_num-1));
    rbg = cm(color_map_index,:);

    h.CData(n,:) = rbg;

end

与MATLAB示例类似,我首先创建条形图。接下来,我想循环并根据计算为每个条形图规定颜色。我这样做是通过使用#bins和min / max创建一个colormap,获取颜色索引,然后最终检索rbg值。当我尝试应用颜色时出现以下错误:

下标索引必须是实数正整数或逻辑。

h.CData(n,:) = rbg;

如果我潜入h对象,MATLAB告诉我CData的大小为(4x65)。这里发生了什么? new_edgeN都是1x65个向量。

3 个答案:

答案 0 :(得分:2)

您是否确定您所获得的错误(“下标索引必须是正整数或逻辑”)来自以下行?:

h.CData(n,:) = rbg;

由于我们知道n是一个大于或等于1的正整数,因此这里的索引应该没有问题。您的错误更可能来自其上方的行(即color_map_index的值小于1)。我会仔细检查你的计算方式color_map_index

您还可以尝试使用function notation(即getset)代替dot notation来更新媒体资源:

cData = get(h, 'CData');
cData(n, :) = rbg;
set(h, 'CData', cData);

顺便说一下,你也不应该给你的变量和现有的函数同名,就像你在这里做的那样:

...
min = 0.5450;
max = 1;
...

这会影响内置的minmax函数can also lead to the same error message under other conditions。绝对重命名那些。

如果您在尝试修复后仍然遇到问题,可以尝试使用索引颜色映射设置颜色,如one of my other answers(靠近底部)所示。举一个简单的例子,下面绘制了20个30个不同可能值的条形图,然后根据它们的高度对它们进行着色:

color_num = 30;
N = randi(color_num, 1, 20);
hBar = bar(N, 'hist');
colormap(parula(color_num));
set(hBar, 'CData', N, 'CDataMapping', 'direct');

情节:

enter image description here

答案 1 :(得分:0)

这可能是您的Matlab版本的问题。 当我在2017b上用条形测试CData时,这可行:

openExample('graphics/ControlIndividualBarColorsExample')

当我在2017a上试用它时,它不会运行。 该示例是否有效?

答案 2 :(得分:0)

鉴于这是版本控制问题,实际上并不是一个干净的解决方案。如果其他人提出类似问题且版本相同,这里的解决方法在2017a中对我有用。

您可以简单地绘制矩形,而不是创建条形图。这很麻烦,但它确实产生了所需的result

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class ApiAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAuthenticated)
        {
            int httpCode = (int)System.Net.HttpStatusCode.Unauthorized;
            filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
            filterContext.HttpContext.Response.StatusCode = 200;
            filterContext.HttpContext.Response.ContentType = "application/json";
            filterContext.HttpContext.Response.Write(JsonConvert.SerializeObject(
                new BaseResource(false, httpCode, "Request Forbidden. You must first login!")
                )
            );

            filterContext.Result = new HttpStatusCodeResult(200);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }                
    }
}