bugGNU Octave - Bugs: bug #57523, [Feature Request] legend should...

 
 

bug #57523: [Feature Request] legend should accept 2-letter abbreviations for "Location" property

Submitter:  Rik <rik5>
Submitted:  Thu 02 Jan 2020 11:11:31 PM UTC
   
 
Category:  Octave Function Severity:  1 - Wish
Priority:  5 - Normal Item Group:  Feature Request
Status:  Confirmed Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sun 16 May 2021 01:23:44 PM UTC, comment #7: 

I think it would be well possible to list all valid acronyms for the location property, if we limit ourself to the most useful acronyms and not try to achieve perfect Matlab compatibility here.

This is my suggestion for a list of those "useful acronyms":


# assumption: capital letters converted to small letters anyways
# strategy: put spaces only between proper words
# option: skip the "shortened" strings
strings_north = {"n", "north"};
strings_northoutside = {"no", "northoutside", "north outside", ...
   "northo", "northou", "northout", "northouts", "northoutsi", "northoutsid", ...    # <- skip those?
   "north o", "north ou", "north out", "north outs", "north outsi", "north outsid"... # <- skip those?
   };
strings_northeast = {"ne", "northeast", "north east"};
strings_northeastoutside = {"neo", "northeastoutside", ...
    "north east outside", "northeast outside", "north eastoutside", ...
    "northeasto", "northeastou", "northeastout", "northeastouts", "northeastoutsi", "northeastoutsid", ... # <- skip those?
    "north easto",  "north eastou", "north eastout", "north eastouts", "north eastoutsi", "north eastoutsid", ... # <- skip those?
    "north east o",  "north east ou", "north east out", "north east outs", "north east outsi", "north east outsid", ... # <- skip those?
    "northeast o",  "northeast ou", "northeast out", "northeast outs", "northeast outsi", "northeast outsid", ... # <- skip those?
    };
strings_northwest = {"nw", "northwest", "north west"};
strings_northwestoutside = {"nwo", "northwestoutside", ...
    "north west outside", "northwest outside", "north westoutside", ...
    "northwesto", "northwestou", "northwestout", "northwestouts", "northwestoutsi", "northwestoutsid", ... # <- skip those?
    "north westo",  "north westou", "north westout", "north westouts", "north westoutsi", "north westoutsid", ... # <- skip those?
    "north west o",  "north west ou", "north west out", "north west outs", "north west outsi", "north west outsid", ... # <- skip those?
    "northwest o",  "northwest ou", "northwest out", "northwest outs", "northwest outsi", "northwest outsid", ... # <- skip those?
    };
#west
#westoutside
#east
#eastoutside
#south
#southoutside
#southeast
#southeastoutside
#southwest
#southwestoutside
#best
#bestoutside
#none


questions:

  • Do you think it is feasible to proceed with such a list of all acronym strings that we want to support? (If yes, I can generate the full list.)
  • What do you think of the "shortened versions", like "northeastou", are they worth the effort of supporting them? (I tend to just skip them. They are always "...outside" strings, this concept is not usable with most of the strings anyways.)
  • What would be the way to integrate this approach into the current input parsing code of legend.m? We would eventually like the location property to be "northwest", even when called via "nw" I assume. How should we do this?


Hartmut <hardy>
Tue 11 May 2021 11:28:32 AM UTC, comment #6: 

We use the default property value matching mechanism to detect whether a given location string is valid, so "set (hlegend, 'location', 'someacronym')" will be rejected unless we list all possible valid acronyms in the first place. Is this something doable? If not then I see a few other solutions, in order of complexity:

  • allow any string value for "location" and validate afterward (through an "addlistener" callback, see below). This approach would work but we need to keep track of the previous value (e.g. in an appdata or a hidden property) to which we could fallback in case of an invalid new location.


  • add to possibility to specify a validation callback (in place of the default/valid values argument) to "addproperty".



  • add a PRESET/POSTSET argument to the "addlistener" function, (similar to Matlab's handle method "addlisterner"'s "EventName" argument [1]) and use a PRESET listener to decide to which valid value an acronym corresponds to. Note that our current implementation of "addlitener" triggers the execution of the callback after the property has been changed (equivalent to "POSTSET") so if we used that function to track "location" changes, acronyms would be rejected before we can validate them.

 
