dia
dia

Reputation: 431

Matplotlib plot doesnt reflect the ordered set of data

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.

Upvotes: 0

Views: 80

Answers (1)

SergiyKolesnikov
SergiyKolesnikov

Reputation: 7815

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

Upvotes: 1

Related Questions