user1691278
user1691278

Reputation: 1885

Bar charts in Julia: changing location of xticks

I'm trying to accomplish the task here in Julia, but I'm struggling to do that.

If I do the following

v = [6 12 17 21 28 25 19 15];

bar(v')

I'll get a bar chart. However, I'm trying to align the xticks with the left edges of the bars, as done in the link. I tried to look but couldn't find a solution. Can I get a hint?

Upvotes: 2

Views: 1330

Answers (2)

Nils Gudat
Nils Gudat

Reputation: 13800

Which plotting library are you using? There's lots of good options in Julia, so it's important to specify when asking questions.

Assuming you're using Plots.jl (probably the most widely used package that matches the syntax you're showing in your question), this actually seems to be a surprisingly complicated issue. Some more (unhelpful) explanations below, but as a workaround I would do something close to what @attdonna suggests: you can always pass your x-axis ticks as a tuple of `(positions, values), so

bar(v', xticks = ((1:length(v)).-0.4, 1:length(v)))

does the trick.

---------------------------

Now to the less helpful explanations as to what's going wrong here: aligning of bars to edges is something that theoretically should work in Plots, from the docstring of bar:

help?> bar

  bar(x,y)
  bar!(x,y)

  Make a bar plot of y vs x.

  Arguments
  ≡≡≡≡≡≡≡≡≡≡≡

    •  bar_position: Symbol. Choose from :overlay (default), :stack. (warning: May not be implemented fully)

    •  bar_width: nothing or Number. Width of bars in data coordinates. When nothing, chooses based on x (or y when orientation = :h).

    •  bar_edges: Bool. Align bars to edges (true), or centers (the default)?

so bar_edges seems to be the keyword you're looking for. Alas when trying this it turns out that nothing changes when doing bar(v', bar_edges = true). The reason for this is that they keyword isn't actually implemented for the default (GR) backend - as Plots supports multiple backends, not all keyword arguments are available for each of them; you can check here which backends support which keywords.

That said, when doing

julia> using Plots; pyplot()
Plots.PyPlotBackend()

julia> bar(v', bar_edges = true)

nothing changes, so it seems this isn't working for some reason. Interestingly, when passing a first argument (for the x-axis positions) of the wrong length, PyPlot claims to be supporting passing of edges:

julia> bar([1 2], v')
ERROR: bar recipe: x must be same length as y (centers), or one more than y (edges).
        length(x)=1, length(y)=8

but unfortunately this doesn't seem to work either:

julia> bar(1:9, v')
ERROR: Expects 9 elements in each col of y, found 8.

(indeed the relevant docs say that allowing the passing of edges is a todo, so maybe this should be expected?)

So in short, this is something that should be easy to do with Plots.jl, but for some reason seems to have fallen through the cracks.

Upvotes: 1

attdona
attdona

Reputation: 18923

It is possible to position x labels at desired position with xaxis and format the values with xformatted options:

bar(v', xaxis = ((0.5, 9), 0.5:1:8), bar_width=1, xformatter=v->Int(ceil(v)))

Upvotes: 2

Related Questions