Reputation: 121
I am trying to build a Figure with 2 subplots.
If the Item is in ax
and ax1
the color of the bar is blue.
If the item is in ax
and not in ax1
the bar color should be green.
If the item is not in ax
and it is in ax1
the bar color should be red.
so in my example:
The bar Exploit
should be green and XSS
should be red.
Is there a way to do this with Matplotlib?
Here is the code:
import matplotlib.pyplot as plt
from collections import OrderedDict
from matplotlib.backends.backend_pdf import PdfPages
from Processesing import dataProcess
from Sizeconvertor import Szconv
def chartmak (curvdic,prevdic,imgname,unit) :
Colors =[]
ImgName=imgname
D={}
D1={}
D=curvdic
D1=prevdic
if len(D):
listo=list(D.items())
listo1=list(D1.items())
if len(listo) < 10:
listo.extend([('', 0)] * (10 - len(listo)))
if len(listo1) < 10:
listo1.extend([('', 0)] * (10 - len(listo1)))
values1 = [v for l, v in listo1]
values = [v for l, v in listo]
Dict=listo
Dict1=listo1
fig, (ax,ax1) = plt.subplots(ncols=2,figsize=(12, 5))
n = len(Dict)
n1 = len(Dict1)
#--------------add the 1 barchart
ax.barh(range(n), values, align='center', fc='#80d0f1', ec='w')
ax.set_yticks(range(n))
ax.set_yticklabels(['' if e == 0 else Szconv(e,unit) for e in values], color='gray')# add the unit
ax.tick_params(pad=10)
for i, (label, val) in enumerate(Dict):
ax.annotate(label.title(), xy=(10, i), fontsize=10, va='center')
for spine in ('top', 'right', 'bottom', 'left'):
ax.spines[spine].set_visible(False)
ax.xaxis.set_ticks([])
ax.yaxis.set_tick_params(length=0)
ax.invert_yaxis()
ax.set_title('curmonth')
#----------add the secound plot
ax1.barh(range(n1), values1, align='center', fc='#80d0f1', ec='w')
ax1.set_yticks(range(n1))
ax1.set_yticklabels(['' if e == 0 else Szconv(e,unit) for e in values1], color='gray')#this need more work to put the GB or the TB
ax1.tick_params(pad=10)
for i, (label, val) in enumerate(Dict1):
ax1.annotate(label.title(), xy=(10, i), fontsize=10, va='center')
for spine in ('top', 'right', 'bottom', 'left'):
ax1.spines[spine].set_visible(False)
ax1.xaxis.set_ticks([])
ax1.yaxis.set_tick_params(length=0)
ax1.invert_yaxis()
ax1.set_title('PrevMonth')
#---------------------------------------------------------------------
#fig.set_size_inches(4, 3.5)
plt.savefig("BarChart/"+ImgName,bbox_inches='tight')
plt.show()
Testdic =OrderedDict([('Exploit', 14664), ('Botnet', 123), ('Virus', 52)])
Testdic2 =OrderedDict([('Botnet', 1252), ('Virus', 600), ('XSS', 452)])
imgname="TestImageformt.png"
unit = "transaction"
chartmak(Testdic,Testdic2,imgname,unit)
Upvotes: 0
Views: 1518
Reputation: 69076
You can change the color of the Rectangle
patches that barh
creates after its been plotted based on your conditions.
I modified your code a little to remove some of the unnecessary parts and make it run. I hope its clear below what its doing. You can use ax.patch[i].set_color('r')
to change the color of patch i
to red, for example.
import matplotlib.pyplot as plt
from collections import OrderedDict
fig,(ax1,ax2) = plt.subplots(1,2)
Testdic1 =OrderedDict([('Exploit', 14664), ('Botnet', 123), ('Virus', 52)])
Testdic2 =OrderedDict([('Botnet', 1252), ('Virus', 600), ('XSS', 452)])
list1 = list(Testdic1.items())
list2 = list(Testdic2.items())
n1 = len(list1)
n2 = len(list2)
values1 = [v for l,v in list1]
values2 = [v for l,v in list2]
ax1.barh(range(n1),values1,align='center', fc='#80d0f1', ec='w')
ax2.barh(range(n2),values2,align='center', fc='#80d0f1', ec='w')
# ====================================
# Here's where we change colors
# ====================================
for i,(label,val) in enumerate(list1):
if label.title() in Testdic2:
pass # leave it blue
else:
ax1.patches[i].set_color('g')
for i,(label,val) in enumerate(list2):
if label.title() in Testdic1:
pass # leave it blue
else:
ax2.patches[i].set_color('r')
# ====================================
ax1.set_yticks(range(n1))
ax2.set_yticks(range(n2))
for i, (label, val) in enumerate(list1):
ax1.annotate(label.title(), xy=(10, i), fontsize=10, va='center')
for i, (label, val) in enumerate(list2):
ax2.annotate(label.title(), xy=(10, i), fontsize=10, va='center')
ax1.invert_yaxis()
ax2.invert_yaxis()
plt.show()
Upvotes: 1