如何将AccountingForm应用于TableView而不影响行/列标签?

时间:2011-12-22 05:17:45

标签: wolfram-mathematica

我正在使用M 8.0.4。

我在演示Manipulate []中使用TableView来显示最终解决方案数据,这是一个数值数据矩阵。

TableView非常适合使用,因为它带有一个自动滚动条,可以向下移动行,也可以向右移动到列上,这样就可以看到整个矩阵,同时保持整个显示区域的固定。 (我底部有一张图片)

我无法找到解决方案的问题是,我需要格式化矩阵数据,以便它看起来不错。否则,如果一个数据元素太大而不适合单元格,它将会环绕,使得TableView不对齐。我还需要将小数点调整为其他格式。

我不能将NumberForm和AccountForm应用于数据,然后在结果上应用TableView,因为TableView不喜欢看那些包装器,它需要数字。

但是如果将AccountingForm应用于TableView,那么表示行号和列号的数字(由TableView自动添加)也会被格式化。我也不希望那些格式化。行号应保持整数,而不是浮点数。我只想将数据本身格式化。

我无法想象如何从Table视图中格式化数据。当我使用FullForm查看数据如何保存在TableView中时,我无法想象如何在不破坏TableView的情况下对其进行格式化。

我会显示问题,然后展示我的尝试。

(* make up some data, and make a TableView of it *)
data = {{-1234.8, 0.123}, {0.12345678, 0.1234}}
tbl = TableView[data, ItemSize -> {{3, {8}}}, DefaultBaseStyle -> 11, 
  Spacings -> {.2, .1}, FrameStyle -> Gray]

enter image description here

请注意,行号和列号(已标记)为正整数。

现在,我想格式化数据本身,(下面使用的确切格式选项只是一个例子)

AccountingForm[tbl, {6, 3}, NumberSigns -> {"-", "+"}, 
 NumberPadding -> {"", ""}, SignPadding -> True]

但现在Table行和列也被格式化:

enter image description here

TableView的FullForm是:

