As mentioned in the instructions, all materials can be open in Colab as Jupyter notebooks. In this way users can run the code in the cloud. It is highly recommanded to follow the tutorials in the right order.

In the last blog, we have created a bubble chart / scatter plot using Plotly. This time we are trying to make other types of plot: a simple bar chart and a lollipop chart using plotly.express and plotly.graph_objects. The creation of both charts begin with a Pandas data frame. Then we pass the data frame into Plotly for a basic plot, and update the layouts afterwards. The bar chart requires only one plotting action .bar(), whereas the lollipop chart requires two plotting actions: first creating the scatter plot, then with add the "stick" using add_shape().

Set Up Environment

import pandas as pd
import numpy as np
import plotly.express as px

# library for creating random lengths of "stick" in the chart
from random import seed
from random import random

Bar Chart

Creating Data Frame

In this example, we create a bar chart based on the records for the type of natural disaster recorded in 《臺灣文獻叢刊》臺灣方志. The data frame is created using a dictionary, created by passing column names and values.

data = {
    "Type of Natural Disaster": ["Fire","Locust","Drought","Earthquake","Flood","Typhoon","Storm"],
    "Number of Record": [63,81,86,13,138,158,8]
}

df = pd.DataFrame(data=data)

Plotting

Then we can do the plotting by calling px.bar(). We can pass x, y, title and the figure size into the function. This will allow the creation of a simple bar chart in Plotly using default layout options. If we wish to change any parameters, we can update it using update_layout().

Here, we will update the hover labels by changing the font size and the background color. We will also adjust the width of the bars. Finally, we pass fig.show() for the display of our plot.

First, we define a set of color for the bars by passing them into a list.

color_discrete_sequence = ['#1f77b4',  # muted blue
    '#ff7f0e',  # safety orange
    '#2ca02c',  # cooked asparagus green
    '#d62728',  # brick red
    '#9467bd',  # muted purple
    '#bcbd22',  # curry yellow-green
    '#e377c2']  # raspberry yogurt pink

Then, we plot the chart. With the title, we can pass the html tag <b> </b> to style the words (bold), and for the color argument, we use 'Type of Natural Disaster', which mean every single column, we use a different colors. By doing so, a legend will be automatically created to explain the implication of colors. We can disable them later using fig.update_layout(showlegend=False).

fig = px.bar(df, y='Number of Record', x='Type of Natural Disaster', 
             title="<b>Disaster Records in 臺灣方志</b>", width=1000, height=500,
             color="Type of Natural Disaster",color_discrete_sequence=color_discrete_sequence)

Let's us disable out legend and adjust the width of the bars.

fig.update_layout(showlegend=False)
fig.update_traces(width=0.5)

Then, we will adjust the hover labels before displaying out plot using fig.show().

fig.update_layout(
    hoverlabel=dict(
        bgcolor="white",
        font_size=14,
        font_family="Courier New"
    )
)

fig.show()

Lollipop Chart

This time, let's us work with some qualitative data. We will try to plot a simple time line of the articles 胡適 had published in his life time. We want to label the data with the shorten titles while putting the full titles in our hover labels.

Creating Data Frame

Let's first create our data frame. In order to have a lollipop chart we need to define the y values. We would like the y values to be different for every titles so we can avoid text overlapping. It can be done using random library and random().

We will also convert the date column to datetime using pd.to_datetime().

data = {
    "date": ["1919-01-01","1917-05-01","1918-01-01","1919-07-20","1924-01-01","1929-01-01","1929-02-01","1929-03-01","1929-04-01","1930-04-10","1959-11-20"],
    "title": ["文學改良芻議","歷史的文學觀念論","建設的文學革命論","多研究些問題,少談些主義","差不多先生傳","人權與約法","我們什麼時候才可有憲法—對於建國大綱的疑問","知難,行亦不易—孫文先生的「行易知難」說述評","新文化運動與國民黨","我們走那條路","容忍與自由"],
    "sub": ["文學改良芻議","歷史的文學觀念論","建設的文學革命論","多研究些問題,少談些主義","差不多先生傳","人權與約法","我們什麼時候才可有憲法","知難,行亦不易","新文化運動與國民黨","我們走那條路","容忍與自由"],
}

