Skip to content

Add raw-lines that doesn't subdivide when a non-identity axis transform is used#110

Closed
tewk wants to merge 1 commit intoracket:masterfrom
tewk:master
Closed

Add raw-lines that doesn't subdivide when a non-identity axis transform is used#110
tewk wants to merge 1 commit intoracket:masterfrom
tewk:master

Conversation

@tewk
Copy link
Collaborator

@tewk tewk commented Jan 23, 2023

log-log convergence plots need to create raw-lines that aren't sampled with subdivide-lines.

@alex-hhh
Copy link
Collaborator

Can you explain what the problem is with using lines in a log-log plot and how your new raw-lines solves it?

Perhaps provide a small example plot illustrating the problem with lines?

Thanks, Alex.

@GregVernon
Copy link

@alex-hhh

Racket (unexpected behavior)

#lang racket/base
(require plot)

(define x (list 5 203 ) )
(define y (list 1.24 510 ) )

(parameterize (  [plot-x-label  #f]
                 [plot-y-label  #f]
                 [plot-x-transform log-transform]
                 [plot-y-transform log-transform]
                 )
  (plot (lines(map vector x y ) ) )
  )

bad_log_plot

Matlab (expected behavior)

x = [ 5 203 ]
y = [1.24 510]
loglog( x, y )

ax = gca;
axis([x y])
xlabel("x")
ylabel("y")
ax.XGrid = "on";
ax.YGrid = "on";

image

@GregVernon
Copy link

Another example:

Racket (unexpected behavior)

#lang racket/base
(require plot)

(define x (list 28 0.13 0.006765 ) )
(define y (list 1.27 0.63 0.325 ) )

(parameterize (  [plot-x-label  #f]
                 [plot-y-label  #f]
                 [plot-x-transform log-transform]
                 [plot-y-transform log-transform]
                 )
  (plot (lines(map vector x y ) ) )
  )

another_bad_log_plot

Matlab (expected behavior)

x = [28 0.13 0.006765]
y = [1.27 0.63 0.325]

loglog( x, y, Marker="o" )

image

@alex-hhh
Copy link
Collaborator

alex-hhh commented Feb 1, 2023

@GregVernon , thanks for providing the examples. You labelled the Racket plots as "unexpected behavior", but I don't understand why?

With my limited math knowledge, a line between two points will show up as a curve on a log-log plot. If you want a straight line on a log-log plot, you need to plot a power function (see example code below).

I'm not familiar with Matlab or what log-log plots are used for, can you explain what does a straight line between two points on a log-log plot represent in Matlab? I tried looking up the loglog documentation, but it is still not clear to me why is Matlab plotting it like that.

Given that Matlab has this behavior, I think the Racket plot package should provide it as well; but I want to make sure it is implemented appropriately -- the lines-raw implementation seems too broad, given that there are other types of axis transforms supported by the Racket plot package. Also, this functionality will need documentation as well as unit tests written, but I am happy to assist with that.

#lang racket
(require plot)

(define x (list 5 203 ) )
(define y (list 1.24 510 ) )

(define x0 (log 5))
(define x1 (log 203))
(define y0 (log 1.24))
(define y1 (log 510))
  
(define k (/ (- y1 y0) (- x1 x0)))
(define a (- y0 (* x0 k)))

(parameterize ([plot-x-label  #f]
               [plot-y-label  #f]
               [plot-x-transform log-transform]
               [plot-y-transform log-transform])
  (plot
   (list
    (tick-grid)
    (function (lambda (x) (* (exp a) (expt x k))) 5 203 #:color 2)
    (lines (map vector x y) #:color 1))))

loglog

@GregVernon
Copy link

With my limited math knowledge, a line between two points will show up as a curve on a log-log plot. If you want a straight line on a log-log plot, you need to plot a power function (see example code below).

Log plots of discrete data have their lineage from the days of graphing data by hand and wanting to identify rates of change graphically. As shown in the example below, the engineer/scientist would plot the discrete points onto graphing paper with appropriate log-axes and then use a ruler to either "connect the dots" or to "least square eyeball-norm" fit the data to a straight line. Then you could simply measure "rise over run" and it would tell you the slope:
image

Another example, showing convergence rates for two numerical methods. Note that the author has included "guidelines" that assist with showing the rates at which the lines are converging. With a curved log-plot this can't be easily done.
image

Another good link if you want to read more: https://www.physics.brocku.ca/PPLATO/interactive-mathematics/loglog2.html

@soegaard
Copy link
Member

soegaard commented Feb 1, 2023

The documentation of lines says that it:

Returns a renderer that draws lines connecting the points in the input sequence vs.

So if we think of a log-transform as a way of describing the paper we draw on,
it is not unreasonable at all to expect lines to be drawn.

The matlab documentation:

Vector and Matrix Data
To plot a set of coordinates connected by line segments, specify X and Y as vectors of the same length.

And that's what happen in the example:

x = [28 0.13 0.006765]
y = [1.27 0.63 0.325]
loglog( x, y, Marker="o" )

@alex-hhh
Copy link
Collaborator

alex-hhh commented Feb 2, 2023

Hi @GregVernon and @soegaard, thanks for the clarification. I was not aware of these paper-based techniques for log-log plots, but if Matlab supports them and users are familiar with them, they should be added to the plot package.

I think however that lines-raw is not a good choice for a name, since it will be difficult to for other users to discover the functionality. I am thinking we could add a #:ignore-axis-transform? option to the lines renderer and add a section to the documentation with an example based on the one you provided above and an explanation of the feature. I'll try an implementation based on this in the next week or so.

@soegaard
Copy link
Member

soegaard commented Feb 2, 2023

I have thought some more about the problem.

At first I thought the problem was that lines doesn't draw lines, but draws the graph
of a linear function. But that's not the full story.

The "problem" is rather that plot allows more sophisticated axis-transforms than Matlab does.

One example is the stretch-transform that zooms in on a particular area.
image

Here I would expect a line a drawn with lines to work with the strech transform. But this means
that lines need to draw the graph of a linear function.

Similarly if the log-transform and the stretch-transform are composed, I belive, that plot
needs to draw the graph of a power function for the composition to work.

Instead of adding options to lines I suggest to special case lines log-paper and loglog-paper.
I.e. in addition to lines have a log-lines and a loglog-lines. Given start and end point
they compute either an exponential or a power function and the graph of that is drawn.
If loglog-lines is used with log-transforms on both axes, the result will be a line.
If loglog-lines is used with no transforms, then the result will be a graph of a power function
connecting the start and end point.

The docs for lines currently reads:

Returns a renderer that draws lines connecting the points in the input sequence vs.

Adding a line that links to a section on "Lines on plots with transformed axes" would
make log-lines and loglog-lines discoverable.

alex-hhh added a commit to alex-hhh/plot that referenced this pull request Feb 6, 2023
... can be used to draw straight lines on a log-log plot, see scribble
documentation for full details.

See also racket#110.
@alex-hhh
Copy link
Collaborator

alex-hhh commented Feb 6, 2023

@soegaard , I had the same concerns about the other types of axis transforms, this is why I asked for so many clarifications. However, it seems to me that those who are familiar with Matlab would expect a plot where only individual points are transformed, and the lines between points are drawn straight.

In any case, I implemented an approach in #111 where the lines renderer has an additional #:ignore-axis-transforms? keyword argument which controls the mode in which the lines are drawn. I think this a better name than lines-raw and the updated documentation also shows an example (drawn from the examples above) on how this new argument can be used.

alex-hhh added a commit that referenced this pull request Feb 11, 2023
... can be used to draw straight lines on a log-log plot, see scribble
documentation for full details.

See also #110.
@alex-hhh alex-hhh closed this Feb 11, 2023
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.

4 participants