[PYTHON] Implement "Data Visualization Design # 2" with matplotlib

What is a data visualization design?

This is a summary of data visualization points published in note by Go Ando of THE GUILD, who is famous for services that focus on UX and UI.

https://note.mu/goando/n/n4a2735c3d69d

# 1?

https://qiita.com/skotaro/items/cdb0732ad1ad2a4b6236

Notes

plt.rcParams['font.family'] = 'Hiragino Sans'  

It is the part of.

8. Do not use the 2nd axis

picture_pc_35cbe51d3cf1f3331ad189ac806eae85.png

#Library import
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.ticker import MultipleLocator


#data
mau = [450,480,500,470,520,550,530,580,620,700,690,720]
g_rate = [0,8,0,-4,10,9,-6,12,4,12,-1,8]
g_rate = [one/100 for one in g_rate]
timeindex = pd.date_range('2019/1', periods=12, freq='MS')
mau = pd.Series(mau, index=timeindex, name='MAU(M)')
g_rate = pd.Series(g_rate,index=timeindex,name='Last month growth rate')

#For error avoidance in pandas
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

#Font settings
plt.rcParams['font.family'] = 'Hiragino Sans'  
plt.rcParams['font.weight'] = 'heavy'

#Split up and down
fig = plt.figure(figsize=(8,5))
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)

# 1.Change bar color and width
ax1.plot(g_rate.index, g_rate,linewidth=5.,color="saddlebrown")
ax2.bar(mau.index, mau, width=20., color='darkorange', zorder=2, align='center')

# 2.Display y-axis label, specify color and font size
ax1.set_ylabel(g_rate.name,color="saddlebrown",fontsize=14,fontweight='bold')
ax2.set_ylabel(mau.name, color='gray',fontsize=14,fontweight='bold')

# 3.Change y-axis tick position
ax1.yaxis.set_major_locator(MultipleLocator(500))
ax2.yaxis.set_major_locator(MultipleLocator(500))

# 4.Erase x-axis y-axis tick,For the graph above, erase all x-axis
ax1.tick_params(labelbottom="off",bottom=False, left=False) 
ax1.set_xticklabels([]) 
ax2.tick_params(bottom=False, left=False)

# 5.Change the color of the x-axis and y-axis tick labels
ax1.tick_params(axis='y', colors='dimgray')
ax2.tick_params(axis='x', colors='dimgray')
ax2.tick_params(axis='y', colors='dimgray')

# 6.Show y-axis grid, color black for graph above
ax1.grid(axis='y',color="black")
ax2.grid(axis='y')

# 7.Erase the right frame
ax1.spines['right'].set_visible(False)
ax2.spines['right'].set_visible(False)

# 8.Change the color of the frame
ax1.spines['bottom'].set_color('dimgray')
ax1.spines['top'].set_color('dimgray')
ax1.spines['left'].set_color('dimgray')
ax2.spines['bottom'].set_color('dimgray')
ax2.spines['top'].set_color('dimgray')
ax2.spines['left'].set_color('dimgray')

# 9.Set x-axis tick label to month only
# '%-m'Is strftime leading zero no month notation
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%-m')) 

# 10.Set the x-axis tick position every month
ax2.xaxis.set_major_locator(mdates.MonthLocator())
ax2.xaxis.set_tick_params(labelsize=12)

#The major tick position is not updated unless the fig is drawn once
fig.canvas.draw()

# 11.Specifying the range of the vertical axis
ax1.set_ylim(-0.20,0.20)
ax2.set_ylim(0,800)
    
# 12.Change of vertical axis tick
vals_1 = [-0.2,0,0.2]
ax1.set_yticks(vals_1)
ax1.set_yticklabels(['{:,.0%}'.format(x) for x in vals_1],color="saddlebrown",fontsize=12,fontweight='bold')
vals_2 = [0,400,800]
ax2.set_yticks(vals_2)
ax2.set_yticklabels(['{}'.format(x) for x in vals_2] ,fontsize=12,fontweight='bold')

# 13.Align ylabel
axs = [ax1,ax2]
fig.align_ylabels(axs)

temp_5.png

For how to set the vertical axis to% in # 12., I referred to the answer from stackoverflow [^ 1].

13. is based on the official doc of matplotlib [^ 2].

You can also write the y label vertically by starting a new line character by character, but I didn't because the code was ugly. (Please tell me if there is a smart way)

9. Reduce elements to a minimum

picture_pc_a37bd978a068d0840f04250ca5b05a3a.png

#data
shipment_n = pd.DataFrame([52217, 9113, 4078],
                           index=['iPhone', 'iPad', 'Mac'],
                           columns=['amount'])

fig, ax = plt.subplots(figsize=(6, 3))
ax.bar(shipment_n.index,shipment_n["amount"])

# 1.Erase the frame other than bottom
sides = ['left','right', 'top']
[ax.spines[side].set_visible(False) for side in sides] 

# 2.Change the color of the bottom frame to gray
ax.spines['bottom'].set_color("dimgray")