df = pd.DataFrame(data=data)
df['date'] =  pd.to_datetime(df['date'], format='%Y-%m-%d')
df['y'] = [random() for i in range(len(df.title))]
df
date title sub y
0 1919-01-01 文學改良芻議 文學改良芻議 0.043649
1 1917-05-01 歷史的文學觀念論 歷史的文學觀念論 0.729784
2 1918-01-01 建設的文學革命論 建設的文學革命論 0.281129
3 1919-07-20 多研究些問題,少談些主義 多研究些問題,少談些主義 0.544732
4 1924-01-01 差不多先生傳 差不多先生傳 0.704270
5 1929-01-01 人權與約法 人權與約法 0.699685
6 1929-02-01 我們什麼時候才可有憲法—對於建國大綱的疑問 我們什麼時候才可有憲法 0.651569
7 1929-03-01 知難,行亦不易—孫文先生的「行易知難」說述評 知難,行亦不易 0.262863
8 1929-04-01 新文化運動與國民黨 新文化運動與國民黨 0.116383
9 1930-04-10 我們走那條路 我們走那條路 0.443837
10 1959-11-20 容忍與自由 容忍與自由 0.266778

Plotting

This time, we create the figure using plotly.graph_objects. We can draw the sticks using fig.add_shape(type='line'). It will be put in a loop so we can draw mulitple sticks for every row instead. x0, x1, y0, y1 mean the coordinates of the shape. As it is a line, x0 equals x1, and y0 and y1 refers to the beginning (always 0) and ending point (depends on y column) of the stick. Other options include the color of the sticks.

import plotly.graph_objects as go

fig = go.Figure()

# Draw lines
for i in range(0, len(df)):
               fig.add_shape(type='line', # draw line
                              x0 = df["date"][i], y0 = 0, # our line
                              x1 = df["date"][i],
                              y1 = df["y"][i],
                              opacity=0.65, # transparency
                              line=dict(color='darkblue', width = 5)) # line color and width

Then we will plot the dots using fig.add_trace(go.Scatter()). We will use the text to indicate the static labels and customdata indicate the full titles. mode="markers+text" means both markers and static labels will be shown. We will also use other customization options and html tags for our hovertemplate.

fig.add_trace(go.Scatter(x = df["date"], 
                         y = df["y"],
                         text=df["sub"], # static labels
                         customdata=df["title"], # hover labels
                         mode="markers+text", # display static labels
                         hovertemplate = # what to shown in hover labels
                          '<extra><br><b>Date</b>: %{x}<br></extra>'+
                          '<extra><b>%{customdata}</b></extra>',
                         textposition="top center",
                         marker_color ='darkblue', # layout for the dots
                         marker_size  = 16))

Then, we add a title to our plot, and change other options including template, figure size, and y range. We will also disable y axis and ticks, as well as adjust layout for x axis and ticks.

fig.update_layout(title_text = 
                   "胡適 文章與期刊",
                   title_font_size = 30)

fig.layout.template = "simple_white" # layout template
fig.update_layout(width=1250, height=400) # figure size
fig.update_layout(yaxis_visible=False, yaxis_showticklabels=False) # y axis and ticks
fig.update_layout(yaxis_range=[0,1.5]) # y range
fig.update_xaxes(tickfont_size=24, ticks="outside", ticklen=20, tickwidth=5) # x axis and ticks

fig.show() # diaply plot

Previous Lesson: Simple Bubble Chart using plotly.express

Next Lesson: Coming soon...




Additional information

This notebook is provided for educational purpose and feel free to report any issue on GitHub.


Author: Ka Hei, Chow

License: The code in this notebook is licensed under the Creative Commons by Attribution 4.0 license.

Last modified: December 2021




References:

Plotly