Opened 8 years ago

Last modified 3 years ago

#11225 new defect

improve piecewise plotting

Reported by: kcrisman Owned by: jason, was
Priority: major Milestone: sage-7.3
Component: graphics Keywords: piecewise
Cc: wdj, jason, jondo, kcrisman, vbraun, slelievre, mkoeppe, eviatarbach, rws Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: #14801 Stopgaps:

Description (last modified by mkoeppe)

Until we actually totally rewrite piecewise functions (done in #14801), we should improve some things.

For concreteness, here is one thing that should work but doesn't. I'm sure there are more - add to this list, and then whatever isn't fixed in this ticket can be moved to another ticket. I just want to make sure they're listed in one place, not ten tickets.

List:

  • plotting more than one
    sage: f = Piecewise([[(0,1),x^3], [(1,2),x^2]], x)
    sage: plot([f,x^3],(x,0,2))
    
    A very similar example was at this ask.sagemath.org post:
    sage: f = Piecewise([[(-2,1),1],[(1,4),x]])
    sage: g =  Piecewise([[(-2,1),1],[(1,4),2*x]])
    sage: plot([f,g])
    AttributeError: PiecewisePolynomial instance has no attribute '__float__'
    

Both examples work in the new piecewise (#14801):

sage: f = piecewise([[(0,1),x^3], [(1,2),x^2]], var=x)
sage: plot([f,x^3],(x,0,2))
sage: f = piecewise([[(-2,1),1],[(1,4),x]])
sage: g =  piecewise([[(-2,1),1],[(1,4),2*x]])
sage: plot([f,g], xmin=-3, xmax=5)
  • plotting a product of a piecewise with a symbolic (well, the problem is multiplying the two, but still worth putting here - see this sage-support thread)

fixed in new piecewise

  • Maybe unify with plot_step_function, which currently is sort of its own thing?
  • In this example:
    sage: zero_func(x)=0
    sage: g = Piecewise([[(-1000,1),zero_func],[(1,1000),(x-1)^3]],x)
    sage: G = g.plot()
    sage: G.show(xmin=-5,xmax=5,ymax=100)
    sage: g(1)
    0
    
    • You can use oo (infinity) for endpoints, but then the plot code for Piecewise gets screwed up.
    • You can try putting in zero instead of defining this new zero function, but then g(1) and g(-1) etc. won't work.
    • You can try using extend_by_zero to make the zero part, but it gives the same problem.
    • You can plot without xmin and xmax, but that gives the whole function.
    • You can plot without ymax, but that gives the range further out than you want.
    • You can try plot(g), but that turns out to uncover a very strange error that may or may not be a bug.

In new piecewise (#14801) 0 is no longer in the domain (open intervals?); and there is now support for unbounded intervals.

sage: zero_func(x)=0
sage: g = piecewise([[(-1000,1),zero_func],[(1,1000),(x-1)^3]])
sage: G = g.plot()
sage: G.show(xmin=-5,xmax=5,ymax=100)
Launched png viewer for Graphics object consisting of 1 graphics primitive
sage: g(1)
ValueError: point 1 is not in the domain

See also #1773.

Change History (12)

comment:1 Changed 8 years ago by kcrisman

  • Description modified (diff)

comment:2 Changed 8 years ago by kcrisman

  • Description modified (diff)

comment:3 Changed 8 years ago by kcrisman

  • Description modified (diff)

comment:4 Changed 8 years ago by kcrisman

  • Description modified (diff)

comment:5 Changed 8 years ago by kcrisman

  • Description modified (diff)

Regarding the first item (can't plot two of them), It probably wouldn't even be that hard to fix. The problem is that setup_for_eval_on_grid wants to use fast_float but Piecewise guys don't have that, or more precisely don't have __float__.

comment:6 Changed 8 years ago by kcrisman

  • Description modified (diff)

comment:7 Changed 8 years ago by kcrisman

From DSM on this ask.sagemath.org question:

# monkeypatch legend duplication of trac #11225
def fix_piecewise(fn):
    import types
    def fixed_plot(self, *args, **kwargs): 
        from sage.plot.all import plot
        return sum([plot(f, a, b, *args, **(dict((k,v) for k,v in kwargs.items() if i == 0 or k != 'legend_label')))
                    for i, ((a,b),f) in enumerate(self.list())])
    def fn2(*args, **kwargs):
        ans = fn(*args, **kwargs)
        ans.plot = types.MethodType(fixed_plot, ans)
        return ans
    return fn2

Piecewise = fix_piecewise(Piecewise)

Nice protopatch, perhaps?

comment:8 Changed 8 years ago by mjo

  • Description modified (diff)

I removed the last bullet point and created #12651 where I'll post a patch with dsm's fix.

comment:9 Changed 6 years ago by jondo

  • Cc jondo added

comment:10 Changed 6 years ago by ppurka

  • Dependencies set to #14801

comment:11 Changed 3 years ago by mkoeppe

  • Cc kcrisman vbraun slelievre mkoeppe eviatarbach rws added
  • Description modified (diff)
  • Keywords piecewise added

Updated description for new piecewise (#14801). Didn't check the xmin/xmax etc. behavior that is mentioned in the description.

This can probably be closed when the old Piecewise (now deprecated) is removed completely.

comment:12 Changed 3 years ago by mkoeppe

  • Milestone set to sage-7.3
Note: See TracTickets for help on using tickets.