improve piecewise plotting
kcrisman opened this issue · 15 comments
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.
Depends on #14801
CC: @wdjoyner @jasongrout @jondo @kcrisman @vbraun @slel @mkoeppe @eviatarbach @rwst
Component: graphics
Keywords: piecewise
Issue created by migration from https://trac.sagemath.org/ticket/11225
Description changed:
---
+++
@@ -1,10 +1,12 @@
-Until we actual totally rewrite piecewise functions, we should improve some things.
+Until we actually totally rewrite piecewise functions, 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))
```
-
+* Maybe unify with `plot_step_function`, which currently is sort of its own thing?Description changed:
---
+++
@@ -10,3 +10,19 @@
sage: plot([f,x^3],(x,0,2))
```
* 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.Description changed:
---
+++
@@ -9,6 +9,7 @@
sage: f = Piecewise([[(0,1),x^3], [(1,2),x^2]], x)
sage: plot([f,x^3],(x,0,2))
```
+* 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](http://groups.google.com/group/sage-support/browse_thread/thread/7357d08529de32dd))
* Maybe unify with `plot_step_function`, which currently is sort of its own thing?
* In this example:
Description changed:
---
+++
@@ -27,3 +27,7 @@
* 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.
+
+
+See also #1773.
+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__.
Description changed:
---
+++
@@ -8,6 +8,14 @@
```
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](http://ask.sagemath.org/question/868/two-piecewise-defined-functions-in-one-plot):
+
+```
+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__'
```
* 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](http://groups.google.com/group/sage-support/browse_thread/thread/7357d08529de32dd))
* Maybe unify with `plot_step_function`, which currently is sort of its own thing?Description changed:
---
+++
@@ -35,7 +35,7 @@
* 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.
-
+* Most keywords are passed on to all component functions, but that is the wrong thing to do for legends. See [this ask.sagemath.org question](http://ask.sagemath.org/question/925/piecewise-functions-and-legend-label).
See also #1773.
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?
Description changed:
---
+++
@@ -35,7 +35,6 @@
* 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.
-* Most keywords are passed on to all component functions, but that is the wrong thing to do for legends. See [this ask.sagemath.org question](http://ask.sagemath.org/question/925/piecewise-functions-and-legend-label).
See also #1773.
I removed the last bullet point and created #12651 where I'll post a patch with dsm's fix.
Description changed:
---
+++
@@ -1,4 +1,4 @@
-Until we actually totally rewrite piecewise functions, we should improve some things.
+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.
@@ -17,7 +17,24 @@
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](http://groups.google.com/group/sage-support/browse_thread/thread/7357d08529de32dd))
+
+ fixed in new `piecewise`
+
* Maybe unify with `plot_step_function`, which currently is sort of its own thing?
* In this example:
@@ -36,5 +53,17 @@
* 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.
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.
Changed keywords from none to piecewise