# 3.Erase the y-axis tick
ax.tick_params(left=False, labelleft=False)

# 4.Larger x-axis label size, gray color
ax.tick_params(axis='x', labelsize='xx-large',color="dimgray",labelcolor="dimgray")

# 5.Show actual value above the bar
vmax = shipment_n['amount'].max()
for i, value in enumerate(shipment_n['amount']):
    ax.text(i, value+vmax*0.06, f'{value:,}', fontsize='xx-large', va='center', ha='center', color='C0')

tmp6.png

4 is achieved by offsetting using vmax.

10. Write the largest key message

picture_pc_c0ccda82a2e6153a56d22b40e1f7d12b.png

#color
ori_blue = "#3674b3"
ori_lightblue = "#b3daff"


# 1.Paint the whole
plt.rcParams["axes.facecolor"] = (1,1,1,0)

# 2.Blue background
fig, ax = plt.subplots(figsize=(6, 4),facecolor=ori_blue)

# 3.title
fig.suptitle("iPhone accounts for 80% of shipments",color="white",size=24,fontweight='bold',ha='center')

# 4.Plot in light blue
ax.bar(shipment_n.index,shipment_n["amount"],color=ori_lightblue)

# 5.Add a description
ax.text(-0.4,shipment_n["amount"].max()*1.2,"Chart: 2017 Apple Shipment Devices",color=ori_lightblue,fontsize=12)

#6.Delete frames other than bottom
sides = ['left','right', 'top']
[ax.spines[side].set_visible(False) for side in sides] 

# 7.bottom frame color setting
ax.spines['bottom'].set_color(ori_lightblue)

# 8.y-axis range setting
ax.set_ylim(0,80000)

# 9.Erase the y-axis tick label
ax.tick_params(left=False, labelleft=False)
    
# 10.x-axis label setting
ax.tick_params(axis='x', labelsize='xx-large',color=ori_lightblue,labelcolor=ori_lightblue)

# 11.Show actual value above the bar
vmax = shipment_n['amount'].max()
for i, value in enumerate(shipment_n['amount']):
    ax.text( i,value+vmax*0.06, f'{value:,}', fontsize='xx-large', va='center', ha='center', color=ori_lightblue)

#When saving
plt.savefig("savefig_with_facecolor.png ",facecolor=fig.get_facecolor())

tmp8.png

About the color, I set it somehow. In the head family, the corners of the background were rounded, but this could not be reproduced. (I did not come out even after checking it quite a bit ...) Also, when saving with plt.savefig (), it is necessary to specify the background color with facecolor = [^ 3].

Recommended Posts

Implement "Data Visualization Design # 2" with matplotlib
Implement "Data Visualization Design # 3" with pandas and matplotlib
Data visualization with pandas
Graph Excel data with matplotlib (1)
Graph Excel data with matplotlib (2)
Data visualization method using matplotlib (1)
Data visualization method using matplotlib (2)
Data visualization method using matplotlib (+ pandas) (5)
Versatile data plotting with pandas + matplotlib
Data visualization method using matplotlib (+ pandas) (3)
Easy data visualization with Python seaborn.
Data visualization method using matplotlib (+ pandas) (4)
Data analysis starting with python (data visualization 2)
Separation of design and data in matplotlib
Recommendation of Altair! Data visualization with Python
Animation with matplotlib
Japanese with matplotlib
Animation with matplotlib
Histogram with matplotlib
Animate with matplotlib
Visualize corona infection data in Tokyo with matplotlib
Read Python csv data with Pandas ⇒ Graph with Matplotlib
Data analysis with python 2
2-axis plot with Matplotlib
Implement FReLU with tf.keras
Visualize data with Streamlit
Reading data with TensorFlow
Overview and tips of seaborn with statistical data visualization
Heatmap with Python + matplotlib
Learn with Cheminformatics Matplotlib
Data manipulation with Pandas!
Shuffle data with pandas
Various colorbars with Matplotlib
Normarize data with Scipy
Data analysis with Python
Logistics visualization with Python
LOAD DATA with PyMysql
Adjust axes with matplotlib
Getting Started with Drawing with matplotlib: Creating Diagrams from Data Files
Implement normalization of Python training data preprocessing with scikit-learn [fit_transform]
[Causal search / causal inference] Implement a Bayesian network with Titanic data
Sample data created with python
Implement login function with django-allauth
Embed audio data with Jupyter
Artificial data generation with numpy
Implement subcommands with Python's argparse
Extract Twitter data with CSV
Try using matplotlib with PyCharm
Get Youtube data with python
Graph drawing method with matplotlib
Clustering ID-POS data with LDA
Learn new data with PaintsChainer
Visualization of data by prefecture
Binarize photo data with OpenCV
Implement PyTorch + GPU with Docker
Save tweet data with Django
Stackable bar plot with matplotlib
[QtDesigner] Implement WebView with PyQt5
Gradient color selection with matplotlib
Animate multiple graphs with matplotlib
Data processing tips with Pandas