我正在使用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]
请注意,行号和列号(已标记)为正整数。
现在,我想格式化数据本身,(下面使用的确切格式选项只是一个例子)
AccountingForm[tbl, {6, 3}, NumberSigns -> {"-", "+"},
NumberPadding -> {"", ""}, SignPadding -> True]
但现在Table行和列也被格式化:
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
,因此我的问题)
感谢
更新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]
到目前为止我唯一注意到的问题是,当n变大时,Pane生成这个外框,表示生成了非常大的输出。但我确信有一种程序化的方式(在某处可以选择)来解决这个问题,我刚开始看这个,应该能够找到解决这个问题的方法,一旦我喝完咖啡。 (手指交叉)
好消息
"生成非常大的输出"只在笔记本界面出现时。当我将代码放入Manipulate并运行它时,它没有显示此输出框架。所以,我现在很高兴,这个问题已经结束。我从现在开始使用Pane。 (再次感谢Mike)
顺便说一句,要删除有问题的邮件,我发现这是一个有用的链接:
http://forums.wolfram.com/mathgroup/archive/2009/Apr/msg00935.html
但我不需要为我正在做的事情做任何事情。
答案 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]
由于使用ToString
不直观,我决定再探讨一下。似乎TableView
抑制了字符串中的引号,但只是字符串。 e.g:
string = "\"\"\"test\"";
TableView[{{ string }}]
TableView[{{ {string} }}]
使用2D格式的字符串可以看到其他有趣的行为:
string = "\!\(\*SuperscriptBox[SqrtBox[\"5\"], \"2\"]\)";
TableView[{{ string }}]
TableView[{{ {string} }}]
答案 1 :(得分:3)
一个建议:
首先将数据中的每个元素都放入AccountingForm
或您想要的任何格式:
f = AccountingForm[#, {6, 3}, NumberSigns -> {"-", "+"},
NumberPadding -> {"", ""}, SignPadding -> True] &
newdata = {f[#[[1]]], f[#[[2]]]} & /@ data
请注意,我做了一点大脑褪色。我确信有一种比Mapping更简单的方法(编辑:大脑褪色让我忘记了levelspec)。这将为您提供如下输出:
问题当然是你现在有字符串字符显示和“常规”尝试关闭失败(“常规”==选项检查器,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]]
这就是它的样子: