# Good ways to plot DataFrames content?

**URL:** <https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877>\
**Category:** Data\
**Created:** [May 9, 2025, 3:26pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877 "2025-05-09T15:26:12Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [May 9, 2025, 3:26pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/1 "2025-05-09T15:26:12Z")

</div>

I have never really gotten along with DataFrames very well (and to be fair, not used it that much). I figured I should ask if there are any straightforward recipes (or methods) for plotting the content of a `DataFrame`?  
(asking because I saw someone doing the equivalent code in pandas and he seemed to have had something relatively straightforward).

Right now, when I want to plot column `c2`, `c3`, and `c4` against `c1` and do:

```julia
using DataFrames, CSV, Plots
data = DataFrame(CSV.File("data.csv"))
plot(data.c1, [data.c2, data.c3, data.c4])

```

It works perfectly fin, but I figured there might be an actually nice way to do this. Trying to plot `DataFrame` columns directly seems to yield errors.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [May 9, 2025, 3:44pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/2 "2025-05-09T15:44:35Z")

</div>

Check this [other post](https://discourse.julialang.org/t/recipe-to-plot-simple-dataframes/64889/6) for one option.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [May 9, 2025, 3:48pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/3 "2025-05-09T15:48:23Z")

</div>

Looks good.

The plotting is not the actual problem, i.e. I can create the plot just fine. However, it feel like something where it likely could/would be something built into DataFrames/Plots already. And if this is the case, I would want to use that (especially in tutorials and stuff that might be published, which here is the case).

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 9, 2025, 3:52pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/4 "2025-05-09T15:52:17Z")

</div>

AlgebraOfGraphics.jl is your friend if you are seeking plots of tables that read off the columns automatically with some predefined meaning. Are you aware of it?

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [May 9, 2025, 4:10pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/5 "2025-05-09T16:10:41Z")

</div>

Wasn’t aware, thanks a lot!

---

<div class="post-metadata">

**Author:** ![mihalybaci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mihalybaci/32/13528_2.png) [@mihalybaci](https://discourse.julialang.org/u/mihalybaci)\
**Post date:** [May 9, 2025, 4:21pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/6 "2025-05-09T16:21:42Z")

</div>

I always found Gadfly.jl to be well-suited for plotting dataframes. There has not been much active development [according to github](https://github.com/GiovineItalia/Gadfly.jl/graphs/contributors), BUT that doesn’t mean it won’t work for your purposes. To be honest though, the last time I used it was probably at least 3 years ago.

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [May 9, 2025, 4:43pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/7 "2025-05-09T16:43:54Z")

</div>

## DataFramesMeta

The `@with` macro from DataFramesMeta.jl can make your Plots.jl command slightly shorter:

```julia-auto
@with data plot(:c1, [:c2, :c3, :c4])

```

or with labels for a fair comparison to the other options below:

```julia-auto
@with data plot(:c1, [:c2, :c3, :c4], labels=["c2" "c3" "c4"]) # no commas

```

* * *

## AlgebraOfGraphics

AlgebraOfGraphics.jl is great for analyzing complicated tabular data, but you will quickly find it wasn’t built for simple pre-grouped wide data like yours. There is a lot of extra boilerplate:

```julia-auto
draw(
    data(df) * # can't use data as variable name since it is an AoG function
    mapping(
        :c1,
        [:c2, :c3, :c4],
        color = dims(1) => renamer(["c2", "c3", "c4"]),
    ) *
    visual(Lines)
)

```

Here are some references on how to plot wide data with AoG:

[https://aog.makie.org/dev/tutorials/intro-v#Wide-data](https://aog.makie.org/dev/tutorials/intro-v#Wide-data)

> **[Wide Data with AlgebraOfGraphics.jl](https://tutorials.pumas.ai/html/PlottingInJulia/06-AoG-Wide.html)**

* * *

## Gadfly

I think the output plots from Gadfly.jl are nice and interactive, but I’ve found it somewhat buggy and slow to respond to issues. It also requires some boilerplate to handle wide data. (These DataFrame plotting packages tend to expect you want statistical plots of tall data.)

```julia-auto
plot(
    data,
    x=:c1,
    y=Col.value(:c2, :c3, :c4),
    color=Col.index(:c2, :c3, :c4),
    Geom.line,
)

```

Gadfly documentation on plotting wide data:

> **[Wide-formatted data - Plotting · Gadfly.jl](https://gadflyjl.org/dev/man/plotting/#Wide-formatted-data)**

* * *

## TidierPlots

TidierPlots.jl would be the most R-like, but I don’t have any experience with it. If you already know R, then I’d try that.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [May 9, 2025, 4:55pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/8 "2025-05-09T16:55:34Z")

</div>

Or TidierPlots:

> **[GitHub - TidierOrg/TidierPlots.jl: Tidier data visualization in Julia, modeled after...](https://github.com/TidierOrg/TidierPlots.jl)**
>
> Tidier data visualization in Julia, modeled after the ggplot2 R package.

🙂

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [May 9, 2025, 5:15pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/9 "2025-05-09T17:15:56Z")

</div>

[StatsPlots](https://docs.juliaplots.org/latest/generated/statsplots/#Original-author:-Thomas-Breloff-(@tbreloff),-maintained-by-the-JuliaPlots-members) is now part of Plots.jl, and has some convenient handling of columns, groups, etc.

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [May 9, 2025, 5:47pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/10 "2025-05-09T17:47:05Z")

</div>

StatsPlots’s `@df` seems to be no better than DataFrameMeta’s `@with` since you still have to manually provide the legend entries. The syntax and output are exactly the same:

```julia
@df data plot(:c1, [:c2, :c3, :c4], labels=["c2" "c3" "c4"])

```

Why can none of these packages automatically find the column names for the legend?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [May 9, 2025, 7:00pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/11 "2025-05-09T19:00:10Z")

</div>

> [@Nathan\_Boyer](#):
>
> Why can none of these packages automatically find the column names for the legend?

I have an issue tracking that on AlgebraOfGraphics [here](https://github.com/MakieOrg/AlgebraOfGraphics.jl/issues/474#issuecomment-2867275082).

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [May 9, 2025, 7:02pm UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/12 "2025-05-09T19:02:52Z")

</div>

> [@Nathan\_Boyer](#):
>
> Why can none of these packages automatically find the column names for the legend?

```julia
@df df plot(:c1, cols([:c2, :c3, :c4]))

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/6/a62dfed905f9adad29b7e388598dcf79e349a774.png)

I found this pretty much by accident, but passing them through a `cols` call seems to turn that feature on.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [May 12, 2025, 9:26am UTC](https://discourse.julialang.org/t/good-ways-to-plot-dataframes-content/128877/13 "2025-05-12T09:26:58Z")

</div>

Thanks everyone! This have been very useful 🙂
