Plotting with more colors in matplotlib - python

I am trying to plot a scatter plot using matplotlib, i am getting " IndexError: pop from empty list" error and I am not sure how to fix it.
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import time
import itertools
d = {'5000cca229d10d09': {374851: 1}, '5000cca229cf3f8f': {372496:3},'5000cca229d106f9': {372496: 3, 372455: 2}, '5000cca229d0b3e4': {380904: 2, 380905: 1, 380906: 1, 386569: 1}, '5000cca229d098f8': {379296: 2, 379297: 2, 379299: 2, 379303: 1, 379306: 1, 379469: 1, 379471: 1, 379459: 1, 379476: 1, 379456: 4, 379609: 4}, '5000cca229d03957': {380160: 3, 380736: 3, 380162: 1, 380174: 1, 381072: 2, 379608: 2, 380568: 3, 380569: 1, 380570: 1, 379296: 3, 379300: 1, 380328: 3, 379306: 1, 380331: 1, 379824: 2, 379825: 1, 379827: 1, 380344: 1, 379836: 1, 379456: 3, 380737: 1, 380739: 1, 379462: 1, 379476: 1, 379992: 3, 379609: 1, 379994: 1, 379611: 1, 379621: 1, 380006: 1, 380904: 3, 380905: 1, 380907: 1, 380535: 3, 380536: 1, 380538: 1}, '5000cca229cf6d0b': {372768: 10, 372550: 15, 372616: 14, 372617: 20, 372653: 3, 372505: 2}, '5000cca229cec4f1': {372510: 132}}
colors = list("rgbcmyk")
for data_dict in d.values():
x = data_dict.keys()
#print x
#X= time.asctime(time.localtime(x))
y = data_dict.values()
#plt.scatter(x,y,color=colors.pop(),s = 60)
plt.scatter(x,y,color=colors.pop(),s = 90, marker='^')
plt.ylabel("Errors" , fontsize=18, color="Green")
plt.xlabel("Occured on",fontsize=18, color="Green")
plt.title("DDN23b", fontsize=25, color="Blue")
plt.gca().get_xaxis().get_major_formatter().set_useOffset(False)
plt.xticks(rotation='vertical')
#plt.ylim(min(y),max(y))
#plt.grid()
#for x, y in dict(itertools.chain(*[item.items() for item in d.values()])).items():
# plt.text(x, y, time.strftime("%m/%d/%y, %H:%M:%S", time.localtime(x*3600)), ha='center', va='top', rotation='vertical', fontsize = '11', fontstyle = 'italic', color = '#844d4d')
plt.xticks(plt.xticks()[0], [time.strftime("%m/%d/%y, %H:%M:%S", time.localtime(item)) for item in plt.xticks()[0]*3600])
plt.legend(d.keys())
mng = plt.get_current_fig_manager()
mng.resize(*mng.window.maxsize())
plt.subplots_adjust(bottom=.24,right=.98,left=0.03,top=.89)
plt.grid()
plt.show()
I have several data sets for d, and d is a dictionary. when the data set is smaller, it works without any errors. When the data set is large, it runs out of collars. How do I add more colors to the list so every key in "d" gets its own color.
Feel free to edit my code and make suggestions.

