Page contents: Matplotlib - Cat Stats Spider PlotPlotly - Cat Origins MapPrevious

Graphing Examples

The data table was used to generate graphs on the Cat Data pages, the Data Exploration pages, and the Cat Map. Two examples, using each of the two graphing packages are shown below. See the project's GitHub page for other graphs' codes. Graph Index



Matplotlib - Radar / Spider Plot of Cat Stats code

The following example generates a figure, as seen on the cat data pages. A random cat is generated as shown on the previous page, and its stats as well as the average stats were selected and used for graphing.


	from pathlib import Path
	import pandas as pd
	import numpy as np
	import matplotlib.pyplot as plt
	
	data = pd.read_csv(Path(Path.cwd(),'subfolder', 'catdata.csv'), index_col = 'name', na_filter = False) # Path is simply an example, persisted from the previous page
	statsCol = pd.Series(pd.read_csv(Path(Path.cwd(),'subfolder','stats.csv'), index_col = 0)['0'], name = 'Cols') # see previous page for generation of "data" and "statsCol"
	
	n_cats = data.shape[0]-1
	random_cat = pd.Series(data.index[:-1]).sample().values[0]
	cat_stats = data.loc[random_cat,statsCol]
	avg_stats = data.loc[data.index[-1],statsCol] # last row is average

	catTheta = np.append(cat_stats,(cat_stats[0])) # repeat first value to close circle 
	avgTheta = np.append(avg_stats,(avg_stats[0]))
	angles = [x / avg_stats.shape[0] * 2 * np.pi for x in range(avg_stats.shape[0])] # radian values for data points, evenly spaced around circle
	angles2 = np.append(angles, angles[0]) # repeat first value to close circle 
	
	labeler = [val.replace('_',' ').capitalize() for val in cat_stats.index.values] # more readable labels 
	avg_text = f'{avg_stats.name} (n={n_cats})' # include number of cats considered in average 
		
	plt.figure(figsize = (8,7), dpi = 150, tight_layout=True) # Text specs need to vary with figure size to keep things pretty
	ax = plt.subplot(111, polar = "True")
	ax.spines['polar'].set_visible(False)
	plt.ylim(0,6) # extend axis lines past 5

	# plot sample data over mean as background
	plt.fill(angles2,catTheta,alpha = 0.25, color = 'cyan', ec ='darkcyan', linewidth = 2, linestyle ='-')
	plt.fill(angles2,avgTheta,alpha = 0.20, color = 'coral', ec='orangered')

	# ticks, axes labels
	plt.xticks(angles,labeler, fontweight = 'bold' )
	plt.yticks([1,2,3,4,5], fontsize=0)
	for num in [1,3,5]:
		plt.text(np.pi*5/12, num, num, fontsize = 12, fontweight='bold')
		
	# sample value labels
	bbox_props = dict(boxstyle="circle, pad = 0.22", fc="cyan", ec="darkcyan", lw=2)
	for i,val in enumerate(cat_stats):
		ax.text(angles[i], int(val), str(int(val)), color = 'black', fontweight = 'bold', bbox=bbox_props)

	# title / legend
	plt.title(cat_stats.name, loc='left', fontsize=18, fontweight='bold', color = 'darkcyan')
	plt.text(3*np.pi/4,8.8, avg_text, fontsize = 12, fontweight = 'bold', color = 'orangered')

	# Show / Save
	plt.plot()
	plt.savefig(Path(Path.cwd(),'subfolder', 'mpl-graphs',f'{cat_stats.name}_radar.png'))
    


Plotly - Map of Cat Origins code

Plotly can generate interactive plots in HTML. The cats' origins were used to populate a world map that shows how many cats, and which ones, originate from a country. See Choropleth Maps and Scatter Plots on Maps for more information. I haven't figured out how to best integrate these plots into the website. I may try to improve the Plotly pages in future updates to the site.


	from pathlib import Path
	import pandas as pd
	import plotly.express as px
	import plotly.utils as pu # JSON Encoder used to integrate into webpages, HTML file also used in "raw-map"

	data = pd.read_csv(Path(Path.cwd(),'subfolder', 'catdata.csv'), index_col = 'name', na_filter = False) # Path is simply an example, persisted from the previous page
	cat_locs = data.loc[:,['origin','country_code']] # Extract location information into data table
	cat_locs = cat_locs.iloc[:-1,:] # Remove CatAPI Average
	
	# Prepare new data table
	locs = pd.DataFrame(cat_locs.value_counts()).reset_index() # organize by number of cats from country (origin)
	locs.columns = (['origin','code','# cats']) # rename columns
	locs['cats'] = [', '.join(cat_locs[cat_locs.origin == val].index) for val in locs['origin']] # Get cats belonging to country
	locs['origin'] = [f'{locs.loc[val,"origin"]} ({locs.loc[val,"# cats"]})' for val in locs.index] # Add cat number to entries for hover label

	# Generate plot
	fig = px.choropleth(locs, locations="code", color="# cats", hover_name="origin",
                            hover_data = {'code': False, '# cats': False, 'cats': True,},
                            color_continuous_scale=px.colors.sequential.Emrld)

	fig.update_geos(showcountries = True, coastlinewidth = 1.5, landcolor = '#dedede', lakecolor = '#b0ceff', 
		        showocean = True, oceancolor = '#b0ceff', showrivers = True, rivercolor = '#b0ceff',
		        projection_type = 'natural earth', fitbounds = "locations")

	# Show / Save
	fig.show() # output can vary depending on IDE used
	fig.write_html(Path(Path.cwd(),'subfolder', 'plotly-graphs','catmap.html')) # html to file, can be opened in web-browser
	graphJSON = json.dumps(fig, cls=pu.PlotlyJSONEncoder) # graphJSON could be passed directly to page or saved to file
	

< Data Table previous

<< Processing further

<<< Background data story start