Page contents: Matplotlib - Cat Stats Spider Plot • Plotly - Cat Origins Map • Previous
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
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 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