Colormaps are callable. When passed a float between 0 and 1, it returns an RGBA color:
In [73]: jet = plt.cm.jet
In [74]: jet(0.5)
Out[74]: (0.49019607843137247, 1.0, 0.47754585705249841, 1.0)
So, you could generate len(d) number of colors by passing the NumPy array np.linspace(0, 1, len(d)) to the colormap:
jet = plt.cm.jet
colors = jet(np.linspace(0, 1, len(d)))
The colors selected will then be equally spaced along the colormap gradient.
import matplotlib.pyplot as plt
import numpy as np
import time
d = {'5000cca229d10d09': {374851: 1}, '5000cca229cf3f8f': {372496:3},'5000cca229d106f9': {372496: 3, 372455: 2}, '5000cca229d0b3e4': {380904: 2, 380905: 1, 380906: 1, 386569: 1}, '5000cca229d098f8': {379296: 2, 379297: 2, 379299: 2, 379303: 1, 379306: 1, 379469: 1, 379471: 1, 379459: 1, 379476: 1, 379456: 4, 379609: 4}, '5000cca229d03957': {380160: 3, 380736: 3, 380162: 1, 380174: 1, 381072: 2, 379608: 2, 380568: 3, 380569: 1, 380570: 1, 379296: 3, 379300: 1, 380328: 3, 379306: 1, 380331: 1, 379824: 2, 379825: 1, 379827: 1, 380344: 1, 379836: 1, 379456: 3, 380737: 1, 380739: 1, 379462: 1, 379476: 1, 379992: 3, 379609: 1, 379994: 1, 379611: 1, 379621: 1, 380006: 1, 380904: 3, 380905: 1, 380907: 1, 380535: 3, 380536: 1, 380538: 1}, '5000cca229cf6d0b': {372768: 10, 372550: 15, 372616: 14, 372617: 20, 372653: 3, 372505: 2}, '5000cca229cec4f1': {372510: 132}}
jet = plt.cm.jet
colors = jet(np.linspace(0, 1, len(d)))
fig, ax = plt.subplots()
for color, data_dict in zip(colors, d.values()):
x = data_dict.keys()
y = data_dict.values()
ax.scatter(x,y,color=color, s = 90, marker='^')
plt.ylabel("Errors" , fontsize=18, color="Green")
plt.xlabel("Occured on",fontsize=18, color="Green")
plt.title("DDN23b", fontsize=25, color="Blue")
ax.get_xaxis().get_major_formatter().set_useOffset(False)
plt.xticks(rotation='vertical')
plt.xticks(plt.xticks()[0],
[time.strftime("%m/%d/%y, %H:%M:%S", time.localtime(item))
for item in plt.xticks()[0]*3600])
plt.legend(d.keys())
plt.subplots_adjust(bottom=.24,right=.98,left=0.03,top=.89)
plt.grid()
plt.show()

Related

Add column data to ASE Atom Object json File

