# How to Transform Plots / Shape with Plots.jl

Hi all,

I want to transform the shape that I plot with this code:

``````using Plots, LaTeXStrings, Roots, SymPy
gr()

f(x) = sin(x^2) + cos(2x) - 6
g(x) = sin(x^2) + cos(2x)

plot(f,2,4, ylims=(-8,3),
legend=:topleft, linecolor=:green, label="")
plot!(g,2,4, ylims=(-8,3),
legend=:topleft, linecolor=:green, label="")

plot!([2,2],[f(2),g(2)], label="", linecolor=:green)
plot!([4,4],[f(4),g(4)], label="", linecolor=:green)

``````

so it can be mirrored, the transformation will be translation and mirroring. Any package here that can help me?

This is the my plot: This is what I want to achieve, the mirror of the above shape: Cavalieri’s Principle

Have you tried declaring your own types to scale and shift the function?

``````julia> struct YShift{F, Y} <: Function f::F; y::Y end

julia> (g::YShift)(x) = g.f(x) + g.y

julia> struct YScale{F, S} <: Function f::F; s::S end

julia> (g::YScale)(x) = g.s * g.f(x)

julia> plot!(YShift(f, -6), 2, 4, linecolor=:green)

julia> plot!(YScale(f, -1), 2, 4, linecolor=:green)
``````
3 Likes

Defining new types may be a bit of an overkill for this problem if it does not repeat a few times. Here is another function with some ‘functional’ approach:

``````function make_fg_plot()
f(x) = sin(x^2) + cos(2x) - 6
g(x) = sin(x^2) + cos(2x)

yshift = y -> y + 5
yreflection = y -> -y
ytransform = yshift ∘ yreflection

plt = plot(; ylims = (-8, 15), legend = :topleft)
for (T, attrs) in [(identity, (;label = "", linecolor = :green)),
(ytransform, (;label = "", linecolor = :red))]
plot!(plt, T ∘ f, 2, 4; attrs...)
plot!(plt, T ∘ g, 2, 4; attrs...)

plot!(plt, [2, 2], T.([f(2), g(2)]); attrs...)
plot!(plt, [4, 4], T.([f(4), g(4)]); attrs...)
end
return plt
end
``````

This function returns the `plt` object and may be called from REPL or `display`ed otherwise.

3 Likes

It is colorful,

I thought someone here can point me to a package that can transform plot of curves, but we need to create our own function instead. Thanks! Where or how did you learn to make the function? I want to learn and understand more.

Why write

``````for (T, attrs)
``````

and

``````plot!(plt, T ∘ f, 2, 4; attrs...)
``````

So `identity` is defined already in Julia?

I add another simple function for anyone who wants to learn:

``````using Plots, LaTeXStrings, Roots, SymPy
gr()

function make_fg_plot()
f(x) = sin(x^2) + cos(2x) - 6
g(x) = sin(x^2) + cos(2x)

yshift = y -> y + 5
yreflection = y -> -y
ytransform = yshift ∘ yreflection

plt = plot(; ylims = (-8, 15), legend = :topleft)
for (T, attrs) in [(identity, (;label = "", linecolor = :green)),
(ytransform, (;label = "", linecolor = :red))]
plot!(plt, T ∘ f, 2, 4; label="")
plot!(plt, T ∘ g, 2, 4; label="")

for i=0:0.2:2
plot!(plt, [2+i, 2+i], T.([f(2+i), g(2+i)]); label="")
end
end
return plt
end

make_fg_plot()
``````
1 Like

I like this approach. It’s not even really specific to the y-axis, and using built-in partial application types makes it play nice with things like InverseFunctions.jl:

``````shift(ν) = Base.Fix1(+, ν)
shift(5) ∘ f # y-up-shift
f ∘ shift(2) # x-left-shift
``````
2 Likes

When I ran the function, it didn’t have all the colors (because of the `attr...` bit). So there is an odd discrepancy. Maybe it’s a version issue. Weird.