Skip to content

Instantly share code, notes, and snippets.

@TheOldMyronSiren
Created October 13, 2021 15:09
Show Gist options
  • Save TheOldMyronSiren/b33967755ff2a0b66714b807d7bb7195 to your computer and use it in GitHub Desktop.
Save TheOldMyronSiren/b33967755ff2a0b66714b807d7bb7195 to your computer and use it in GitHub Desktop.
Wrapper for creating a donut graph to be used with DearPyGUI
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
import dearpygui.dearpygui as dpg
import numpy as np
class donutGraph():
def __init__(self,width:int=500,height:int=500,dpi:int=100,tightLayout:bool=True,pad:int=0,colors:list=None,labels:list=[],values:list=None,background:str=None,labelSize:int=14,labelColor:str="white"):
"""Creates a donut graph with matplotlib and returns it has an image for use as a texture in DearPyGUI.
Attributes:
width -- Integer represting the width of the resulting image
height -- Integer represting the height of the resulting image
dpi -- Integer represting the DPI of the plot
tightLayout -- Boolean for enabling a tight layout for the plot
pad -- Padding for the tight layout
colors -- List of colors to be used in sequence for the pie wedges
labels -- List of strings providing the labels for each pie wedge
values -- List of floats providing the sized for each pie wedge
background -- HTML formatted color for the plot background and donut center
labelSize -- Font size for the labels for each pie wedge
labelColor -- Font color for the labels of each pie wedge"""
# Check arguments
if type(width) != int:
raise self.errors.invalidArgument("width",int,type(width))
elif type(height) != int:
raise self.errors.invalidArgument("height",int,type(height))
elif type(dpi) != int:
raise self.errors.invalidArgument("dpi",int,type(dpi))
elif type(colors) != list and type(colors) != None:
raise self.errors.invalidArgument("colors",list,type(colors))
elif type(values) != list:
raise self.errors.invalidArgument("values",list,type(values))
elif type(labels) != list:
raise self.errors.invalidArgument("values",list,type(labels))
elif type(labelSize) != int:
raise self.errors.invalidArgument("labelSize",int,type(labelSize))
elif type(tightLayout) != bool:
raise self.errors.invalidArgument("tightLayout",bool,type(tightLayout))
elif type(pad) != int:
raise self.errors.invalidArgument("pad",int,type(pad))
elif type(background) != str:
raise self.errors.invalidArgument("background",str,type(background))
elif len(labels) != len(values) and len(labels) > 0:
raise self.errors.mismatchedLengths(len(values),len(labels))
# Assign attributes
self.width = width
self.height = height
self.dpi = dpi
self.labels = labels
self.colors = colors
self.values = values
self.background = background
self.labelSize = labelSize
self.labelColor = labelColor
# Create plot
fig = plt.figure(figsize=(width/dpi,height/dpi),dpi=dpi)
canvas = FigureCanvasAgg(fig)
ax = fig.gca()
fig.patch.set_facecolor(self.background)
if len(labels) > 0:
ax.pie(self.values,colors=self.colors,labels=labels,textprops={"fontsize":self.labelSize,"color":self.labelColor},startangle=113)
else:
ax.pie(self.values,colors=self.colors,startangle=113)
if tightLayout == True:
plt.tight_layout(pad=pad)
circle = plt.Circle((0,0),0.7,color=self.background)
ax.add_artist(circle)
canvas.draw()
buffer = canvas.buffer_rgba()
image = np.asarray(buffer)
self.image = image.astype(np.float32)/255
class errors:
class invalidArgument(Exception):
def __init__(self,argument:str,expectedType:str,suppliedType:str):
"""Raised when an argument is of an invalid type.
Attributes:
argument -- The argument that was invalid.
expectedType -- The type of the argument provided
message -- Explanation of the error
suppliedType -- The type of the invalid argument"""
self.argument = argument
self.expectedType = expectedType
self.suppliedType = suppliedType
self.message = f"Invalid argument supploed for [{argument}]. Type must be {expectedType}, not {suppliedType}."
super().__init__(self.message)
class mismatchedLengths(Exception):
def __init__(self,valuesLength,labelsLength):
"""Raised when the length of values does not match the length of labels.
Attributes:
message -- Explanation of the error"""
self.message = f"Lengths of values and labels are mismatches. Values: ({valuesLength}) Labels ({labelsLength})"
def getDonut(self):
return self.image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment