Matplotlib change the bar color if a condition is met

匿名 (未验证) 提交于 2019-12-03 01:45:01

问题:

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) 

回答1:

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() 



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!