How to reflect plot function toward $y=x$ with Plots?

Hi all,

I have the code from previous forum I made, that reflect a graph toward y axis. Now I want to reflect it toward y=x , I can’t just do yreflection = y -> x it prompts a lot of errors

This code works on y axis reflection.

using Plots, LaTeXStrings, Plots.PlotMeasures
gr()

function make_fg_plot()
    f(x) = log(6x) 
    g(x) = 2x + log(6x)

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

    plt = plot(; xtick=:false, ylims = (-15, 15), 
	 legend = :topleft, bottom_margin=5mm)
    for (T, attrs) in [(identity, (;label = "", linecolor = :green)), 
                       (ytransform, (;label = "", linecolor = :red))]
        plot!(plt, T ∘ f, 0, 10; label="")
        plot!(plt, T ∘ g, 0, 10; label="")

	for i=0:0.2:2        
	plot!(plt, [2+i, 2+i], T.([f(2+i), g(2+i)]); label="")
	end
	
	annotate!([(3,-16.1, (L"x", 10, :black))])
	annotate!([(3,-15.1, (L"|", 10, :black))])
    end
    return plt
end

make_fg_plot()

Hi!

Thanks for the example code. Could you clarify what it should be doing? Because it doesn’t reflect the functions at the y axis, as far as I can tell. Did you mean to write

yreflection = y -> -y

perhaps?

Regarding the question: Doing yreflection = y -> x will not do the right thing, because x is not known to this “reflection function”. What we are using here are anonymous functions (you can read more about them here Functions · The Julia Language ) and they are basically normal Julia functions, just without a name. So the function you intuitively wrote down would be something like

begin <no name>(y)
    return x
end

but of course, x is not defined anywhere in the code, so it doesn’t know how to use it.


The transformation you want is only possible if we know the pair of coordinates (x, y) and make a function like reflect_at_45 = (x, y) -> (y, x). But then the syntax for the plot would have to change and we would need to pass the range of x values explicitly, for example like so:

# Define the x-range explicitly
xrange = 0.0:0.1:10.0
# Define the transform (or anything else like `(x,y) -> (x, -y)` etc.
xyidentity = (x,y) -> (x,y)
xytransform = (x,y) -> (y, x)

...
for (T, attrs) in [(xyidentity, (;label = "", linecolor = :green)), 
                       (xytransform, (;label = "", linecolor = :red))]

    # Apply the transformation to all tuples (x, f(x))
    transformedPoints = T.(xrange, f.(xrange))
    # Make vectors out of the resulting tuples for plotting
    newx = first.(transformedPoints)
    newy = last.(transformedPoints)

    plot!(plt, newx, newy; label="")
...
end

There is probably a simpler way of writing it than in my example, but it should be flexible enough to to any kind of reflections in 2D.

1 Like

Hi @Sevi ,

the code should reflect the graphs toward y=0 axis. This is the plot:
Capture d’écran_2023-03-07_16-21-37

I give the bars to make it looks like Pharaoh

I just meant that the reflection in your example code is the same as identity. So when I run it, I just get the upper half of the plot, not the lower one. But it’s just a missing minus sign :slight_smile:

1 Like

I am able to create it like this:

Capture d’écran_2023-03-07_19-20-31

with this code:

using Plots, LaTeXStrings, Plots.PlotMeasures
gr()

# Define the x-range explicitly
xrange = 0.0:0.1:20.0
# Define the transform (or anything else like `(x,y) -> (x, -y)` etc.
xyidentity = (x,y) -> (x,y)
xytransform = (x,y) -> (y, x)

function make_fg_plot()
    f(x) = log(x) 
   
    plt = plot(; xtick=:true, xlims = (-15,15), ylims = (-15, 15), 
	 legend = :topleft, bottom_margin=5mm)
    for (T, attrs) in [(xyidentity, (;label = "", linecolor = :green)), 
                       (xytransform, (;label = "", linecolor = :red))]
    # Apply the transformation to all tuples (x, f(x))
    transformedPoints = T.(xrange, f.(xrange))
    # Make vectors out of the resulting tuples for plotting
    newx = first.(transformedPoints)
    newy = last.(transformedPoints)

    plot!(plt, newx, newy; label="")
    g(x)=x
    plot!(g,linecolor=:green, line=(:dash), label="")
    end
    return plt
end

make_fg_plot()

thanks a lot!

1 Like