I am trying to add Columns data i.e. Temperature, Molarity etc to an ASE Atom Object in a .json file, which is formated as follows,
{"1": {
"cell": {"__ndarray__": [[3, 3], "float64", [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]},
"ctime": 23.062761176728078,
"mtime": 23.062761176728078,
"numbers": {"__ndarray__": [[63], "int32", [35, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]},
"pbc": {"__ndarray__": [[3], "bool", [false, false, false]]},
"positions": {"__ndarray__": [[63, 3], "float64", [1.02088, -0.07049, -0.03212, 1.0973, -3.2788, 3.87728, 2.61528, -3.29081, 3.8975, 3.15998, -3.00975, 2.50308, 4.67887, -3.0308, 2.49295, 5.20986, -2.78486, 1.07948, 6.73103, -2.81918, 1.01952, 7.26742, -4.1725, 1.4482, 8.77632, -4.17848, 1.43408, 9.26424, -5.51692, 1.94735, 10.77335, -5.50232, 1.97542, 11.28332, -6.82712, 2.48445, 12.80015, -6.79016, 2.50407, 13.29845, -8.13591, 2.97445, 14.81673, -8.19203, 2.94905, 15.31473, -9.54583, 3.43333, 14.81153, -10.67945, 2.53755, 15.25421, -12.06622, 3.00288, 16.77287, -12.17072, 3.02548, 14.67692, -12.39547, 4.37401, 14.70058, -13.08165, 1.99749, 0.6998, -3.46574, 4.87783, 0.71285, -4.05308, 3.20454, 0.7212, -2.31013, 3.5324, 2.967, -4.26501, 4.25235, 2.97929, -2.53549, 4.60251, 2.81017, -2.03287, 2.15577, 2.78347, -3.76456, 1.80124, 4.99943, -4.00574, 2.86952, 5.07838, -2.27055, 3.17637, 4.86624, -1.80795, 0.71974, 4.80511, -3.54038, 0.39431, 7.14617, -2.02959, 1.65792, 7.05652, -2.60496, -0.00639, 6.87826, -4.96031, 0.78846, 6.94637, -4.41838, 2.46536, 9.15862, -3.37521, 2.07596, 9.15115, -3.99773, 0.42005, 8.89989, -6.32829, 1.30471, 8.87374, -5.70588, 2.95654, 11.12913, -4.69141, 2.62325, 11.16301, -5.3113, 0.96742, 10.92897, -7.63817, 1.83648, 10.89587, -7.0253, 3.4914, 13.15552, -5.99488, 3.16603, 13.17901, -6.58063, 1.49654, 12.87249, -8.89368, 2.31322, 12.93068, -8.34259, 3.98611, 15.22396, -7.40473, 3.5943, 15.18383, -7.99669, 1.93376, 14.98703, -9.68396, 4.46777, 16.4104, -9.51576, 3.43886, 15.16831, -10.54649, 1.51163, 13.71549, -10.72486, 2.51819, 17.16035, -11.53426, 3.81916, 17.15315, -11.86178, 2.05054, 17.04038, -13.21533, 3.22842, 15.13502, -11.7425, 5.12017, 14.91931, -13.43378, 4.61043, 13.59434, -12.25198, 4.34169, 15.10052, -12.84284, 1.00836, 13.60916, -13.00919, 1.99737, 15.01561, -14.08621, 2.30661]]},
"unique_id": "8fc6b41faacf669e07523ea9932aae59",
"user": null},
"ids": [1],
"nextid": 2}
So far I have tried adding an additional node to the positions graph, adding a 4th dimension to the positions graph, incrementing one axis of the positions graph by the column value, adding a new key to the json file, and adding the value within the built in "tags" key, so far all have either had no effect or have given an error which cannot be solved without editing the ASE library. I am not sure what to try next or if I have missed something obvious.
Full Code:
https://github.com/nfurth1/MatDeepLearn

Sharing Y-axis in a matplotlib subplots

I have been trying to create a matplotlib subplot (1 x 3) with horizontal bar plots on either side of a lineplot.
It looks like this:
The code for generating the above plot -
u_list = [2, 0, 0, 0, 1, 5, 0, 4, 0, 0]
n_list = [0, 0, 1, 0, 4, 3, 1, 1, 0, 6]
arr_ = list(np.arange(10, 11, 0.1))
data_ = pd.DataFrame({
'points': list(np.arange(0, 10, 1)),
'value': [10.4, 10.5, 10.3, 10.7, 10.9, 10.5, 10.6, 10.3, 10.2, 10.4][::-1]
})
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(20, 8))
ax1 = plt.subplot(1, 3, 1)
sns.barplot(u_list, arr_, orient="h", ax=ax1)
ax2 = plt.subplot(1, 3, 2)
x = data_['points'].tolist()
y = data_['value'].tolist()
ax2.plot(x, y)
ax2.set_yticks(arr_)
plt.gca().invert_yaxis()
ax3 = plt.subplot(1, 3, 3, sharey=ax1, sharex=ax1)
sns.barplot(n_list, arr_, orient="h", ax=ax3)
fig.tight_layout()
plt.show()
Edit
How do I share the y-axis of the central line plot with the other horizontal bar plots?
I would set the limits of all y-axes to the same range, set the ticks in all axes and than set the ticks/tick-labels of all but the most left axis to be empty. Here is what I mean:
from matplotlib import pyplot as plt
import numpy as np
u_list = [2, 0, 0, 0, 1, 5, 0, 4, 0, 0]
n_list = [0, 0, 1, 0, 4, 3, 1, 1, 0, 6]
arr_ = list(np.arange(10, 11, 0.1))
x = list(np.arange(0, 10, 1))
y = [10.4, 10.5, 10.3, 10.7, 10.9, 10.5, 10.6, 10.3, 10.2, 10.4]
fig, axs = plt.subplots(1, 3, figsize=(20, 8))
axs[0].barh(arr_,u_list,height=0.1)
axs[0].invert_yaxis()
axs[1].plot(x, y)
axs[1].invert_yaxis()
axs[2].barh(arr_,n_list,height=0.1)
axs[2].invert_yaxis()
for i in range(1,len(axs)):
axs[i].set_ylim( axs[0].get_ylim() ) # align axes
axs[i].set_yticks([]) # set ticks to be empty (no ticks, no tick-labels)
fig.tight_layout()
plt.show()
This is a minimal example and for the sake of conciseness, I refrained from mixing matplotlib and searborn. Since seaborn uses matplotlib under the hood, you can reproduce the same output there (but with nicer bars).

Python - Problem to paint different colours in x,y and z axis with Ipyvolume library

I'm trying to create a 3D plot with Python library "ipyvolume" where every point in the plot has a colour. The points can be repeated colours. There is a problem when it paint the points in the plot. Some idea to fix this?
Import the libraries:
import pandas as pd
import numpy as np
import ipyvolume as ipv
Load the data:
dataframe = pd.read_csv("C:/Users/j/Desktop/K - Means/test.csv",sep=",")
dataframe.head()
Picture about Dataframe:
Dataframe
Creation of the axes:
X = np.array(dataframe[["op","ex","ag"]])
y = np.array(dataframe['categoria'])
Information about X:
array([[34.297953, 41.948819, 29.370315],
[44.986842, 37.938947, 24.279098],
[41.733854, 38.999896, 34.645521],
[40.377154, 52.337538, 31.082154],
[36.664677, 48.530806, 31.138871],
[33.531771, 43.211667, 25.786667],
[31.851102, 47.182362, 19.594331],
[31.865118, 55.377559, 36.258346],
[46.393488, 39.93031 , 16.658062],
[39.436667, 32.966288, 32.291591],
[52.750992, 41.698855, 17.057176],
[41.328182, 39.173333, 21.070505],
[54.407727, 34.104318, 18.771818],
[47.610076, 39.439545, 21.438409],
[39.435149, 41.479403, 21.004104],
[48.617348, 43.617955, 19.263258],
[40.073543, 44.194724, 33.921417],
[43.37292 , 43.792263, 21.067737],
[49.792403, 41.435581, 16.433953],
[30.020465, 44.29969 , 39.117984],
[36.909459, 51.947297, 34.687568],
[50.594462, 41.383154, 17.896538],
[34.186667, 18.693542, 9.682292],
[31.215455, 44.180909, 32.87 ],
[47.27686 , 41.973372, 12.40186 ],
[45.369773, 35.925909, 23.478258],
[35.943438, 45.519531, 28.02125 ],
[36.272348, 40.065152, 28.706894],
[44.501603, 46.598931, 29.535038],
[49.028308, 38.450462, 19.791538],
[34.235923, 41.231615, 14.153692],
[53.11048 , 39.00608 , 17.2064 ],
[49.28542 , 42.117786, 21.008931],
[52.895725, 38.620229, 19.972748],
[30.691797, 59.824844, 33.395938],
[34.949528, 50.177402, 36.325276],
[41.76596 , 49.865253, 30.071414],
[30.825938, 55.912578, 29.489922],
[38.948976, 44.460866, 27.345827],
[46.955854, 35.376179, 23.747561],
[45.053969, 48.950992, 24.374427],
[45.088504, 50.765276, 25.71252 ],
[42.444615, 45.780231, 24.745615],
[40.046439, 37.722197, 30.568258],
[52.535221, 35.290973, 15.793009],
[56.691163, 31.135698, 20.439651],
[48.709282, 44.728513, 19.387538],
[53.453713, 38.522321, 16.655907],
[31.450855, 45.490983, 40.583162],
[31.891474, 53.373368, 24.296316],
[49.077731, 45.670798, 17.449202],
[36.196989, 42.358817, 24.191613],
[38.91342 , 46.979524, 28.669524],
[60.225087, 28.902609, 14.337043],
[35.545054, 30.295484, 39.422796],
[56.815859, 38.419375, 13.961641],
[49.47 , 30.96626 , 23.053053],
[47.811742, 41.36447 , 20.816439],
[35.779512, 31.227724, 27.689919],
[55.974031, 33.09 , 21.330698],
[40.502021, 34.040957, 16.767979],
[38.78828 , 36.947204, 24.048172],
[52.082462, 39.402308, 16.628231],
[57.427596, 33.121827, 12.412404],
[39.528547, 42.353077, 23.810769],
[39.36155 , 40.205116, 26.27124 ],
[66.665564, 26.855564, 15.602331],
[48.587099, 26.988702, 9.948168],
[52.675729, 35.32625 , 16.510208],
[45.813043, 53.54587 , 30.403261],
[44.765313, 43.954375, 24.824609],
[42.643386, 33.345984, 14.643386],
[44.512578, 37.723594, 15.144922],
[51.830571, 44.304667, 10.049524],
[42.202857, 38.628681, 21.68989 ],
[57.241308, 33.237462, 16.194154],
[36.353298, 39.223723, 26.603617],
[35.566589, 48.679535, 29.923023],
[33.422105, 56.539263, 32.230842],
[31.7503 , 44.3443 , 39.1499 ],
[33.332362, 46.603622, 37.348898],
[41.929385, 41.960077, 17.815385],
[57.145227, 31.194545, 16.385 ],
[46.137348, 43.874697, 15.843258],
[49.331231, 34.458231, 23.982462],
[44.171154, 43.299846, 27.451538],
[49.322373, 41.494915, 14.199153],
[46.158281, 47.806719, 23.341641],
[48.355859, 35.778281, 15.101563],
[47.143474, 40.162316, 20.52 ],
[48.403333, 36.152326, 12.157829],
[40.281616, 35.341515, 20.805657],
[49.049323, 32.918647, 22.447594],
[47.737462, 41.528077, 19.694385],
[48.743333, 42.93187 , 17.984797],
[38.766702, 42.88383 , 22.15266 ],
[38.471406, 41.289922, 39.664375],
[54.911368, 42.269895, 11.263263],
[37.240989, 46.254286, 31.804286],
[46.319462, 38.176692, 14.143846],
[53.331333, 33.349333, 18.497333],
[51.006406, 36.351563, 22.484609],
[47.646364, 39.943939, 23.249848],
[32.683125, 54.681667, 35.906667],
[65.067447, 25.46617 , 14.787447],
[54.431756, 37.019847, 19.690305],
[35.834375, 44.595625, 23.930625],
[39.546441, 45.188475, 25.213644],
[41.114 , 41.884769, 19.713231],
[50.898163, 38.136837, 19.937347],
[45.669015, 44.523106, 20.548864],
[37.411719, 43.379531, 33.332422],
[31.541828, 47.688172, 28.897527],
[41.483701, 50.352283, 30.561496],
[36.813721, 52.722403, 14.703256],
[43.81828 , 42.931613, 17.494624],
[39.31561 , 30.73935 , 13.23122 ],
[63.995606, 26.921818, 9.305985],
[44.541328, 45.529453, 33.89125 ],
[35.420439, 41.05807 , 24.249737],
[45.162043, 34.678602, 22.719355],
[38.499688, 46.513828, 34.344766],
[55.293566, 49.822326, 20.592791],
[46.21 , 35.002222, 19.006667],
[54.151721, 32.722131, 11.041475],
[43.443893, 23.982901, 17.032443],
[40.120985, 27.149545, 23.975758],
[53.95 , 42.411488, 16.108347],
[48.796045, 46.014478, 14.642985],
[43.805615, 36.315846, 21.608308],
[51.161 , 44.074 , 17.386154],
[58.380294, 45.653922, 12.822843],
[40.345769, 37.003923, 17.285538],
[40.808939, 43.961591, 18.982424],
[57.962308, 33.373538, 17.684 ],
[35.569389, 38.904885, 31.624351],
[31.960417, 48.533125, 40.096458],
[71.696129, 27.57121 , 19.093548],
[51.537405, 36.465344, 23.008168],
[36.258913, 45.225652, 39.427283]])
Information about y:
array([7, 7, 4, 2, 4, 7, 7, 5, 7, 7, 3, 1, 1, 2, 8, 3, 4, 6, 2, 4, 2, 3,
3, 7, 2, 4, 8, 1, 4, 3, 8, 1, 2, 7, 4, 5, 1, 2, 2, 1, 6, 2, 6, 1,
1, 2, 6, 3, 1, 7, 2, 8, 6, 2, 8, 2, 1, 3, 8, 2, 8, 4, 2, 1, 8, 9,
1, 1, 2, 4, 6, 8, 8, 4, 9, 2, 8, 4, 4, 9, 5, 2, 4, 1, 2, 7, 2, 3,
2, 1, 2, 7, 2, 2, 1, 7, 7, 2, 4, 6, 1, 1, 1, 4, 2, 4, 2, 8, 7, 5,
9, 9, 8, 9, 7, 1, 8, 2, 4, 8, 8, 2, 2, 1, 2, 1, 6, 2, 4, 2, 1, 1,
1, 7, 3, 7, 4, 2, 1, 1], dtype=int64)
In this piece of code I am trying to add different colours by every point in the plot:
fig = ipv.figure()
colores=['blue','red','green','cyan','yellow','orange','black','pink','brown','purple']
asignar=[]
for row in y:
asignar.append(colores[row])
scatter=ipv.scatter(X[:, 0], X[:, 1], X[:, 2],marker="sphere", color=asignar, size=2)
ipv.selector_default
ipv.show()
The result of the last piece of code is an infinite execution.
Changing the scatter's color the plot is created:
fig = ipv.figure()
colores=['blue','red','green','cyan','yellow','orange','black','pink','brown','purple']
asignar=[]
for row in y:
asignar.append(colores[row])
scatter=ipv.scatter(X[:, 0], X[:, 1], X[:, 2],marker="sphere", color="red", size=2)
ipv.selector_default
ipv.show()
Plot
Suggestion from https://github.com/maartenbreddels/ipyvolume/issues/12#issuecomment-284685146 might work, something like:
import ipyvolume as ipv
import matplotlib
c = matplotlib.cm.afmhot(np.linspace(0, 1, len(y)))
ipv.quickscatter(X[:, 0], X[:, 1], X[:, 2],marker="sphere",color=c,size=2)

How do I color background based on 1 or 0 in Python

I want the background of the graph of x to be grey when y=1 and white when y=0
#some random data
x = np.random.random(12)
#0's and 1's
y = [0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]
plt.plot(np.linspace(0, 12, 12), x);
So it looks something like this in stead of this
You can try manually drawing the rectangles using a loop:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
idx = np.linspace(0, 12, 12)
x = np.random.random(12)
y = [0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1]
fig, ax = plt.subplots(1)
ax.plot(idx, x)
rect_height = np.max(x)
rect_width = 1
for i, draw_rect in enumerate(y):
if draw_rect:
rect = patches.Rectangle(
(i, 0),
rect_width,
rect_height,
linewidth=1,
edgecolor='grey',
facecolor='grey',
fill=True
)
ax.add_patch(rect)
plt.show()

How to annotate a stacked bar plot and add legend labels

In short:
Height of bars does not match the numbers.
Labels seem to be placed on the wrong height. (should be right in the middle of each bar)
On the very bottom I also see the '0' labels which I really don't want to see in the graph.
Explained:
I'm trying to make a stacked bar chart and label each bar with it's appropriate value in it. But for some reason the height of the bars is completely wrong. Like for the first week the green bar should be 20 points long but it is only 10. And the red bar should be 10 points long but it is only 8 or so. And week 17 should have multiple bars in it but instead has only one (the white one)
I am guessing that because of the wrong bar heights the labels are misplaced too. I have no idea why the 0's on the very bottom are also showing but that's a problem too.
I don't know if these are all separate questions and should be asked in separate posts, but I feel like they are all connected and that there is an answer that solves them all.
import matplotlib.pyplot as plt
import numpy as np
newYearWeek =[201613, 201614, 201615, 201616, 201617, 201618, 201619, 201620, 201621, 201622]
uniqueNames = ['Word1', 'Word2', 'Word3', 'Word4', 'Word5', 'Word6',
'Word7', 'Word8', 'Word9', 'Word10', 'Word11']
#Each column in the multiarray from top to bottom represents 1 week
#Each row from left to right represents the values of that word.
#So that makes 11 rows and 10 columns.
#And yes the multidimensional array have to be like this with the 0's in it.
keywordsMuliarray = [
[20, 3, 1, 0, 0, 1, 6, 3, 1, 2],
[10, 1, 0, 0, 3, 1, 3, 1, 0, 2],
[2, 2, 5, 3, 5, 4, 5, 4, 3, 2],
[0, 4, 3, 3, 1, 0, 2, 7, 1, 2],
[0, 0, 2, 0, 1, 1, 1, 0, 1, 3],
[0, 0, 3, 2, 0, 0, 0, 1, 0, 0],
[1, 0, 1, 0, 1, 0, 0, 0, 1, 1],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 7, 6, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 0, 1]]
fig = plt.figure(figsize=(8.5, 5.5))
ax = fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
N = len(newYearWeek)
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequence
colors = ['seagreen', 'indianred', 'steelblue', 'darkmagenta', 'wheat',
'orange', 'mediumslateblue', 'silver',
'whitesmoke', 'black', 'darkkhaki', 'dodgerblue', 'crimson',
'sage', 'navy', 'plum', 'darkviolet', 'lightpink']
def autolabel(rects, values):
# Attach some text labels.
for (rect, value) in zip(rects, values):
ax.text(rect.get_x() + rect.get_width() / 2.,
rect.get_y() + rect.get_height() / 2.,
'%d'%value,
ha = 'center',
va = 'center')
left = np.zeros(len(uniqueNames)) # left alignment of data starts at zero
helpingNumber = 0
for i in range(0, len(newYearWeek)):
rects1 = plt.bar(ind, keywordsMuliarray[helpingNumber][:],width, color=colors[helpingNumber], label=uniqueNames[helpingNumber])
autolabel(rects1, keywordsMuliarray[helpingNumber][:])
helpingNumber = helpingNumber+1
# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 1, box.height])
# Put a legend to the right of the current axis
ax.legend(loc='center left', fontsize=9, bbox_to_anchor=(1, 0.5))
#plt.ylabel('Scores')
plt.xticks(ind + width/2., newYearWeek, fontsize=8)
#plt.yticks(np.arange(0, 81, 10))
plt.margins(x=0.02)
plt.tight_layout(rect=[0,0,0.8,1])
plt.show()
This is how the graph looks now:
To make what you want you have to sum heights of all previous bars in current column (list bot_heights), like here:
import matplotlib.pyplot as plt
import numpy as np
newYearWeek =[201613, 201614, 201615, 201616, 201617, 201618, 201619, 201620, 201621, 201622]
uniqueNames = ['Word1', 'Word2', 'Word3', 'Word4', 'Word5', 'Word6',
'Word7', 'Word8', 'Word9', 'Word10', 'Word11']
#Each column in the multiarray from top to bottom represents 1 week
#Each row from left to right represents the values of that word.
#So that makes 11 rows and 10 columns.
#And yes the multidimensional array have to be like this with the 0's in it.
keywordsMuliarray = [
[20, 3, 1, 0, 0, 1, 6, 3, 1, 2],
[10, 1, 0, 0, 3, 1, 3, 1, 0, 2],
[2, 2, 5, 3, 5, 4, 5, 4, 3, 2],
[0, 4, 3, 3, 1, 0, 2, 7, 1, 2],
[0, 0, 2, 0, 1, 1, 1, 0, 1, 3],
[0, 0, 3, 2, 0, 0, 0, 1, 0, 0],
[1, 0, 1, 0, 1, 0, 0, 0, 1, 1],
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 7, 6, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 0, 1]]
fig = plt.figure(figsize=(8.5, 5.5))
ax = fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
N = len(newYearWeek)
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequence
colors = ['seagreen', 'indianred', 'steelblue', 'darkmagenta', 'wheat',
'orange', 'mediumslateblue', 'silver',
'whitesmoke', 'black', 'darkkhaki', 'dodgerblue', 'crimson',
'sage', 'navy', 'plum', 'darkviolet', 'lightpink']
def autolabel(rects, values):
# Attach some text labels
for (rect, value) in zip(rects, values):
if value > 0:
ax.text(rect.get_x() + rect.get_width() / 2.,
rect.get_y() + rect.get_height() / 2.,
'%d'%value, ha = 'center', va = 'center', size = 9)
left = np.zeros(len(uniqueNames)) # left alignment of data starts at zero
# plot the first bars
rects1 = plt.bar(ind, keywordsMuliarray[0][:],width,
color=colors[0], label=uniqueNames[0])
autolabel(rects1, keywordsMuliarray[0][:])
# put other bars on previuos
bot_heights = [0.] * len(keywordsMuliarray[0][:])
for i in xrange(1,N):
bot_heights = [bot_heights[j] + keywordsMuliarray[i-1][j] for j in xrange(len(bot_heights))]
rects1 = plt.bar(ind, keywordsMuliarray[i][:],width,
color=colors[i], label=uniqueNames[i],
bottom=bot_heights)
autolabel(rects1, keywordsMuliarray[i][:])
# Shrink current axis by 20%
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 1, box.height])
# Put a legend to the right of the current axis
ax.legend(loc='center left', fontsize=9, bbox_to_anchor=(1, 0.5))
#plt.ylabel('Scores')
plt.xticks(ind + width/2., newYearWeek, fontsize=8)
plt.yticks(np.arange(0, 41, 5))
plt.margins(x=0.02)
plt.tight_layout(rect=[0,0,0.8,1])
plt.show()
To prevent overlapping of bar labels I recommend you do not add a label if a value is zero (look to modified autolabel function). As a result I get:
The other answer doesn't plot data for 'Word11'
Lists and arrays of data can most easily be plotted by loading them into pandas
Plot the dataframe with pandas.DataFrame.plot and kind='bar'
When plotting data from pandas, the index values become the axis tick labels and the column names are the segment labels
matplotlib.pyplot.bar_label can be used to add annotations
See Adding value labels on a matplotlib bar chart for more options using .bar_label.
Tested in pandas 1.3.1, python 3.81., and matplotlib 3.4.21.
Minimum version required
labels = [f'{v.get_height():0.0f}' if v.get_height() > 0 else '' for v in c ] without the assignment expression (:=).
import pandas as pd
import matplotlib.pyplot as plt
# create a dataframe from the data in the OP and transpose it with .T
df = pd.DataFrame(data=keywordsMuliarray, index=uniqueNames, columns=newYearWeek).T
# display(df.head())
Word1 Word2 Word3 Word4 Word5 Word6 Word7 Word8 Word9 Word10 Word11
201613 20 10 2 0 0 0 1 0 0 0 0
201614 3 1 2 4 0 0 0 0 1 0 0
201615 1 0 5 3 2 3 1 0 0 0 0
201616 0 0 3 3 0 2 0 1 0 0 0
201617 0 3 5 1 1 0 1 0 7 0 0
colors = ['seagreen', 'indianred', 'steelblue', 'darkmagenta', 'wheat', 'orange', 'mediumslateblue', 'silver', 'whitesmoke', 'black', 'darkkhaki']
# plot the dataframe
ax = df.plot(kind='bar', stacked=True, figsize=(9, 6), color=colors, rot=0, ec='k')
# Put a legend to the right of the current axis
ax.legend(loc='center left', fontsize=9, bbox_to_anchor=(1, 0.5))
# add annotations
for c in ax.containers:
# customize the label to account for cases when there might not be a bar section
labels = [f'{h:0.0f}' if (h := v.get_height()) > 0 else '' for v in c ]
# set the bar label
ax.bar_label(c, labels=labels, label_type='center', fontsize=8)
plt.show()

Categories

Resources