Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use in memory drawing for @png etc. when there's no filename? #49

Closed
Roger-luo opened this issue Mar 17, 2019 · 19 comments
Closed

Use in memory drawing for @png etc. when there's no filename? #49

Roger-luo opened this issue Mar 17, 2019 · 19 comments

Comments

@Roger-luo
Copy link
Contributor

Roger-luo commented Mar 17, 2019

It's sometimes annoying when I draw some pics for a package, it mess up git and I have to rm those drawings manually.

e.g

@png <script>

will just do the drawing in memory and will not create a file.

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 5, 2019

I have looked into it a bit right now and landed here as well.

The question:
Can the macros @png and @svg be modified so they would accept a parameter for only in-memory drawing.

They certainly could, wouldn't be a complicated task.
However the issue with that is in the preview function.
The preview function currently needs a current_filename.
Which means, the in-memory png drawings can't be previewed.

So we need to modify the macros and the preview function.

I lack on knowledge about juno and jupyter, how to display images from data.
I guess the current_buffer function in Luxor might help.

The preview function also opens windows on Windows, Apple and Linux operating systems.
I don't have any expertise about that.

Proposal:
Change macros for supporting in-memory drawings.
Adapt preview (in the case of jupyter and juno) in order to show in-memory drawings.
If the adaption of preview is not possible, then this whole issue doesn't make any sense.

@cormullion
Copy link
Member

Sounds like a great idea... Perhaps - a new macro called @draw would be even better, since we're not worried about the format. (?) Then use temp files and another (internal) function to preview them. The existing macros are good, but they're quite restricted in some ways - for example, you can't use string interpolation in the output filenames (there's a regex stage now, I believe).

I know nothing about the in-memory code here, it was added by @barche and it works great but if we want to modify/extend it we'll have to get to grips with Juno/Jupyter display systems...

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 5, 2019

So the approach would be:

Create a new macro @draw
approach a) If possible (and in python it is possible) handle the image in memory and display it.
- When if at all do i need to "delete" the image in memory?
- Pros: Should be faster
- Cons: need to tinker with each framework/backend separately
approach b) create a temp file in temp directory.
- When if at all do i need to delete the temp file?
- Pros: Should be easy to implement, since there is no need to change the preview function.
- Cons: Depends on IO

I'll try to cook something together.
Might take a while, i am new to julia and it's whole working process.

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 5, 2019

I have implemented the approach b), since i didn't want to disrupt anything.
Regarding jupyter, everything should be handled by the display function, so in-memory picture shouldn't be too hard either.

I am still thinking about the possibility to also do :svg, but i don't want too many parameters.
After all this should be used for immediate view in jupyter/juno

#68

Old info


By the way, as copied from the documentation, all circle functions don't work, no matter what macro i am using...

I am not sure what i am doing wrong here.

> @png circle(0, 20, :fill)

MethodError: no method matching arc(::Cairo.CairoContext, ::Int64, ::Int64, ::Symbol, ::Int64, ::Float64)
Closest candidates are:
  arc(::Cairo.CairoContext, ::Real, ::Real, !Matched::Real, ::Real, ::Real) at /home/hrom/.julia/packages/Cairo/htbtf/src/Cairo.jl:688
  arc(::Graphics.GraphicsContext, ::Real, ::Real, !Matched::Real, ::Real, ::Real) at none:0

Stacktrace:
 [1] circle(::Int64, ::Int64, ::Symbol, ::Symbol) at /home/hrom/.julia/dev/Luxor/src/curves.jl:15
 [2] circle(::Int64, ::Int64, ::Symbol) at /home/hrom/.julia/dev/Luxor/src/curves.jl:12
 [3] top-level scope at /home/hrom/.julia/dev/Luxor/src/drawings.jl:391
 [4] top-level scope at In[15]:1

@cormullion
Copy link
Member

use O not 0.

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 5, 2019

Yeah, i should have used copy paste... Yep it works just fine.

@cormullion
Copy link
Member

testing is going to be interesting... I’ll take a look tomorrow.

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 5, 2019

Yeah, about the tests. I coudn't find any tests on the macros png, pdf either.
Does the testing pipeline run the code in the documentation string as well?

@barche
Copy link
Contributor

barche commented Oct 6, 2019

Note that this is already possible if you use Drawing directly instead of the macros:

#26

@cormullion
Copy link
Member

Sorry I just got round to looking at this properly (on my phone over the weekend).

If you want a simple macro that does in-memory drawing and display (for PNG) when using Juno or Jupyter, add this code to drawings.jl and export @draw:

macro draw(body, width=600, height=600)
    quote
        Drawing($width, $height, :png)
        origin()
        background("white")
        sethue("black")
        $(esc(body))
        finish()
        (isdefined(Main, :IJulia) && Main.IJulia.inited) ? jupyter = true : jupyter = false
        Juno.isactive() ? juno = true : juno = false
        if juno || jupyter
            display(CURRENTDRAWING[1])
        else
            @info "use Juno or Jupyter"
        end
    end
end

In Juno, you'd see this:

Screenshot 2019-10-07 at 09 42 14

In Jupyter, you'd see this:

Screenshot 2019-10-07 at 09 43 11

In the Terminal, you'd see this:

Screenshot 2019-10-07 at 09 44 01

It appears to work, but it might be what you're looking for?

Perhaps the message should be more helpful... :)

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 7, 2019

Yep, that does the job as well.

Should i change it to this and create a new pull-request?

Or should we use the temporary-file approach?
I liked that it is almost the same as the previous png macro.
Reusing code is always good :)

@cormullion
Copy link
Member

Well, it depends on whether the purpose of the original issue (and your subsequent interest) was to do in-memory drawing or just to not have to worry about creating/deleting temporary files. It seemed to start off as the former, and end up as the latter... :)

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 7, 2019

I approached it from the user perspective, where i don't care, i just want to see a pretty picture, and i don't want to deal with created files :D

@cormullion
Copy link
Member

On macOS, I think your macro launches Preview and displays a window that contains no graphics (because the file gets deleted while Preview is launching :)).

Screenshot 2019-10-07 at 13 16 08

Not sure what it might do on faster/slower machines...

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 7, 2019

On my machine it works.

Also i don't know if i have to delete the file, or if i can leave it, since it is in a tmp directory.

On Wednesday i can look into the in-memory only option.

@barche
Copy link
Contributor

barche commented Oct 7, 2019

I have two reasons for choosing the completely in-memory approach for my notebooks:

  • Faster updates when using Interact.jl to manipulate the drawing
  • We have a read-only dir with notebooks on jupyterhub, it used to be that the temp files were in the same dir and that wouldn't work

@cormullion
Copy link
Member

@barche Thanks, useful info.

@m3m0ry
Copy link
Contributor

m3m0ry commented Oct 9, 2019

I copied your code and tested it. You can merge it.

@cormullion
Copy link
Member

@m3m0ry Thanks for adding this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants