简体   繁体   中英

How to reduce the number of tick labels on a bar plot

The following bar graph is too cluttered on the x axis.

Is there a manner in which I can increment my ticks? Instead of showing every tick between 18-55, it increments by 3 or 5 (or more) so it looks nicer? I noticed that when I ran a line plot, it incremented automatically by 10.**

import matplotlib as mpl
from matplotlib import pyplot as plt
import numpy as np

agesx = [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
          36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]

py_devy = [20046, 17100, 20000, 24744, 30500, 37732, 41247, 45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640, 84666,
            84392, 78254, 85000, 87038, 91991, 100000, 94796, 97962, 93302, 99240, 102736, 112285, 100771, 104708, 108423, 101407, 112542, 122870, 120000]

js_devy = [16446, 16791, 18942, 21780, 25704, 29000, 34372, 37810, 43515, 46823, 49293, 53437, 56373, 62375, 66674, 68745, 68746, 74583, 79000,
            78508, 79996, 80403, 83820, 88833, 91660, 87892, 96243, 90000, 99313, 91660, 102264, 100000, 100000, 91660, 99240, 108000, 105000, 104000]

all_devy = [17784, 16500, 18012, 20628, 25206, 30252, 34368, 38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752, 77232,
         78000, 78508, 79536, 82488, 88935, 90000, 90056, 95000, 90000, 91633, 91660, 98150, 98964, 100000, 98988, 100000, 108923, 105000, 103117]

width = 0.25
x_indexes = np.arange(len(agesx))
 
plt.xticks(ticks=x_indexes,labels=agesx)

plt.style.use("seaborn-dark")
plt.bar(x_indexes-width, all_devy, width=width, label= "All Devs")
plt.bar(x_indexes,py_devy,width=width, label= "Python Devs")
plt.bar(x_indexes + width, js_devy, width=width, label= "Javascript Dev")

plt.title("Median Developer Salaries by Age (USD)")
plt.xlabel("Ages")
plt.ylabel("Salary (USD)")
plt.tight_layout()

plt.legend()
plt.show()

This results in the following graph:

图一

Initially I thought that I could solve this just by

plt.xticks(np.arange(18,55,3))

However it results in this output:

尝试图

How can I modify this to get the graph to begin at 18 as opposed to starting the tick at position 18?

1. Increase Figure Size

# increase the figure size
plt.figure(figsize=(10, 6))

plt.bar(x_indexes-width, all_devy, width=width, label= "All Devs")
plt.bar(x_indexes,py_devy,width=width, label= "Python Devs")
plt.bar(x_indexes + width, js_devy, width=width, label= "Javascript Dev")
_ = plt.xticks(ticks=x_indexes, labels=agesx)

在此处输入图像描述

2. Specify the xtick labels with plt.xticks

  • plt.xticks(np.arange(18, 55, 3)) didn't work because, unlike a line plot, bar plot ticks are 0 indexed. print(plt.gca().get_xticklabels()) shows '18' at index 0 .
    • You preset the ticks and labels with plt.xticks(ticks=x_indexes, labels=agesx)
    • [v if i%2 == 0 else '' for i, v in enumerate(agesx)] uses a list-comprehension to set every other label to an empty string.
      • Increase 2, for fewer tick labels.
plt.bar(x_indexes-width, all_devy, width=width, label= "All Devs")
plt.bar(x_indexes,py_devy,width=width, label= "Python Devs")
plt.bar(x_indexes + width, js_devy, width=width, label= "Javascript Dev")

# adjust the frequency of the visible labels; the number of ticks and labels must be the same
_ = plt.xticks(ticks=range(len(agesx)), labels=[v if i%2 == 0 else '' for i, v in enumerate(agesx)])

在此处输入图像描述


import pandas as pd

# load data to pandas
data = {'Python Devs': py_devy, 'Javascript Devs': js_devy, 'All Devs': all_devy}
df = pd.DataFrame(data=data, index=agesx)

# 1. plot the bars with rotated labels
ax = df.plot(kind='bar', width=0.85, rot=90)

# 2. plot with increased figure size
ax = df.plot(kind='bar', width=0.85, figsize=(10, 6), rot=0)

# 3. plot horizontal bars, which may be better for many bars, and long labels
ax = df.plot(kind='barh', width=0.85, figsize=(6, 7))

# 4. every other tick label
ax = df.plot(kind='bar', width=0.85, rot=0, xticks=range(len(df.index))[::2])
_ = ax.set_xticklabels(df.index[::2])

plot1 plot2 plot3 plot4

df.head()

    Python Devs  Javascript Devs  All Devs
18        20046            16446     17784
19        17100            16791     16500
20        20000            18942     18012
21        24744            21780     20628
22        30500            25704     25206

The following bar graph is too cluttered on the x axis.

IMHO the clutter is Matplotlib trying to tell you that your graph is quite crowded.

运行平均值

import matplotlib.pyplot as plt
import numpy as np

agesx = [18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]
py_devy =  [20046, 17100, 20000, 24744, 30500, 37732, 41247, 45372, 48876, 53850, 57287, 63016, 65998, 70003, 70000, 71496, 75370, 83640, 84666, 84392, 78254, 85000, 87038, 91991, 100000, 94796, 97962, 93302, 99240, 102736, 112285, 100771, 104708, 108423, 101407, 112542, 122870, 120000]
js_devy =  [16446, 16791, 18942, 21780, 25704, 29000, 34372, 37810, 43515, 46823, 49293, 53437, 56373, 62375, 66674, 68745, 68746, 74583, 79000, 78508, 79996, 80403, 83820, 88833, 91660, 87892, 96243, 90000, 99313, 91660, 102264, 100000, 100000, 91660, 99240, 108000, 105000, 104000]
all_devy = [17784, 16500, 18012, 20628, 25206, 30252, 34368, 38496, 42000, 46752, 49320, 53200, 56000, 62316, 64928, 67317, 68748, 73752, 77232, 78000, 78508, 79536, 82488, 88935, 90000, 90056, 95000, 90000, 91633, 91660, 98150, 98964, 100000, 98988, 100000, 108923, 105000, 103117]

rmean = lambda l,n:[sum(t)/n for t in zip(*(l[i:]for i in range(n)))]
N = 5

plt.style.use("seaborn-v0_8-dark")
for y, label in zip((py_devy,js_devy,all_devy),
                  'Python JavaScript all'.split()):
     plt.plot(rmean(agesx, N), rmean(y, N), label=label+' devs')
plt.ylim((-1000, 120000))
plt.grid()
plt.legend()
plt.xlabel('Central Age for the running mean')
plt.ylabel('Median Salary, €')
plt.suptitle('              Median Developer Salary')
plt.title('— running mean over %d age classes —'%N, size='small')
plt.tight_layout()
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM