We are planning to introduce python in the workplace. If I was looking for something I couldn't do with Excel and something I could do with Python, You can draw ** interactive graphs ** using a library called ** Bokeh **. I researched various things together with ** HoloViews ** that I was interested in in the article of here, so I summarized it.
Refers to a graph that responds to user operations. (Interactive = bidirectional) You can move around with the mouse, zoom, and display information like this.
For the time being, I wanted to get started quickly, so I implemented it with Google Colaboratory. Therefore, the description about library installation is omitted in this article. (Unverified, but if you install the library, it should work with Jupyter Notebook)
Prepare the following data of the first Pokemon in DataFrame format. Data is taken from the official Pokédex and Pokemon Wiki.
How to draw a basic graph. This time I will write a scatter graph.
#Import of graph related library
import holoviews as hv
hv.extension('bokeh')
#Basic drawing
poke_graph = hv.Scatter(poke_df,kdims=["height"],vdims=["weight"])
#display
poke_graph
Extend holoviews to bokeh mode with hv.extension ('bokeh')
.
( The graph will not be displayed unless the above is described for each cell )
Create a scatter plot instance with hv.Scatter ()
.
In the case of Scatter, specify the dataset to be used and ** kdims ** and ** vdims ** as arguments.
kdims: key dimensions. Key element. x-axis image.
vdims: value dimensions. Value element corresponding to the above key. In addition to the y-axis, it can also be applied to the optional values described below.
The display can be displayed just by writing the instance name like pandas.
(Jupyter Notebook requires a spell called output_notebook ()
to display the graph)
holoviews can add graph options later.
hv.extension('bokeh')
#Title setting
poke_graph.opts(title="Pokemon data")
#Grid drawing
poke_graph.opts(show_grid=True)
#Change axis label
poke_graph.opts(xlabel="height", ylabel="Weight")
Set various options with instance.opts (…)
.
It is set individually for the sake of clarity, but it can also be set collectively with a single .opts
.
poke_graph.opts (title =" Pokemon data ", show_grid = True, xlabel =" Takasa ", ylabel =" Weight ")
The settings related to markers look like this
hv.extension('bokeh')
#Marker color setting
poke_graph.opts(color = "red")
#Marker edge color setting
poke_graph.opts(line_color = "black")
#Marker size setting
poke_graph.opts(size=7)
#Marker transparency setting
poke_graph.opts(alpha = 0.8)
The above is a bit cramped, so I added settings to make it easier to see.
hv.extension('bokeh')
#Background color setting
poke_graph.opts(bgcolor = "whitesmoke")
#Setting the drawing size of the graph area
poke_graph.opts(width=640, height=480)
#Font size is uniform and large
poke_graph.opts(fontscale=1.5)
#Axis format change
poke_graph.opts(xformatter="%.1f m", yformatter="%.1f kg")
Here, let's apply the total race value to the size of the marker as in the bubble chart.
When applying an element to an option, the display will be strange if the element has not been added to vdims .
So, add an element to the dimension with .add_dimension ()
.
poke_graph2 = poke_graph.add_dimension("Total race value",dim_pos=2,vdim=True,dim_val = "total")
Specify the element name in the first argument. Specify the number to add (insert) the element with dim_pos
.
(I don't know how the order of vdims will affect it, but for the time being, it would be nice if the new element didn't start at the beginning.
Try to add to vdims with vdim = True
(if omitted, it will be added to kdims).
Specify the data to be actually used as a value with dim_val =
. In this case, the dataset has already been passed in DataFrame format, so you can just specify it by column name. In addition to the values specified in the dataset, you can also specify new values such as dim_val = df ["special "]
and dim_val = poke_df ["total "] ** 2
.
Once added to vdims, you will be able to pass the dimension name you added to the argument with opts.
poke_graph2 = poke_graph2.opts(size="Total race value")
Oops.
The reason for the above is that size is passed a large value such as 600.
To avoid this, convert the value with a mathematical formula. You must then use dim ()
to apply the element to the formula .
from holoviews import dim
poke_graph2 = poke_graph2.opts(size=(dim("Total race value")/poke_df["total"].min())*5)
In the above example, the ratio of the total value of the total race value of each Pokemon to the minimum value of the total race value is multiplied by 5 to obtain the size value.
It is also possible to specify the marker color from the element.
As with size, first add an element to vdims and specify the dimension name in color =
.
hv.extension('bokeh')
#Added type 1 to data element
poke_graph3 = poke_graph2.add_dimension("Type 1",dim_pos=2,vdim=True,dim_val = "Type 1")
#Set the marker color according to "Type 1"
poke_graph3.opts(color="Type 1")
#Set the legend position to the right
poke_graph3.opts(legend_position="right")
#Reset the width of the drawing size
poke_graph3.opts(width=800)
In the above, the color is automatically assigned, but it can be any color.
Create a dictionary with the element to be passed to color as the key and the color as the value, and pass it to cmap =
.
color_table = {"normal":"cornsilk", "Fire":"orangered", "Mizu":"royalblue", "Denki":"gold",
"Kusa":"green", "Ice":"powderblue", "Fighting":"darkorange", "Poison":"mediumorchid",
"Ground":"saddlebrown", "flight":"lightcyan", "Esper":"khaki", "insect":"yellowgreen",
"Iwa":"dimgrey", "ghost":"mediumpurple", "Dragon":"lightseagreen",
"Evil":"indigo", "Steel":"steelblue","Fairy":"pink",
}
poke_graph3.opts(color="Type 1",cmap=color_table)
The same color name as matplotlib can be used. Maybe you can also specify hexadecimal RGB.
Try using a tooltip, one of the features of bokeh.
hv.extension('bokeh')
#Add Pokemon name to data element
poke_graph4 = poke_graph3.add_dimension("name",dim_pos=2,vdim=True,dim_val = "name")
#Import hover tools
from bokeh.models import HoverTool
#Hover tool settings
TOOLTIPS = [("name","@name")]
hover = HoverTool(tooltips=TOOLTIPS)
#Apply hover tool settings to the graph
poke_graph4 = poke_graph4.opts(plot=dict(tools=[hover]))
Hover tools are a type of tooltip. Information on the element that the cursor is on can be displayed.
Create an instance of HoverTool
and pass the information you want to display in the argumenttooltips =
as a list of tuples.
Information to be displayed on one line is described in the tuple. Multiple lines can be displayed by passing multiple tuples.
Specify the dimension name added to vdims with " @ ~ "
. If the dimension name is Japanese, it will not be recognized unless it is enclosed in {} like " @ {attack} "
.
In addition to "@ ~", basic information of elements can be displayed by "\ $ x" or "$ index".
In addition, a more elaborate layout is possible with HTML description. In addition to the \