0

the issue with the following is that in a small sample, whatever label I used, matplotlib plotted in the order of x/y arrays I gave. It just doesnt apply when the dataset increase.

data = {a:1, b:2, c:3}

def plot_bar_new(data, reverse):
    data = sorted(data.items(), key=lambda x:x[1], reverse=reverse)
    plotx, ploty = zip(*data)  # replaces the for-loop from plot_bar()
    locs = range(0, len(ploty))
    plt.figure()
    plt.bar(locs, ploty)
    plt.xticks(locs, plotx)
    plt.show()
plot_bar_new({1: 1, 2: 2, 3: 3}, False)
  1. I wish to understand why matplotlib doesnt plot the data in the order the user give
  2. I wish to plot the data I stream by the descending order of values,
  3. and the keys printed as is on the x label
  4. But the data is huge and I can only have every 300th x label visible.
3
  • 1
    If you want to receive help, you'll have to simplify your code quite a bit, the goal is to produce a Minimal, Complete, and Verifiable example. As far as I can tell, the first part of the code has nothing to do with your problem. Try calling your plots with a small made-up dictionnary of words and see where that gets you. Commented Oct 5, 2018 at 12:06
  • I'm lost on what the question is here. It currently shows the solution from the answer. And that solution seems to work fine. Commented Oct 6, 2018 at 2:05
  • I need xlabel plotted with the texts, not in the numbers that replace the texts for the sake of matplotlib recognizing the input arrays are already ordered Commented Oct 6, 2018 at 12:43

1 Answer 1

1

The problem is that you assume plotx being a list of labels that will be plotted on the X axis in the listed order. Actually, plotx is a list of absolute locations on the X axis at which the corresponding Y values will be plotted. Since the default X axis ascends from left to right, the order in which you list locations in plotx does not matter.

Consider the following plot function that lets you sort plotx in descending or ascending order by setting the reverse paramter to True or False:

def plot_bar(data, reverse):
    data = sorted(data.items(), key=lambda x:x[1], reverse=reverse)
    plotx =[]
    ploty =[]
    for item in data:
        plotx.append(item[0])
        ploty.append(item[1])
    plt.figure()
    plt.bar(plotx, ploty)
    plt.show()

Plot with plotx in ascending order:

plot_bar({1: 1, 2: 2, 3: 3}, False)

enter image description here

Now plot with plotx in descending order:

plot_bar({1: 1, 2: 2, 3: 3}, True)

enter image description here

As you can see, the order of locations in plotx does not matter.

To plot the Y values in the order they are listed in ploty, you can create a new list of locations locs to be used in plt.bar() and use plotx as labels for these locations:

def plot_bar_new(data, reverse):
    data = sorted(data.items(), key=lambda x:x[1], reverse=reverse)
    plotx, ploty = zip(*data)  # replaces the for-loop from plot_bar()
    locs = range(0, len(ploty))
    plt.figure()
    plt.bar(locs, ploty)
    plt.xticks(locs, plotx)
    plt.show()
plot_bar_new({1: 1, 2: 2, 3: 3}, False)

enter image description here

plot_bar_new({1: 1, 2: 2, 3: 3}, True)

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

In fact, I still need the x labels as is. Matplotlib is quite limited in functions it seems - 1. I dont quite understand why it has to be modified like this for plotting. 2. Id rather be able to view all the 9000 labels 3. takes too much time making labels at every 300th position visible
@HSL Then it would be helpful if you provide a minimal, complete, and verifiable example as Diziet Asahi suggests in his comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.