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?
fig = plt.figure(figsize=(10, 6))
plt.figure(figsize=(10, 6))
. plt.xticks
python 3.11.2
, pandas 2.0.1
, matplotlib 3.7.1
# 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)
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
.
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.
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)])
matplotlib
is the default backend for pandas.DataFrame.plot
.
matplotlib.axes.Axes
to ax
, which is the explicit "Axes" interface .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])
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.