# Drawing stripped dodged bar charts in Makie

**URL:** <https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [May 13, 2024, 7:06pm UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208 "2024-05-13T19:06:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![harrysw](https://avatars.discourse-cdn.com/v4/letter/h/aeb1de/32.png) [@harrysw](https://discourse.julialang.org/u/harrysw)\
**Post date:** [May 13, 2024, 7:06pm UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208/1 "2024-05-13T19:06:20Z")

</div>

I tried to create a dodged stripped barplot where bars from each plot have different strip directions.

After consulting the documentation about [dodged bars](https://docs.makie.org/stable/reference/plots/barplot/) and [stripped bars](https://beautiful.makie.org/examples/2d/bars/stripped_bars), I came up with the following short example:

```julia
using CairoMakie

cats = repeat(Float64[1, 2], inner=2)
heights = repeat(Float64[1, 2], outer=2)
group = repeat([1, 2], outer=2)

directions = [[1.0, 1.0], [-1.0, 1.0]]
patterns = Any[Makie.LinePattern(background_color=(:red, 0.5), direction=direction) for direction in directions]

fig = Figure()
barplot(fig[1, 1], cats, heights, dodge=group, color=patterns[group])
fig

```

However, I got the following error message:

```julia
ERROR: MethodError: Cannot `convert` an object of type Makie.LinePattern to an object of type Float32

```

The individual line patterns seem to be valid, as the following code that uses just one line pattern for every bar works fine:

```julia
fig2 = Figure()
barplot(fig2[1, 1], cats, heights, dodge=group, color=patterns[1])
fig2

```

 ![plots](https://global.discourse-cdn.com/julialang/original/3X/c/1/c1a12b7f9fa3d1b38fad03857b57228dac46cabe.jpeg)

I wonder where my code went wrong. Thank you very much for the help!

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [July 30, 2024, 7:14am UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208/2 "2024-07-30T07:14:52Z")

</div>

@jules I am currently also stack with this. Is there an easy work around ?  
(maybe sorry for the audacity to ping directly 😅)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [July 30, 2024, 8:53am UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208/3 "2024-07-30T08:53:19Z")

</div>

Patterns currently only work when there’s one per plot type. So you can’t use that with stacking, you’d have to create multiple barplots and make the stacking yourself using `offset`. But it’s not so difficult if you make one matrix of heights and then `cumsum` it along one dimension

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [August 6, 2024, 11:35am UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208/4 "2024-08-06T11:35:30Z")

</div>

Some code that does that

```julia
using CairoMakie, Random

# data
begin
	n = 10
	k = 3
	rng = Random.MersenneTwister(0);
	
	ys = [rand(rng, n) for _ in 1:k]
	xs = [1:n for _ in 1:k]
end;

# transform data
begin
	ys_flat = reduce(vcat, ys)
	xs_flat = reduce(vcat, xs)
	groups = reduce(vcat, [fill(i, length(x)) for (i,x) in enumerate(xs)])
end;

# plot data
begin
	colors = Makie.wong_colors()
	
	patterns = let
		patternsymbols = ["/", "x", "-"]
	[Pattern(pat, background_color=col, linecolor = :black) for (col,pat) in zip(colors, patternsymbols)]
	end

	offsets = let
		ys_cumsum = accumulate(+, ys[1:end-1])
		pushfirst!(ys_cumsum, zero(ys_cumsum[1]))
	end
end;

# get Makie dodge x values
function compute_x(x, dodge; width=1, gap=0.2, dodge_gap=0.03)
    scale_width(dodge_gap, n_dodge) = (1 - (n_dodge - 1) * dodge_gap) / n_dodge
    function shift_dodge(i, dodge_width, dodge_gap)
        (dodge_width - 1) / 2 + (i - 1) * (dodge_width + dodge_gap)
    end
    width *= 1 - gap
    n_dodge = maximum(dodge)
    dodge_width = scale_width(dodge_gap, n_dodge)
    shifts = shift_dodge.(dodge, dodge_width, dodge_gap)
    return x .+ width .* shifts
end

```

```julia
# Normal dodge barplot
let
	barplot(xs_flat, ys_flat; dodge=groups, color=colors[groups])
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/f/4f8acbe963e5c786766a81b053f645de2fff3204.png)

```julia
# Dodge barplot with patterns
let
	fig = Figure()

	a = Axis(fig[1,1])

	uniquegroups = unique(groups)
	
	dodge_gap = 0.03 #Makie default
	gap = 0.2 #Makie default
	width = 1 #Makie default	
	widthplot = width / (length(uniquegroups) + 0.2) # work around
	
	xs_explicit_flat = compute_x(xs_flat, groups; width, gap, dodge_gap)

	for (g,pat) in zip(uniquegroups, patterns)
		indices = findall(==(g), groups)
		ys_g = ys_flat[indices]
		xs_g = xs_explicit_flat[indices]
		barplot!(a, xs_g, ys_g; color=pat, dodge_gap, gap, width=widthplot)
	end
	
	fig
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/d/9d372e461735b436192cf0f195f7692874038062.png)

```julia
# Stacked barplot with pattern
let
	fig = Figure()

	a = Axis(fig[1,1])

	uniquegroups = unique(groups)
	
	dodge_gap = 0.03 #Makie default
	gap = 0.2 #Makie default
	width = 1 #Makie default	
	widthplot = width / (length(uniquegroups) + 0.2) # work around

	for (g,pat,offs) in zip(uniquegroups, patterns, offsets)
		indices = findall(==(g), groups)
		ys_g = ys_flat[indices]
		xs_g = xs_flat[indices]
		barplot!(a, xs_g, ys_g; color=pat, offset=offs, gap, width=widthplot)
	end
	
	fig
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/9/992292ea4b73a95d31d8332782d45d025d8e0482.png)

---

<div class="post-metadata">

**Author:** ![filchristou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/filchristou/32/26760_2.png) [@filchristou](https://discourse.julialang.org/u/filchristou)\
**Post date:** [August 6, 2024, 11:40am UTC](https://discourse.julialang.org/t/drawing-stripped-dodged-bar-charts-in-makie/114208/5 "2024-08-06T11:40:48Z")

</div>

Credits to [Errorbars for grouped barplots · Issue #3300 · MakieOrg/Makie.jl · GitHub](https://github.com/MakieOrg/Makie.jl/issues/3300) for the `compute_x` function. @jules do you think if the `compute_x` data could ever be provided by Makie directly ? Plus I had to use `widthplot = width/3.2` instead of `width` for plotting. These both look very hacky and it would be nice if Makie could provide some interfaces/funcionalities here.
