plotjuliaplotlyplotly.js

How to plot a vector field in Julia?


I want to plot a vector field in Julia. I could not find an example here. Here there are some examples using plotly, however, they do not work for me. I would like to plot the vector field by plotlyjs or plotly.

Here is an example code in Julia:

using Plots
pyplot()
x = collect(linspace(0,10,100));
X = repmat(x,1,length(x));
Y = repmat(x',length(x),1);
U = cos.(X.*Y);
V = sin.(X.*Y);
streamplot(X,Y,U,V)

Here is the Matlab example:

[x,y] = meshgrid(0:0.2:2,0:0.2:2);
u = cos(x).*y;
v = sin(x).*y;

figure
quiver(x,y,u,v)

enter image description here


Solution

  • The short answer: use quiver from Plots.jl.

    quiver(x, y, quiver=(u, v))
    

    In the following, I'll attempt to fully recreate the example you showed in Matlab.

    First, we'll import Plots and enable the plotly backend.

    using Plots
    plotly()
    

    We need to define a function similar to Matlab's meshgrid. Since Plots will operate on our arrays of points regardless of their dimensionality, I chose to simply use repeat and use the "flattened" outputs.

     meshgrid(x, y) = (repeat(x, outer=length(y)), repeat(y, inner=length(x)))
    

    Now, we can create x, y, u, and v using the same logic as the Matlab code. For the sake of brevity, we can use the @. macro to vectorize all calls in the given expression.

    x, y = meshgrid(0:0.2:2, 0:0.2:2)
    u = @. cos(x) * y
    v = @. sin(x) * y
    

    From here, we can simply use the quiver function from Plots, passing u and v as a 2-tuple to the keyword argument quiver.

    quiver(x, y, quiver=(u, v))
    

    Initial plot

    The result is close to the Matlab output, but it seems that Plots.jl scales the arrows to be longer than they are in Matlab. This is easily fixable, though; we can simply broadcast-multiply u and v by a scale constant.

    scale = 0.2
    u = @. scale * cos(x) * y
    v = @. scale * sin(x) * y
    

    Final plot