[1] https://fr.mathworks.com/help/matlab/ref/handle.addlistener.html

Pantxo Diribarne <pantxo>
Group Member
Mon 10 May 2021 08:50:58 PM UTC, comment #5: 

Sorry, I might have written that code as a way to describe my findings from comment #2 without running it.

I thought the code would go in the update_legend_position subfunction:


diff -r e8e9f815945a scripts/plot/appearance/legend.m
--- a/scripts/plot/appearance/legend.m  Sun Apr 25 18:45:46 2021 +0200
+++ b/scripts/plot/appearance/legend.m  Mon May 10 21:43:37 2021 +0100
@@ -1417,6 +1417,24 @@
   persistent vmargin = 6;

   location = get (hl, "location");
+
+  locations = {"East", "EastOutside", "North", "NorthEast", ...
+    "NorthEastoOutside", "NorthOutside", "NorthWest", "NorthWestOutside", ...
+    "South", "SouthEast",  "SouthEastOutside", "SouthOutside", "SouthWest", ...
+    "SouthWestOutside", "West",  "WestOutside"};
+  acronyms = cellfun (@(x) tolower (x(x>='A' & x<='Z')),  locations, ...
+    "UniformOutput", false);
+  locations = tolower (locations);
+  acr2loc = cell2struct (locations, acronyms, 2);
+  if (isfield (acr2loc, location))
+    location = acr2loc.(location);
+  endif
+  location = location(~isspace (location));
+  idx = find (strncmp (location, locations, numel (location)));
+  if (isscalar (idx))
+    location = locations{idx};
+  endif
+
   outside = strcmp (location(end-3:end), "side");
   if (outside)
     location = location(1:end-7);


but that's not enough and you are probably right it should go in parse_opts. I will look into it.

Guillaume <gyom>
Mon 10 May 2021 07:10:32 PM UTC, comment #4: 

@Guillaume: I just tried to test your code proposal in comment #3 but failed to get it running. Could you provide a patch to legend.m that I can use to test this? I've already seen a warning from your code proposal that "strmatch is obsolete, please use str(n)comp instead", but currently also get an error from your call to strmatch. I think your code fragment should go somewhere in the (lengthy) subfunction parse_opts inside of legend.m .

Hartmut <hardy>
Tue 04 May 2021 09:47:30 PM UTC, comment #3: 

No sure what is the cleanest way to implement this. What about:


location = get (hl, "location");

locations = {"North", "East", "South", "West", "NorthEast", "SouthEast", "SouthWest", "NorthWest"}; # ...
acronyms = cellfun (@(x) tolower (x(x>='A' & x<='Z')),  locations, "UniformOutput", false);
locations = tolower (locations);
acr2loc = cell2struct (locations, acronyms, 2);
try
  location = acr2loc.(location);
end_try_catch
location = location(~isspace (location));
idx = strmatch (location, locations);
if (isscalar (idx))
  location = locations{idx};
endif


Guillaume <gyom>
Tue 04 May 2021 09:21:48 PM UTC, comment #2: 

From further testing, it seems that one can remove all whitespace characters:


location = location(~isspace (location))


Shortened versions are accepted too as soon as they are unambiguous, e.g. "northeasto" is fine but "northeas" is not. The acronym version mentioned in the original submission takes precedence, i.e. "NO" is unambiguously "NorthOutside". No whitespace are accepted with acronyms. This means that expansion should take place first, followed by removing whitespace, and then performing partial matching.

Guillaume <gyom>
Tue 04 May 2021 06:22:41 PM UTC, comment #1: 

Matlab (e.g. R2019b) also accepts "location" properties with spaces. The following works in Matlab, but currently throughs an error in Octave: legend('my text', 'location', 'south east');

I was about to file a new bug report of the type "incompatibility", because this Octave behavior prevented me to run a Matlab script from someone else. Shouldn't we raise the importance of the "feature request"?

Hartmut <hardy>
Thu 02 Jan 2020 11:11:31 PM UTC, original submission:  

Although undocumented, Matlab accepts 2-letter abbreviations for the "Location" property.  For example, "NW" for "NorthWest".  This is a small feature, but it is pretty handy not to have to type long strings like "southeast".

Rik <rik5>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by gyom (Posted a comment)
  • -email is unavailable- added by hardy (Posted a comment)
  • -email is unavailable- added by rik5 (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code