Upon creating a table, the 'VariablesNames' at the top of each column are automatically bolded. When I check the table in my diary file, each of the column names are surrounded by HTML style strong tags. Is there a line of code I can use to prevent the automatic bolding?
I've had no luck with the MATLAB documentation for fontweights in regards to table titles: https://www.mathworks.com/help/matlab/ref/matlab.ui.control.table-properties.html They mention font weights, but they don't provide an example of how to implement the code. (The strike-through text wasn't relevant documentation for console outputs.)
Here is the command I'm using to create a table: X = array2table(B,'VariableNames', {'y','One','Two','Three'}); The column titles come out bold, for some reason. Worth noting that B is a 5x4 matrix.
I believe that you are mixing things up: the documentation page that you referenced refers to tables displayed in Matlab GUI (using the uitable function), and its FontWeight property refers to the font-weight of the internal data elements displayed in that table.
This is apparently entirely unrelated to what you're actually doing, which is to use a non-GUI data table, such as one that is created using the table function. Such a table is an object which uses an internal overload of the disp function in order to display the table contents in the Matlab console (Command Window). This overloaded disp function displays the table headers using the HTML <Strong> tag. You can see the full source code in matlabroot/toolbox/matlab/datatypes/#tabular/disp.m, and the part that adds the strong tag around line 45.
In short, if you want table output not to use a strong tag in its header, you need to either modify that file, or create your own class that inherits the table tablular class and overloads the disp function in whatever way that you wish.
Addendum: I just discovered an even simpler way:
feature('HotLinks',0); % temporarily disable bolded headers (matlab.internal.display.isHot=false)
disp(myTable)
feature('HotLinks',1); % restore the standard behavior (matlab.internal.display.isHot=true)
In short, if you want table output not to use a strong tag in its
header, you need to either modify that file, or create your own class
that inherits the table class and overloads the disp function in
whatever way that you wish.
Unfortunately the table class is sealed, therefore a subclass cannot inherit from it.
Error using unbold_table
Class 'table' is Sealed and may not be used as a superclass.
You could always go into the source code as Yair suggested and edit it.
As #YairAltman mentions, the bolding is done by the disp method of the table class.
(Actually, that's not quite true: in older versions, it's done by the disp method of the table class, in the more recent versions, it's done by the disp method of the tabular superclass of the table class).
Yair suggests two ideas:
Firstly, that you might be able to create your own class that inherits from table, and implement your own version of disp. Unfortunately, that won't work as table is Sealed, so you can't inherit from it. (Of course, if you're comfortable with modifying the MATLAB source code you could unseal it; but I don't recommend trying that, they've sealed it for very good reasons).
Secondly, that you might be able to modify the source code for the disp method so that it doesn't do the bolding. That would work, but you might not want to fiddle around with the MATLAB source code (and some may have it installed by IT in a way that is read-only anyway).
However, there is a little undocumented feature of the disp method of table/tabular, that may help you here without modifying anything: if you pass in an additional argument to disp, you can turn off the bold.
>> a = table(1,2);
>> disp(a) % the following Var1 and Var2 are bold
Var1 Var2
____ ____
1 2
>> disp(a,false) % the following Var1 and Var2 are not bold
Var1 Var2
____ ____
1 2
The default value for the second argument is true, so to achieve this you need to call disp explicitly with the second argument false.
Related
Background
I'm planning to create a large number of Matlab table objects once, so that I can quickly refer to their contents repeatedly. My understanding is that each table variable/column is treated in copy-on-write manner. That is, if a table column is not modified by a function, then a new copy is not created.
From what I recall of C++ as of 1.5 decades ago, I could ensure that the code for a function does not modify its argument's data by using constant-correctness formalism.
The specific question
I am not using C++ in these days, but I would like to achieve a similar effect of ensuring that the code for my Matlab function doesn't change the data for selected arguments, either inadvertently or otherwise. Does anyone know of a nonburensome way to do this, or just as importantly, whether this is an unrealistic expectation?
I am using R2015b.
P.S. I've web searched and came across various relevant articles, e.g.:
http://www.mathworks.com/matlabcentral/answers/359410-is-it-possible-to-avoid-copy-on-write-behavior-in-functions-yet
http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data
(which I need clarification on to fully understand, but it isn't my priority just now)
However, I don't believe that I am prematurely optimizing. I know that I don't want to modify the tables. I just need a way to enforce that without having to go through contortions like creating a wrapper class.
I've posted this at:
* Stack Overflow
* Google groups
There is no way of making variables constants in MATLAB, except by creating a class with a constant (and static?) member variable. But even then you can do:
t = const_table_class.table;
t(1,1) = 0; % Created and modified a copy!
The reason that a function does not need to mark its inputs as const is because arguments are always passed by value. So a local modification does not modify data in the caller’s workspace. const is something that just doesn’t exist in the MATLAB language.
On the other hand, you can be certain that your data will not be modified by any of the functions you call. Thus, as long as the function that owns the tables does not modify them, they will remain constant. Any function you pass these tables to, if they attempt to modify them, they will create a local copy to be modified. This is only locally a problem. The memory used up by this copy will be freed upon function exit. It will be a bug in the function, but not affect code outside this function.
You can define a handle class that contains a table as it's preperty. Define a property set listener that triggers and generates error/warning when the value of the property changes.
classdef WarningTable < handle
properties (SetObservable)
t
end
methods
function obj = WarningTable(varargin)
obj.t = table(varargin);
addlistener(obj,'t','PreSet',...
#(a,b)warning('table changed!'));
end
end
end
This should generate warning:
mytable = WarningTable;
mytable.t(1,1) = 0;
SETUP Win7 64b, R2015b, 16 GB of RAM, CPU i7-2700
The table() is a fundamental Matlab class which is also sealed, hence I cannot subclass it.
I want to fix some methods of this class and add new ones.
For instance, table.disp() is fundamentally broken, e.g. try NOT disp(table(rand(1e7,1))), or forget the ; in the command window. The variable takes only 76 MB in RAM but the display is unbuffered and it will stall your system!
Can I override methods like table.disp() without writing into matlabroot\toolbox\matlab\datatypes\#table?
Can I extend the table class with a new method under C:\MATLAB\#table\ismatrixlike.m? Why do I get
ismatrixlike(table)
Undefined function 'ismatrixlike' for input arguments of type 'table'.
Obviously, I did
addpath C:\MATLAB\
rehash toolboxcache
I also tried clear all.
The path has (alphabetic) precedence over matlabroot, but is missing a table.m class definition. If I add the native class defition to C:\MATLAB\#table, then I can run my new method (after a clear all). However:
>> methods(table)
Methods for class table:
classVarNames ismatrixlike table varfun
convertColumn renameVarNames unstack
only lists the methods in the new \#table folder, even though (some of) the old methods still work, e.g.
size(table)
This partly solves the problem, since now, the native \#table\private folder is not accessible anymore and therefore many native methods are broken!
Why am I doing this? Because I do not want to wait another 2 years before the table() is fixed. I already lost entire days because I simply forgot a ; in the command window and I cannot force a restart on my pc if it is running multiday simulations, but I have to wait for the disk-swap to end :(.
APPENDIX
More context about disp(table(rand(1e7,1))). This is what happens when I hit it (and luckily I am fast enough to CTRL-C out of it):
The culprit is line 172 of table.disp() which converts the numeric array into a cellstring (with the padding too!):
[cells, err, isLeft] = sprintfc(f, x, b);
After experimenting with several alternatives, I adopted the solution that intereferes the least with Matlab's native #table implementation and it's easily removed if things go awry.
The solution:
copy the whole #table folder, i.e. fullfile(matlabroot,'toolbox','matlab','datatypes','#table'), into a destination where you have write permissions.
I picked the destination to be fullfile(matlabroot,'toolbox','local','myfiles') since I do not have to bother with OS cross-compatibility, i.e. matlabroot takes care of that for me.
paste into the destination your #table folder with the new, overloaded and overriding methods (partially overwriting the copied original files)
add the destination to the matlab path, before the original #table, e.g. addpath your_destination -begin
Effects, pros and cons:
The native #table class/methods are now shadowed, try e.g. which table -all. However, this effect is quite clear, easily detectable and easily removed (delete destintation and remove path);
No weird conflicts between native #table (now shadowed) and new #table;
All methods, new and old, are visible, try methods(table);
Private table methods are accessible...
... but you are forced to use them.
Exposing the new methods (user-implemented) to the private ones requires more maintenance and direct handling of version conflicts in the table implementations.
You need write permissions on some eligible destination.
For those interested about the details, you can look into, https://github.com/okomarov/tableutils. Specifically the install_tableutils (the readme might not be updated).
The following works for me:
Define a modified disp function, say disp_modified.m, as follows, and put it in your path:
function disp_modified(t)
if istable(t)
%// Do whatever you want to display tables
builtin('disp', '''disp'' function intercepted!')
else
%// For non-tables, call `disp` normally
builtin('disp', t)
end
Define disp as a function handle to the modifed function (you can do that in startup.m to always have it by default):
disp = #disp_modified;
After this, in the command window I get
>> disp(1:5)
1 2 3 4 5
>> disp({1 2 3 'bb'})
[1] [2] [3] 'bb'
>> disp(table(rand(1e3,1)))
'disp' function intercepted!
Depending on the usage of the new class perhaps you could follow a cleaner approach. The proposed approach described in your post has the drawback that perhaps code used in your updated environment would not be easily portable to a new environment, or a program executed in your environment may demonstrate different behavior in a different environment.
Some questions you could consider (and perhaps clarify) would be: How do you intend to use the new class? Do you want to replace all the existing table uses? Do you want to be able to use it instead of a table class argument? Or do you want to alter the table so that each usage of the original table class in your environment uses the new class.
If you just need a new improved table for your usage, you could consider encapsulating the original table class in a new class. E.g MyTable, delegate all the methods you do not need to the original table methods, replace the methods you would like to improve or add new ones.
Update: Just saw the complete solution in Github and understood what you intended to do. Nice work. I will leave the post in case anyone finds it useful.
I am looking for a way to handle different type of data in one column of a Matlab uitable.
Usually uitable is used to set whole columns to the same data type, such as logical (gives a checkboxes), char (gives left-aligned text), numeric (gives right-aligned number) or a 1xn-cell-array (gives pop-up menus with different choices).
It is set using the columnformat property of uitable, e.g.
columnformat = {'numeric', 'logical', {'Fixed' 'Adjustable'}}; % 3 columns
You can find an example at matlab documentation.
I am looking for a way to set the format for single cells to realize something like this:
Matlab's uitable is a crippled version of an underlying JIDE table.
It is possible to get to the underlying java (see findjobj in file exchange), but that requires a lot of work. Yair Altman's undocumented matlab site is a good starting place for understanding the java side of matlab.
It sounds like you want something like a property editor, as opposed to a generic UI table -- i.e. properties listed in first column, property value editable in second column. There are a few "off the shelf" versions in the file exchange, which use JIDE:
See propertiesgui, or property-grid for mostly functional examples. The second example is easier to use -- you simply provide a class or struct, and it creates the proper field entry format. The first one offers more choices -- like color boxes, drop downs, etc, but requires you to be more involved in specifying how things behave.
I had the same problem, but in the end it worked by giving the (numeric) cell an (char) initial value. When changing the char value from the UI the format of the cell remained char, although the rest of the column was numeric.
Does any one would know a way of overriding the data tooltip that is shown when hovering over a variable when we are in the Matlab editor ? I have a custom class that is relatively simple and its content could be shown easily in the tool tip, but Matlab insists on saying it is a 1x1 CustomClass, which is nice and all, but it would be more useful if we could make it to show the content of the object in a nice way. Right now, I have to type the name of the variable in the cmd window e.g. when debugging instead of a short hover on the variable name. Nitpicky, but I'd find it interesting ^^
I've tried to dig a bit using undocumented leads on data tooltips, e.g. http://undocumentedmatlab.com/blog/accessing-the-matlab-editor/
http://undocumentedmatlab.com/blog/spicing-up-matlab-uicontrol-tooltips/
But I don't have the final answer, anyone has any ideas ?
The tooltip seems to get its string by using the disp method. Override disp on your class. In the method body, construct your desired string however you want and then call disp on it. In R2012a at least this works for the debugger tooltip.
Note that you'll need to do a clear classes after editing the class to get MATLAB to recognize the overridden disp.
Say I had the following code:
% Cellmode_subfunction_test.m
%% Cell 1
foo(1);
%% Cell 2
foo(2);
%% Definition of the foo subfunction
function foo(num)
disp(['num=' num2str(num)]);
How can test cell 1 and cell 2 with the subfunction defined at the end?
Edit: Basically each of the cells in this example perform some lengthy calculations so I'd like to test and debug them separately. I'm using subfunctions to abstract out and reuse common functionality and since so far this functionality is only used in this particular application I don't really want to place foo in a separate m-file.
Edit(2): I just remembered that I vaguely recall cell mode only working in matlab scripts and not in function m-files and that subfunctions and nested functions are not allowed in such scripts. Thus what I'm asking for is probably not possible.
Although the anonymous function solution given below is perhaps somewhat restrictive as it only allows single expression functions, it did in fact suffice for what I wished to do and hence I've accepted it as a solution to my problem.
CORRECTION:
I misunderstood your use of the word CELL. My apologies. It appears you simply want to define a function at the command line without saving it to a .m file. For this, you can use anonymous functions:
foo = #(num) disp(['num=' num2str(num)]);
Then you can use "foo" as you would any other function.
The way that I normally handle that is by using dbstop somewhere inside of the main function. Then you have access into all of the functions which the main function would normally have access to. If you're working with the ML editor, just use a breakpoint at the first call to foo.
Hope it helps.
Dan