In[156]:= FullForm[tbl]
TableView[List[List[-1234.8`,0.123`],List[0.12345678`,0.1234`]],
          Rule[ItemSize,List[List[3,List[8]]]],
          Rule[DefaultBaseStyle,11],Rule[Spacings,List[0.2`,0.1`]],
          Rule[FrameStyle,GrayLevel[0.5`]]]

因此可以使用

拉出TableView中的数据
In[166]:= tbl[[1]]
Out[166]= {{-1234.8,0.123},{0.12345678,0.1234}}

但是当我使用tbl[[1]]更改ReplacePart[]并使用AccountingForm版数据时,TableView不再有效:

formattedData = 
 AccountingForm[data, {6, 3}, NumberSigns -> {"-", "+"}, 
  NumberPadding -> {"", "0"}, SignPadding -> True];

In[245]:= tbl=ReplacePart[tbl,1->formatted]
Out[245]= TableView[{{-1234.8,+0.123},{+0.123,+0.123}},
          ItemSize->{{3,{8}}},DefaultBaseStyle->11,Spacings->{0.2,0.1},
          FrameStyle->GrayLevel[0.5]]

所以,我打破了TableView。因为它不再显示。

问题是:如何格式化进入TableView的数字数据而不影响行/列索引值?

Fyi,这就是TableView在我所拥有的一个Manipulate演示中的样子。请注意自动滚动条。 (在这一篇中,我没有使用NumberForm及其朋友进行格式化。但我所做的并不是非常有效,如果可以,我宁愿使用NumberForm,因此我的问题)

enter image description here

感谢

更新12/22/11 1:30 AM

这是Mike完整的代码示例,以便跟进他的回答

data = {{-1234.8, 0.123}, {0.12345678, 0.1234}};

newData = 
  Map[AccountingForm[#, {6, 3}, NumberSigns -> {"-", "+"}, 
     NumberPadding -> {"", ""}, SignPadding -> True] &, data, {2}];

tbl = TableView[newData, ItemSize -> {{3, {8}}}, Spacings -> {.2, .1},
   FrameStyle -> Gray]

现在我如何使用Cell命令进行上述操作? (这是在Manipulate,而不是笔记本会话,Manipulate在一个单元格中运行。我不能在此代码中制作单独的单元格。但是为了尝试它,我可以在一个新的笔记本中,但实际的代码是将使用此解决方案,必须在没有单元格的Manipulate中运行。

更新12/22/11上午5点

我注意到TableView的某些性能不佳。考虑一下这段代码

Remove["Global`*"];
ClearSystemCache[]
m1 = MemoryInUse[$FrontEnd];
N[m1/10^6]
n = 256;
data = Table[RandomReal[], {n}, {n}];
TableView[data, ContentSize -> {300, 300}]
m2 = MemoryInUse[$FrontEnd] - m1;
N[m2/10^6]

数据本身,假设实数是双倍,仅约半MB。 ByteCount说 由于其他簿记数据结构而导致2 MB。

In[114]:= ByteCount[data]/10^6//N
Out[114]= 2.10948

但是前端似乎使用了更多的RAM(对于整个TableView我的意思不仅仅是数据),有时我得到20 MB,有时甚至更多(一次得到100 MB)。但是如果你在计算机上尝试上述操作,你会发现M很难用这个。我认为可能是表格部分的渲染会导致M花费这么多时间。

我不认为256乘256就是这么大的矩阵。即使使用128乘128,也很难在屏幕上呈现它。一旦启动,它就会很快,使用它也没问题。

看起来TableView还没有很好地优化。我想我只会用它来显示解决方案矩阵的一小部分,因为在演示中使用它来表现整个解决方案并不好,它会使演示看起来很糟糕。

问题是我的解决方案矩阵可能很大,我想要在有限的GUI空间中显示数据。 TableView就是我可以找到的内置滚动条的内容。 Manipulate控件中没有其他东西可以使用,所以我必须使用TableView。

更新12/22/11 4 PM

感谢Mike的提示,我现在正在考虑使用Pane和Scollbars,它比TableView更好用。 (对于大数据来说仍然很慢,但没有TableView那么糟糕)

以下是执行此操作的代码示例:

n = 32;
data = Table[RandomReal[], {n}, {n}];
grid = Grid[data, Spacings -> {.4, .4}, Alignment -> Left, Frame -> All];
grid = Style[NumberForm[grid, {6, 5}], LineBreakWithin -> False];
pane = Pane[grid, ImageSize -> {200}, Scrollbars -> True]

enter image description here

到目前为止我唯一注意到的问题是,当n变大时,Pane生成这个外框,表示生成了非常大的输出。但我确信有一种程序化的方式(在某处可以选择)来解决这个问题,我刚开始看这个,应该能够找到解决这个问题的方法,一旦我喝完咖啡。 (手指交叉)

enter image description here

好消息

"生成非常大的输出"只在笔记本界面出现时。当我将代码放入Manipulate并运行它时,它没有显示此输出框架。所以,我现在很高兴,这个问题已经结束。我从现在开始使用Pane。 (再次感谢Mike)

顺便说一句,要删除有问题的邮件,我发现这是一个有用的链接:

http://forums.wolfram.com/mathgroup/archive/2009/Apr/msg00935.html

但我不需要为我正在做的事情做任何事情。

2 个答案:

答案 0 :(得分:4)

我想这是一个不同的方法,可以作为另一个答案发布,尽管它明显借鉴迈克的回答。

f = ToString @ 
    AccountingForm[#, {6, 3}, NumberSigns -> {"-", "+"}, 
     NumberPadding -> {"", ""}, SignPadding -> True] &;

data = {{-1234.8, 0.123}, {0.12345678, 0.1234}};

TableView[Map[f, data, {2}], ItemSize -> {{3, {8}}}, 
  DefaultBaseStyle -> 11, Spacings -> {.2, .1}, FrameStyle -> Gray]

Mathematica graphics



由于使用ToString不直观,我决定再探讨一下。似乎TableView抑制了字符串中的引号,但只是字符串。 e.g:

string = "\"\"\"test\"";

TableView[{{ string }}]

Mathematica graphics

TableView[{{ {string} }}]

Mathematica graphics

使用2D格式的字符串可以看到其他有趣的行为:

string = "\!\(\*SuperscriptBox[SqrtBox[\"5\"], \"2\"]\)";

TableView[{{ string }}]

Mathematica graphics

TableView[{{ {string} }}]

Mathematica graphics

答案 1 :(得分:3)

一个建议:

首先将数据中的每个元素都放入AccountingForm或您想要的任何格式:

f = AccountingForm[#, {6, 3}, NumberSigns -> {"-", "+"}, 
   NumberPadding -> {"", ""}, SignPadding -> True] &

newdata = {f[#[[1]]], f[#[[2]]]} & /@ data

请注意,我做了一点大脑褪色。我确信有一种比Mapping更简单的方法(编辑:大脑褪色让我忘记了levelspec)。这将为您提供如下输出:

enter image description here

问题当然是你现在有字符串字符显示和“常规”尝试关闭失败(“常规”==选项检查器,Style[]等)。但是您可以通过修改Core.nb样式表中存在的两种样式来解决此问题。因此,您需要编辑当前笔记本中的私有样式 - 并从代码中删除DefaultBaseStyle,因为它会导致与样式表样式冲突。所以格式>编辑样式表并添加此样式:

Cell[StyleData["TableViewItemExpression"],
 ShowStringCharacters->False,
 TemplateBoxOptions->{DisplayFunction->(StyleBox[#, Deployed -> False]& )}]

实际上这真的是你需要做的所有事情,但如果你后来想要对数字做一些额外的样式,那么你需要修改一个不同的风格。以下是将数字设为红色的示例:

Cell[StyleData["TableViewGrid"],
 ContextMenu->FEPrivate`FrontEndResource["ContextMenus", "TableView"],
 ShowAutoStyles->False,
 AutoSpacing->False,
 ShowStringCharacters->False,
 AutoNumberFormatting->True,
 LineIndent->0,
 FontWeight->"Plain",
 FontColor->RGBColor[1, 0, 0]]

这就是它的样子:

enter image description here