Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[legend pt5] Reserve space for outside legend #74

Merged
merged 5 commits into from
Sep 21, 2020

Conversation

bdeket
Copy link
Contributor

@bdeket bdeket commented Sep 11, 2020

This PR builds on the previous (#70 #71 #72) to implement #49

With this, space is reserved for drawing the legend outside of the plot area.

When the legend anchor is a corner (eg top-left etc.) the reserved space (horizontal or vertical) is based on the width/height of the legend. It tries to maximize the space for the plot area.

the fixpoint margin calculation was broken -- edit: see #75

Also the margin calculation for pict titles in the 3d version was not updated -- edit: see #76


(require plot pict)
(plot3d (list (surface3d (λ (x y) 1) 0 1 0 1 #:label "v" #:color 'blue)
              (surface3d (λ (x y) 2) 0 1 0 1 #:label "x"))
        #:legend-anchor '(outside right) #:title (text "a long title" null 12 1))

untitled

(cond
[legend-rect
(define 2*gap (* 2 gap))
(define 3*gap (* 3 gap))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The names 2*gap and 3*gap are confusing (I know they are valid, but they can be confusing to anyone who is not familiar with Racket or Scheme). Can you change them to something that reflects their intent (as oppose to their value). E.g. they could be called small-gap and large-gap.

Copy link
Collaborator

@alex-hhh alex-hhh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added some comments, but I have some higher level concerns about the entire approach, which I think we should discuss first, see also #49 (comment).

In short, I think we should:

  1. Have explicit legend anchor positions for all outside locations (i.e. allow the user to explicitly choose between locations A and L in the picture in my comment)
  2. Avoid redundancies like top-left and (inside top-left) and meaningless positions such as (outside center), as these can confuse users
  3. Not move the plot legend if it overflows, for example a legend in positions A, B, C, G, H. I should only reserve their width from the plot area and if they overflow downwards, so be it, the plot legend should always be aligned with the plot area.

An approach that chooses the best location to maximize the plot area works for situations where the user is interactively constructing the plot (for example for publication in a paper). If plots are embedded into another application (this is my main use case), the program author has little control over the actual data and number of functions displayed, this being the choice of the user who might not have a technical inclination. An approach which allows explicit placement of the plot legend would work for everyone.

For point number 2, I feel that not all users of the plot library will be programmers and an interface which contains redundant and meaningless values can be confusing to them.

Number 3 is mainly for consistency with the "inside" legend behavior, but also, because I don't want the plot legend to jump around in an interactive application when another function is added to the plot in the interactive application, and the plot legend no longer fits with the plot area height (or width)

My preference would be to simply have a list of all possible legend locations. This would be a long list, but its length simply reflects the number of possible locations for the legend. We can also define helper functions, such as outside-anchor? or outside-left-anchor? to simplify their use in the code...

(define legend-anchor/c
  (or/c
   ;; Indicates that the legend should not be displayed anywhere (i.e. the
   ;; user will use `plot-legend-as-pict` for the legend. `no-legend` is more
   ;; explicit than `#f` or `none` about what it does.
   'no-legend
   ;; Inside anchor positions
   'top-left 'top 'top-right
   'left 'center 'right
   'bottom-left 'bottom 'bottom-right
   ;; Outside anchors, top row
   'outside-top-left 'outside-top 'outside-top-right
   ;; Outside positions, on the left and right sides
   'outside-left-top 'outside-left-middle 'outside-left-bottom
   'outside-right-top 'outside-right-middle 'outside-right-bottom
   ;; Outside positions, bottom row
   'outside-bottom-left 'outside-bottom 'outside-bottom-right))

(define (outside-anchor? a)
  (member a '(outside-top-left outside-top outside-top-right
              outside-left-top outside-left-middle outside-left-bottom
              outside-right-top outside-right-middle outside-right-bottom
              outside-bottom-left outside-bottom outside-bottom-right)))

(define (outside-left-anchor? a)
  (member a '(outside-left-top outside-left-middle outside-left-bottom)))


;; the maximum width/height for the plot+axis-labels
(define x-size-left (- dc-x-size width))
(define y-size-left (- dc-y-size title-margin height))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the intent of these variables, they should better be named remaining-{x,y}-size, or plot-{x,y}-size since left can be confused with being on the left side of something.

@bdeket
Copy link
Contributor Author

bdeket commented Sep 19, 2020

I feel like there is one option missing, something like outside-top-center-dc for when it makes more sense to align the legend with the title than with the plot area. (Imagine horizontal layout that is to big to fit above the plot area, but with space left above the axis/tick marks).
I kept Legend-Anchor as an extension of Anchor to not break existing code (in TR).
I'll try to remove the overflow code and address your other comments tomorrow.

Copy link
Collaborator

@alex-hhh alex-hhh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these changes look good, and the only minor comment I have is about the choice of name for outside-top-center-dc

(define legend-anchor/c (or/c anchor/c
(one-of/c
'no-legend
'outside-top-center-dc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This anchor position needs a better name. The term dc will not mean anything to a user of the plot package. Maybe outside-top-center-plot, but I am not sure?

Also, given all the refactoring that was done, I think it will be relatively easy to add new anchor locations in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe outside-global-top-center?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good.

@alex-hhh alex-hhh merged commit 7eee201 into racket:master Sep 21, 2020
@bdeket bdeket deleted the legend-outside branch September 22, 2020 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants