# \[ANN\] PythonCall and JuliaCall

**URL:** <https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778>\
**Category:** Package Announcements\
**Tags:** interoperability, python, pythoncall\
**Created:** [February 19, 2022, 10:49pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778 "2022-02-19T22:49:15Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [February 22, 2022, 8:27pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/45 "2022-02-22T20:27:13Z")

</div>

> [@sqr00t](#):
>
> Could there be a more self-explanatory way for Tabular data conversion instead of having pytable and PyTable as separate methods?

Can you elaborate on this? `pytable` sends a Julia table to Python, `PyTable` wraps a Python table as a Julia table, so they are opposites.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [February 22, 2022, 8:28pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/46 "2022-02-22T20:28:32Z")

</div>

Thanks for all the great questions everyone. I shall collate them into an FAQ.

---

<div class="post-metadata">

**Author:** ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)\
**Post date:** [February 22, 2022, 10:11pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/47 "2022-02-22T22:11:59Z")

</div>

Maybe thinking like multiprocessing - so having one python.exe for each thread

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [February 23, 2022, 7:04am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/48 "2022-02-23T07:04:26Z")

</div>

Coincidentally, we talked about this on the Julia HPC call yesterday (@jblaschke @staticfloat). The thing with one interpreter per thread is that you get in the “distributed business” of having to do something like `@everywhere pyimport("numpy")` and so on.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 23, 2022, 9:13am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/49 "2022-02-23T09:13:29Z")

</div>

Do you mean subinterpreters ([PEP 554](https://www.python.org/dev/peps/pep-0554/))? It looks like that it is still work-in-progress. It’s definitely an interesting addition to Python. But one of [the concerns](https://www.python.org/dev/peps/pep-0554/#concerns) was that it complicates C API usages. Also, since it looks like that at least the first version of subinterpreters share the GIL, we need to release GIL at Python-Julia boundary anyway (I’ve been wanting this in PyCall) to make it useful.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [February 23, 2022, 9:45am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/50 "2022-02-23T09:45:34Z")

</div>

I’ve tried using `PythonCall` + `CondaPkg` from pluto notebooks. Everything basically works fine: packages get installed and imported, plots displayed:

> **Screenshot**
>
> ![image](https://global.discourse-cdn.com/julialang/original/3X/7/c/7c36d6180cf6a147a008f71ff788ec1996b65d72.png)

The packages themselves seem to exist in a single copy in `~/.julia/scratchspaces` even if I create multiple notebooks that use matplotlib - they don’t duplicate for each notebook. I don’t really understand how this works though…

Still, new directories in `/tmp` are created for each new notebook run. They are created by Pluto, but Pluto only puts Project & Manifest files there that don’t take any noticeable space. “Apparent sizes” of those temporary dirs (speicifcally, the .CondaPkg subdirs) are 1 Gb, but actually most of the files are hardlinks I assume: each dir adds 150 Mb to disk usage, not 1 Gb. Is it possible to remove this duplication?

---

<div class="post-metadata">

**Author:** ![sqr00t](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sqr00t/32/33545_2.png) [@sqr00t](https://discourse.julialang.org/u/sqr00t)\
**Post date:** [February 23, 2022, 1:16pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/51 "2022-02-23T13:16:46Z")

</div>

thank you for the reply, I need to re-word to elaborate on what I meant.

having separate methods for conversion is fine, however it would be nice  
to have separate method names entirely rather than different casing, to  
minimise potential confusion.

alternatively there could be a flag/arg to specify conversion direction?

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [February 23, 2022, 7:14pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/53 "2022-02-23T19:14:54Z")

</div>

> [@aplavin](#):
>
> “Apparent sizes” of those temporary dirs (speicifcally, the .CondaPkg subdirs) are 1 Gb, but actually most of the files are hardlinks I assume: each dir adds 150 Mb to disk usage, not 1 Gb. Is it possible to remove this duplication?

Good to know not everything is copied. I doubt there’s anything we can do from Julia to reduce this, it’s just how Conda works I think.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [February 23, 2022, 7:20pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/54 "2022-02-23T19:20:47Z")

</div>

> [@sqr00t](#):
>
> having separate methods for conversion is fine, however it would be nice  
> to have separate method names entirely rather than different casing, to  
> minimise potential confusion.

It’s a naming convention you’ll have to just learn I’m afraid.

The good news is it’s consistent: `pyint`, `pylist`, `pydict`, `pytable` etc all convert a Julia object to a Python one, and `PyList`, `PyDict`, `PyTable` etc all wrap a Python object to give a more Julian interface.

The reason the latter are capitalised is that they are classes: e.g. `PyList{T} <: AbstractArray{T}`. The former are lowercase because they are all functions and all return `Py`.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [February 23, 2022, 7:24pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/55 "2022-02-23T19:24:23Z")

</div>

> [@Impressium](#):
>
> Maybe thinking like multiprocessing - so having one python.exe for each thread

PythonCall should work fine with Julia’s multiprocessing packages.

Having multiple interpreters or threads within a single process isn’t currently supported.

---

<div class="post-metadata">

**Author:** ![sqr00t](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sqr00t/32/33545_2.png) [@sqr00t](https://discourse.julialang.org/u/sqr00t)\
**Post date:** [February 24, 2022, 3:42pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/56 "2022-02-24T15:42:51Z")

</div>

Thank you for the detailed explanation!

---

<div class="post-metadata">

**Author:** ![George9000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/george9000/32/23619_2.png) [@George9000](https://discourse.julialang.org/u/George9000)\
**Post date:** [March 1, 2022, 1:45am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/57 "2022-03-01T01:45:13Z")

</div>

Noticed that the [JuliaPy](https://github.com/JuliaPy) github organization did not list PythonCall among the repos – it should.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 1, 2022, 1:49am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/58 "2022-03-01T01:49:40Z")

</div>

[`PythonCall.jl`](https://github.com/cjdoris/PythonCall.jl) is _ **not** _ under the JuliaPy organisation.

---

<div class="post-metadata">

**Author:** ![George9000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/george9000/32/23619_2.png) [@George9000](https://discourse.julialang.org/u/George9000)\
**Post date:** [March 1, 2022, 1:56am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/59 "2022-03-01T01:56:09Z")

</div>

My bad. I’d assumed that the Julia orgs were similar to [R task views](https://cran.r-project.org/web/views/): a convenient way to navigate the many packages available for a particular domain. Not so…

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 1, 2022, 2:01am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/60 "2022-03-01T02:01:35Z")

</div>

“Julia orgs” are simply [GitHub organisations](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations). There is nothing formal like those R task views.

---

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [March 4, 2022, 11:36am UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/61 "2022-03-04T11:36:08Z")

</div>

EDIT: this message is about having `plot()` instead of `plt.plot()`.

As a quick fix to run plotting code with PythonCall.jl, the following worked well. Do you know of a better/simpler way?

```julia
const mplot_funcs = (:figure, :gca, :subplot, :subplots_adjust,
                     :plot, :scatter, :bar,
                     :title, :xlabel, :ylabel, :xticks, :legend, :annotate,
                     :axhline, :axvline, :xlim, :ylim, :savefig )

for f in mplot_funcs
    @eval $f(args...; kws...) = plt.$f(args...; kws...)
end

```

and then the usual plotting

---

<div class="post-metadata">

**Author:** ![Impressium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/impressium/32/19575_2.png) [@Impressium](https://discourse.julialang.org/u/Impressium)\
**Post date:** [March 4, 2022, 12:47pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/62 "2022-03-04T12:47:04Z")

</div>

I’m just curious. How is it done? Python is known for its GIL

---

<div class="post-metadata">

**Author:** ![icweaver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/icweaver/32/45764_2.png) [@icweaver](https://discourse.julialang.org/u/icweaver)\
**Post date:** [March 4, 2022, 3:27pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/63 "2022-03-04T15:27:34Z")

</div>

> [@Paul\_Soderlind](#):
>
> As a quick fix to run plotting code with PythonCall.jl, the following worked well. Do you know of a better/simpler way?

I could be misunderstanding, but do you mean just doing something like this?

> [@\[ANN\] CondaPkg.jl v0.2.6 - now with REPL integration!](https://discourse.julialang.org/t/ann-condapkg-jl-v0-2-6-now-with-repl-integration/75370/8):
>
> Yea, I used to be a somewhat heavy user of PyCall.jl, but since discovering [PythonCall.jl](https://github.com/cjdoris/PythonCall.jl)+[CondaPkg.jl](https://github.com/cjdoris/CondaPkg.jl)+[MicroMamba.jl](https://github.com/cjdoris/MicroMamba.jl), I haven’t looked back. The fact that this fresh take on python interop uses project specific envs AND scratch spaces AND artifacts AND versatile show methods AND … is just insane. I mean c’mon:

So basically:

```julia
@py import matplotlib.pyplot as plt
plt.plot(<stuff>)

```

Edit: haha, also just saw @aplavin doing the same thing earlier in the thread!

> [@\[ANN\] PythonCall and JuliaCall](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/50):
>
> I’ve tried using PythonCall + CondaPkg from pluto notebooks. Everything basically works fine: packages get installed and imported, plots displayed: play_button Screenshot The packages themselves seem to exist in a single copy in ~/.julia/scratchspaces even if I create multiple notebooks that use matplotlib - they don’t duplicate for each notebook. I don’t really understand how this works though… Still, new directories in /tmp are created for each new notebook run. They are created by Pluto, but Pluto onl…

---

<div class="post-metadata">

**Author:** ![Paul\_Soderlind](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paul_soderlind/32/1753_2.png) [@Paul\_Soderlind](https://discourse.julialang.org/u/Paul_Soderlind)\
**Post date:** [March 4, 2022, 3:41pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/64 "2022-03-04T15:41:38Z")

</div>

Thanks for asking. The purpose of the message was to discuss how we could use `plot()` instead of `plt.plot()`. This would avoid rewriting code that currently uses `PyPlot.jl`.

---

<div class="post-metadata">

**Author:** ![icweaver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/icweaver/32/45764_2.png) [@icweaver](https://discourse.julialang.org/u/icweaver)\
**Post date:** [March 4, 2022, 4:09pm UTC](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778/65 "2022-03-04T16:09:21Z")

</div>

Ahh, gotcha, thanks for the clarification! Would something like this work then?

```julia
@py import matplotlib.pyplot: plot, scatter, bar

```

[Previous page](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778.md?page=2)

[Next page](https://discourse.julialang.org/t/ann-pythoncall-and-juliacall/76778.md?page=4)
