# Ticket #2922(new enhancement)

Opened 5 years ago

Last modified 8 months ago

## scale function for plot_vector_field

Reported by: Owned by: schilly was minor sage-5.10 graphics jason, novoselt N/A

### Description

When plotting a vector field, it is useful to be able to scale the length of the arrows. This is similar to  mma:ScaleFunction.

e.g.:

• an upper therehold: lambda x: min(1,x)
• logarithmic: lambda x: log(1+x)

where x is the positive absolute length of the vector and each coordinate is divided by that - or some generalization of that.

## Change History

### comment:1 Changed 4 years ago by kcrisman

• Cc jason added

This would be good. There are two options for this.

1. Rewrite the matplotlib scale to take either a number or a callable function, and somehow make the Sage interface to this make scaling do what one would expect (the mpl scale does NOT behave as expected, as it essentially makes its own adhoc function similar to ones above).
1. Get at the underlying matplotlib object for each and every arrow in the Quiver and adjust the length.

I'm not sure how the second one could even happen. But the first one requires some non-trivial changes to matplotlib.quiver (since currently scale is an attribute only), and probably should be sent upstream if done.

### comment:2 Changed 4 years ago by jason

So basically you want to give a function that gives the length of a vector? That sounds reasonable.

Since Sage is actually the thing that generates the vectors, and matplotlib just plots them, I think scaling the vectors in Sage to each have the length you want is the correct thing to do here, before passing them to matplotlib.

plot_vector_field((-y,-x), (x,0,1),(y,0,1), norm=f)

where f is a function defined to take f(v,w), where v is the vector, w is the point in space (as a vector).

so your examples would be:

f=lambda v,w: min(1,v.norm())

f=lambda v,w: log(1+v.norm())

We could then adjust the scale parameter of the quiver plot so that the arrows would plot exactly the length you wanted (I believe units='x', scale=1 should do the job).

### comment:3 Changed 4 years ago by kcrisman

Well, yeah, you can use the same thing you do in plot_slope_field to get the norm (in fact, numpy has this nice absolute() function that mpl uses). But it looked to me like it might not be possible to get around the auto-scaling that mpl does (see matplotlib.quiver??), since ordinarily scale=1 is definitely not what one wants. I will look to see if units='x' would actually get around that.

### comment:4 Changed 4 years ago by jason

The scale argument says the ratio of length to units, where units are specified in the units parameter. Usually the units are not in terms of data coordinates, I believe. So what you want is to make the units equal to data coordinates (i.e., 'x' or 'y'), instead of a function of the plot size, like 'width' and 'height' are.

### comment:5 Changed 4 years ago by jason

After playing with this a bit more, I decided that, while what matplotlib has makes sense, it isn't what we want. I just sent a message to the matplotlib-users mailing list.

### comment:6 Changed 4 years ago by jason

Eric Firing just committed the change to the matplotlib quiver function that allows us to scale arrows easily. See  http://www.nabble.com/scaling-arrows-in-quiver-tt25673613.html#a25673613

Now we just need to update the matplotlib spkg and wrap it (the new scale_units function). This might wait a while until the next release of matplotlib comes out, unless someone wants to update the spkg before then.

### comment:8 follow-up: ↓ 9 Changed 4 years ago by edrex

I'd like to be able to pass the scale kwarg to quiver, is that what we're talking about doing?

### comment:9 in reply to: ↑ 8 Changed 4 years ago by jason

Replying to edrex:

I'd like to be able to pass the scale kwarg to quiver, is that what we're talking about doing?

yes.

### comment:10 follow-up: ↓ 11 Changed 2 years ago by kcrisman

• Report Upstream set to N/A

See also #11208, which is also about quivers.

Is this ready to wrap? We've definitely updated mpl since a year and a half ago.

### comment:11 in reply to: ↑ 10 Changed 2 years ago by jason

Replying to kcrisman:

Is this ready to wrap? We've definitely updated mpl since a year and a half ago.

Yes, it should be ready to wrap now.

### comment:12 Changed 17 months ago by novoselt

• Cc novoselt added

### comment:13 Changed 8 months ago by benjaminfjones

Just a note, this ticket would provide a nice solution to the issue raised at  http://ask.sagemath.org/question/1816/visualize-vector-field-with-singularities.

Note: See TracTickets for help on using tickets.