How to draw a rectangular region with Plots.jl?

For an example in PyPlot:

http://matthiaseisen.com/pp/patterns/p0203/

2 Likes

You could either do a scatter with custom markers (https://juliaplots.github.io/examples/gr/#custom-markers) or more likely you want to use the :shape seriestype, where the x/y inputs are the vertices of the polygon you wish to draw. You can draw multiple polygons in the same series by separating them with NaN. It may not run out of the box, but this tutorial was how I created the JuliaPlots logo.

2 Likes

From @tbreloff tutorial, the solution is:

# define a function that returns a Plots.Shape
rectangle(w, h, x, y) = Shape(x + [0,w,w,0], y + [0,0,h,h])

plot(0:5,0:5)
plot!(rectangle(3,2,0,0), opacity=.5)

6 Likes

I tried figuring out how Shape() works in general, but I couldn’t really figure out the rules for myself. I also searched the docs, but so far I didn’t find anything, that explained in a very general way, how to pass arguments to Shape() in a way that makes it do what I want. I could of course reproduce the rectangle, but what if I want to plot a trapezoid or anything? I did have a look at the neat batman-example, but it’s so much and so complicated, I couldn’t find the general rule how to get the x and y argument, that has to be passed to Shape(). I also found the Shape(vertices) -syntax and thought I could plot something, if I give e.g. four coordinates, but i didn’t find the right way to do so.
Can anybody here explain how I would use Shape(x,y) in a general way? Which type of vector do I need to pass? Why does the rectangle(w,h,x,y) function above work like it does?
I’m kind of desperate right now, because I really did try to figure it out on my own… Any help is appreciated!
Thanks!

1 Like

Just after writing here, I finally found out, what was what in general. In case anybody aver wonders this as well, I’ll add a small explanation:

Shape([x-value-corner1, x-value-corner2, x-value-corner3, x-value-corner4, …], [y-value-corner1, y-value-corner2, y-value-corner3, y-value-corner4, …])

So, to get a trapezoid, the code would be something like this:

plot(Shape([25, 425, 425, 25], [-1, -5.24, 5.24, 1]))

ultimatley giving the four corners of the trapezoid the coordinates

  • x= 25, y= -1
  • x= 425, y= -5.24,
  • x=425, y= 5.24,
  • x=25, y=5.24

I hope,this helps anybody stumbling across the same problem :slight_smile:

8 Likes

Currently gives me

ERROR: MethodError: no method matching +(::Int64, ::Array{Int64,1})
Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...) at operators.jl:502
  +(::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}, ::T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8}) where T<:Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8} at int.jl:53
  +(::Union{Int16, Int32, Int64, Int8}, ::BigInt) at gmp.jl:456
  ...
Stacktrace:
 [1] rectangle(::Int64, ::Int64, ::Int64, ::Int64) at ./REPL[17]:1
 [2] top-level scope at none:0

In Julia 1.0 you have to put dots in front of the plus signs in rectangle (be explicit about the fact that you add a scalar to every component of an array).

4 Likes

Simple

# define a function that returns a Plots.Shape
rectangle(w, h, x, y) = Shape(x .+ [0,w,w,0], y .+ [0,0,h,h])

plot(0:5,0:5)
plot!(rectangle(3,2,0,0), opacity=.5)

Only difference is a setting placing the legend in top right.

2 Likes