Python’da İnteraktif Veri Görselleştirme: Bokeh

Mustafa Erdogan
Academy Team
Published in
10 min readMay 18, 2023

Geleceğin petrolü olarak kabul edilen verinin açıklanması çok önemlidir. Binlerce satırdan ve sütundan oluşan bir veri setinin bize neler söylediğinin ortaya çıkarılması için veriyi grafikler ile incelemek belki de içinden çıkılmaz olarak görülen bu durumun çok kolay anlaşılmasını sağlamaktadır. İşte tamda bu noktada veri görselleştirme kavramı karşımıza çıkmaktadır.

Veri görselleştirme, veri bilimcilerin, analistlerin ve programcıların veri hakkında çok kısa sürede bilgi sahibi olmasına olanak sağlamakta, bunun yanında verinin analizi sonrasında yapılacak sunumların daha anlaşılır ve etkileyici bir şekilde sunulmasına yardımcı olan önemli bir kavramdır.

Bu yazımızda özellikle Python programlama dilini kullananlar için bu görselleştirme kütüphanelerinden biri olan Bokeh kütüphanesini incelenecektir.

Bokeh

Bokeh, Python tabanlı bir veri görselleştirme kütüphanesidir. Python programlama dilini kullananlar için güçlü bir görselleştirme kütüphanesi olduğu kadar aynı zamanda interaktif, ilgi çekici ve etkileyici görseller oluşturmak için de kullanılmaktadır.

Bokeh Kütüphanesinin Avantajları

Bokeh kütüphanesini, diğer veri görselleştirme kütüphanelerinden ayıran başlıca güçlü yanlarını sıralamk gerekirse;

İnteraktif görselleştirme

Bokeh, zengin interaktif görselleştirme özellikleri ile öen plana çıkmaktadır. Kullanıcılar, grafikler üzerinde yakınlaştırma, kaydırma, seçme, arama gibi etkileşimleri gerçekleştirebilmektedirler. Bu sayede keşifsel veri analizi daha etkileşimli hale gelmektedir.

Web desteği

Bokeh, tasarımsal avantajlarından bir diğeri ise web tabanlı uygulamalar ve görselleştirmeler ile sorunsuz ve uyumlu çalışıyor olmasıdır. Bokeh, HTML, CSS ve JavaScript ile uyumlu çalışmaktadır. Bu özellik, veri görselleştirmelerini web tabanlı projelere entegre etmek için kullanıcılara çok büyük avantaj sağlamaktadır.

Çoklu platform desteği

Bokeh, Python ile geliştirilen uygulamaların yanı sıra Jupyter Notebook, JupyterLab, Flask, Django gibi platformlarda da kullanılabilmektedir. Bu esneklik, farklı ortamlarda ve projelerde Bokeh’in kullanılabilmesine olanak sağladığından kullanıcı dostu bir kütüphane denebilir.

Çizim esnekliği

Bokeh, çizimlerin çok çeşitli özelliklerini ve seçeneklerini kullanmak için seçenekler sunmaktadır. Kısaca BOkeh daha kişisel görseller elde etmek için tasarlanmış bir kütüphanedir. Grafiklerin görüntülenme stili, renk paletleri, etiketleri ve eksenleri özelleştirilebilir, katmanlı grafikler, gölgeler, arka plan resimleri gibi ileri düzey çizim özellikleri kullanılabilmektedir.

Büyük veri setleri için uygunluk

Bokeh’in en büyük özelliklerinden bir diğeri ise büyük veri setleri ile çok rahat çalışabilmesidir. Bokeh, büyük veri setlerini daha etkili işleyebilir ve görselleştirebilir. Veri seti boyutu arttıkça, Bokeh’in performansı düşmez ve hızlı bir şekilde çalışır. Bu özellik, ölçeklenebilir veri analizi projelerinde çok büyük avantaj sağlar.

Bu avantajlar Bokeh’i diğer veri görselleştirme kütüphanelerinden ayıran en önemli argümanlardan bazılarıdır. Kısaca Bokeh kullanıcılarına güçlü ve etkileşimli görselleştirme fırsatı vermektedir.

Bokeh Kütüphanesinin Kurulumu

Bokeh’ı kullanabilmek için öncelikle kütüphaneyi kurmamız gerekmektedir. pip paket yöneticisini kullanarak Bokeh’ı kolayca kurabilirsiniz. Aşağıdaki komutu kullanarak Bokeh’ı kurabilirsiniz:

pip install bokeh

Line Plot çizimi

Şimdi, Bokeh kütüphanesini kullanarak basit bir çizgi grafiği oluşturalım. İlk olarak, Bokeh modüllerini içe aktaralım ve Bokeh için bir veri kaynağı oluşturalım.

from bokeh.plotting import figure, show
from bokeh.io import output_notebook

# Jupyter Notebook için çıktıyı ayarlar
output_notebook()

# Veri oluşturma
x = [2, 4, 6, 8, 10]
y = [12, 14, 4, 16, 18]

# Bokeh için bir figure (şekil) oluşturur
p = figure(title='Basit Bir Cizgi Grafigi', x_axis_label='X', y_axis_label='Y')

# Çizgi grafiğini oluşturur
p.line(x, y, legend_label='Cizgi', line_width=2)

# Grafiği gösterir
show(p)

Scatter Grafiği Çizimi

Şimdi, Bokeh kütüphanesini kullanarak basit bir scatter plot grafiği oluşturalım. Oluşan bu scatter grafiğinde grafiği özellşetimek için bazı parametrelerde kullanılmıştır.

# figure ölçülerini kullanarak yeni bir çizim oluşturur
p = figure(width=400, height=400)

# Grafik dışındaki yapılan özelleştirmeler
p.outline_line_width = 7
p.outline_line_alpha = 0.3
p.outline_line_color = "red"

# Veri oluşturma
x = [2, 4, 6, 8, 10]
y = [12, 8, 4, 16, 18]

# Scatter grafiğini oluşturur
r = p.circle(x, y, size=15, line_color="navy", fill_color="orange", fill_alpha=0.5)

# Grafiği gösterir
show(p)

Scatter grafiğini dilerseniz daireler ile değil kareler kullanaraktan yapabilirsiniz.

# figure ölçülerini kullanarak yeni bir çizim oluştur
p = figure(width=500, height=500)

# Grafik dışındaki yapılan özelleştirmeler
p.outline_line_width = 7
p.outline_line_alpha = 0.3
p.outline_line_color = "purple"

# Veri oluşturma
x = [2, 4, 6, 8, 10]
y = [12, 8, 4, 16, 18]
# Scatter Plot grafiğini oluştur opsiyonel olarak size, color, alpha gir
p.square(x, y, size=[10, 15, 20, 25, 30], line_color="black", color="green", alpha=0.9)

# Grafiği gösterir
show(p)

Grafik Üzerinde Stil ve Düzenleme Yapma
Bokeh, grafiğinizi özelleştirmek için birçok seçenek sunmaktadır. Örneğin, akses etiketlerini, başlığı, çizgi kalınlığını ve renklerini ayarlayabilirsiniz.

# Veri oluşturma
x = [2, 4, 6, 8, 10]
y = [12, 14, 4, 16, 18]

# Çizgi grafiğini oluşturur
p.line(x, y, legend_label='Cizgi', line_width=6, line_color = 'red')

p.title.text = 'Yeni Baslık'
p.xaxis.axis_label = 'Yeni X Ekseni Etiketi'
p.yaxis.axis_label = 'Yeni Y Ekseni Etiketi'

# Grafiği gösterir
show(p)

Hexbin Grafiği

Hexbin grafiği, özellikle büyük veri kümelerinde noktaların yoğunluğunu görselleştirmek için tercih edilmektedir. Grafikteki altıgen hücrelerin sayısı, veri noktalarının nasıl dağıldığını gösterirken, daha fazla altıgen hücre, daha yoğun bir dağılımı temsil etmekte, daha az altıgen hücre, daha seyrek bir dağılımı temsil etmektedir. Yoğunluğu daha yüksek olan bölgeler daha koyu renklerle temsil edilirken, düşük yoğunluklu bölgeler daha açık renklerle temsil edilmektedir.

from bokeh.palettes import Viridis256
from bokeh.util.hex import hexbin

# Veri oluşturun
# n (50000) adet normal dağılıma sahip rastgele x ve y noktaları oluşturulması
n = 50000
x = np.random.standard_normal(n)
y = np.random.standard_normal(n)

# Hexbin oluşturma ve altıgen hücre kenar uzunluğu tanımlanması
bins = hexbin(x, y, 0.1)

# bins.counts ile her bir altıgen hücredeki nokta sayısını elde ederiz.
# Bu sayıları normalize ederek (maksimum nokta sayısına bölerek) 0-255 aralığına getiririz.
# Daha sonra bu değerlere karşılık gelen renkleri Viridis256 renk paletinden seçeriz.
color = [Viridis256[int(i)] for i in bins.counts/max(bins.counts)*255]

# Bokeh grafiği oluşturulması
p = figure(tools="wheel_zoom,reset", match_aspect=True, background_fill_color='#440154')
p.grid.visible = False

# Hexbin grafiğinin çizilmesi
p.hex_tile(bins.q, bins.r, size=0.1, line_color=None, fill_color=color)

# Grafiği göster
show(p)

image & image_rgba Grafikleri

Bu fonksiyonlarla oluşturulan grafikler ısı haritaları ile benzer şekilde yorumlanmaktadır.

image fonksiyonu ile oluşturulan görseller tek bir renk paleti kullanarak gri tonlamalı bir görüntü oluşturur ve her pikselin değeri renk paleti aracılığıyla bir renge dönüştürülerek görselleştirilebilir.

image_rgba fonksiyonu ile RGB(A) (Kırmızı, Yeşil, Mavi, Alfa) piksel renkleri kullanılarak görselleştirilmektedir. Bu fonksiyon, piksellerin renk değerlerinin doğrudan belirtmesini sağlamaktadır. Bu sayede, renk paleti kullanma zorunluluğu olmadan, daha özelleştirilmiş grafikler tasarlanabilmektedir.

# Veri oluşturun
# 0 ile 10 arasında, N adet nokta oluşturan bir x ve y dizisi oluşturun
N = 500
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)

# x ve y dizilerini kullanarak 2D bir ızgara oluşturuyorsunuz.
# xx ve yy matrisleri, her noktanın koordinatlarını içerecektir.
xx, yy = np.meshgrid(x, y)

# np.sin(xx) ve np.cos(yy) işlemlerini kullanarak img adında bir görüntü matrisi oluşturuyorsunuz.
# Bu matris, xx ve yy koordinatlarının sinüs ve kosinüs fonksiyonlarına göre hesaplanan değerlerini içerecektir.
img = np.sin(xx)*np.cos(yy)

# Figure fonksiyonunu kullanarak bir çizim alanı (p) oluşturuyorsunuz.
# x_range ve y_range parametreleri ile x ve y eksenlerinin aralığını belirliyorsunuz.
p = figure(x_range=(0, 10), y_range=(0, 10))

# image fonksiyonunu kullanarak çizim alanına bir görüntü ekliyoruz.
# image parametresi olarak img matrisini veriyorsunuz.
# x ve y parametreleri ile görüntünün başlangıç noktasını belirliyorsunuz.
# dw ve dh parametreleri ile görüntünün genişlik ve yüksekliğini ayarlıyorsunuz.
# Palette parametresi, görüntünün renk paletini belirler.
p.image(image=[img], x=0, y=0, dw=10, dh=10, palette="Spectral11")

# Grafiği göster
show(p)
from __future__ import division
import numpy as np

# N değişkenine 20 değerini atıyorsunuz.
# Bu, görüntünün boyutunu belirleyen bir parametredir.
# Görüntü 20x20 piksel boyutunda olacak.
N = 20

# img adında bir Numpy dizisi oluşturuyorsunuz.
# Bu dizi, N x N boyutunda bir görüntüyü temsil eder.
# dtype=np.uint32 parametresi
# Her pikselin RGBA değerlerini 32 bitlik tamsayı olarak tutacağını belirtir.
img = np.empty((N,N), dtype=np.uint32)

# view adında yeni bir dizi oluşturuyorsunuz.
# Bu dizi, img dizisine bir görünüm sağlar
# Her bir pikselin RGBA kanallarına ayrı ayrı erişimi mümkün kılar.
# dtype=np.uint8 parametresi
# Her RGBA kanalının 8 bitlik tamsayı olarak tutulacağını belirtir.
view = img.view(dtype=np.uint8).reshape((N, N, 4))

# for döngüsü kullanarak, her piksele bir RGBA değeri atıyorsunuz.
# Bu değerler pikselin rengini belirler.
# Kırmızı kanal (R) pikselin yatay pozisyonuna bağlı olarak değişir
# Yeşil kanal (G) 158 olarak sabitlenir
# Mavi kanal (B) pikselin dikey pozisyonuna bağlı olarak değişir.
# Alpha kanalı (A) ise tamamen opaktır ve değeri 255'tir.
for i in range(N):
for j in range(N):
view[i, j, 0] = int(i/N*255) # red
view[i, j, 1] = 158 # green
view[i, j, 2] = int(j/N*255) # blue
view[i, j, 3] = 255 # alpha

# bir çizim alanı (figure) oluşturuyoruz.
# x_range ve y_range parametreleri, çizim alanının x ve y eksenlerinin aralığını belirler.
p = figure(x_range=[0,10], y_range=[0,10])

# image_rgba fonksiyonunu kullanarak çizim alanına bir RGBA görüntü ekliyoruz.
p.image_rgba(image=[img], x=[0], y=[0], dw=[10], dh=[10])

# Grafiği göster
show(p)

Etkileşimli (İnteraktif) Grafikler

Bokeh kütüphanesi, grafiklerin özelleştirilmesine ve grafiklerin interaktif şekilde görülmesine olanak tanır. Ayrıca, eksenlerin özelleştirilmesi ve arka plana görsel ekleme gibi daha gelişmiş özelleştirmelere fırsat vermektedir.

Glyph

Glyph’ler, Bokeh kütüphanesindeki çizim araçları ve plot objeleriyle birlikte kullanılmaktadır. Çizim alanına eklenen bir veya daha fazla Glyph, veri setinin görselleştirilmesine ve kullanıcıların veriyi etkileşimli olarak keşfetmelerine olanak tanımaktadır.

# figure ölçülerini kullanarak yeni bir çizim oluşturur
p = figure(width=400, height=400)

# Grafik dışındaki yapılan özelleştirmeler
p.outline_line_width = 7
p.outline_line_alpha = 0.3
p.outline_line_color = "red"

# Veri oluşturma
x = [2, 4, 6, 8, 10]
y = [12, 8, 4, 16, 18]

# Glyph grafiğini oluşturur
r = p.circle(x, y)

# Dairenin boyutu ayarlanır
r.glyph.size = 50

# Dairenin iç renginin şeffaflığı ayarlanır
r.glyph.fill_alpha = 0.2

# Dairenin kenar çizgisinin rengi ayarlanır
r.glyph.line_color = "firebrick"

# Dairenin kenar çizgisinin şekli (line_dash) ve
# Çizgilerin ve boşlukların boyu [5, 1] ayarlanır
r.glyph.line_dash = [5, 1]

# Dairenin kenar çizgisinin kalınlığı ayarlanır
r.glyph.line_width = 2

# Grafiği gösterir
show(p)

Bokeh Data setleri

Şimdi ise Bokeh kütüphanesinin içerisinde gömülü data setleri ile birkaç örnek yapalım. Öncelikle Bokeh kütüphanesindeki data setlerinin indirilmesi gerekmektedir.

import bokeh.sampledata
bokeh.sampledata.download()

Bokeh kütüphanesi içinde olan “glucose” data seti ile interaktif bir grafik örneği yapalım.

# veri noktalarının üzerine geldiğinde interaktif
# bir açıklama görüntülemek için kullanılan bir araçtır.
from bokeh.models.tools import HoverTool
from bokeh.sampledata.glucose import data

# "glucose" veri setinden 2010-10-06 tarihindeki verileri seçiyoruz
subset = data.loc['2010-10-06']

# Seçilen verilerin zaman damgası (index) değerlerini x değişkenine
# 'glucose' sütunundaki değerleri y değişkenine atıyoruz
x, y = subset.index.to_series(), subset['glucose']

# 600 x 300 piksel bir çizim alanı (figure) oluşturuyoruz.
# x_axis_type="datetime" parametresi, x ekseninin zaman damgası
# olarak yorumlanacağını belirtir.
# Ayrıca, çizim alanına bir başlık (title) ekliyoruz.
p = figure(width=600, height=300, x_axis_type="datetime", title='Hover over points')

# line fonksiyonunu kullanarak çizim alanına bir çizgi grafik ekliyoruz.
# x ve y değişkenleri, çizginin x ve y koordinatlarını belirtir.
# line_dash parametresiyle çizgiyi kesikli bir desenle,
# line_width parametresiyle çizgi kalınlığını
# color parametresiyle çizgi rengini ayarlarız.
p.line(x, y, line_dash="4 4", line_width=1, color='gray')

# fonksiyonunu kullanarak çizim alanına daire glyph'leri ekliyoruz
# x ve y değişkenleri, dairelerin merkez koordinatlarını belirtir.
# size parametresiyle dairelerin boyutunu,
# fill_color parametresiyle dolgu rengini,
# hover_fill_color parametresiyle fare üzerine gelindiğinde dolgu rengini,
# fill_alpha parametresiyle dolgu şeffaflığını,
# hover_alpha parametresiyle fare üzerine gelindiğinde dolgu şeffaflığını,
# line_color parametresiyle kenar çizgisinin rengini
# hover_line_color parametresiyle fare üzerine gelindiğinde kenar çizgisinin rengini ayarlarız.
# circle fonksiyonu ile, GlyphRenderer tipinden bir nesne döndürülür ve cr değişkenine atarız.
cr = p.circle(x, y, size=20,
fill_color="grey", hover_fill_color="firebrick",
fill_alpha=0.05, hover_alpha=0.3,
line_color=None, hover_line_color="white")

# tooltips=None parametresiyle açıklamaların görüntülenmeyeceğini belirtirsiniz.
# renderers parametresiyle hangi görsellerin (GlyphRenderer'larının)
# bu araca bağlanacağını belirtiriz
# mode='hline' parametresiyle yatay bir çizgi modunda açıklamaların görüntüleneceğini belirtiriz.
p.add_tools(HoverTool(tooltips=None, renderers=[cr], mode='hline'))

# Grafiği göster
show(p)
from bokeh.sampledata.autompg import autompg
from bokeh.models import LinearColorMapper, ColorBar, HoverTool
from bokeh.transform import transform
from bokeh.plotting import figure, show
from bokeh.models.sources import ColumnDataSource

source = ColumnDataSource(autompg)
color_mapper = LinearColorMapper(palette="Viridis256", low=autompg.weight.min(), high=autompg.weight.max())

p = figure(x_axis_label='Horsepower', y_axis_label='MPG', tools='hover', toolbar_location=None)
p.circle(x='hp', y='mpg', color=transform('weight', color_mapper), size=20, alpha=0.6, source=autompg)

color_bar = ColorBar(color_mapper=color_mapper, label_standoff=12, location=(0,0), title='Weight')
p.add_layout(color_bar, 'right')

hover = p.select_one(HoverTool)
hover.tooltips = [('MPG', '@mpg'), ('Horsepower', '@hp'), ('Weight', '@weight')]

show(p)

İris data seti ile bir başka interaktif görselleştirme yapalım.

from bokeh.plotting import figure, show
from bokeh.sampledata.iris import flowers
from bokeh.transform import factor_cmap
from bokeh.palettes import Category10

# Veri setini yüklüyoruz
df = flowers.copy()

# Çiçek türlerine göre renk paleti oluşturuyoruz
color_map = factor_cmap('species', palette=Category10[3], factors=df['species'].unique())

# Jupyter Notebook çıktısını etkinleştiriyoruz
output_notebook()

# Figure oluşturuyoruz
p = figure(title='Iris Çiçekleri', x_axis_label='Sepal Length', y_axis_label='Petal Length')

# Scatter plot çiziyoruz
scatter = p.circle(x='sepal_length', y='petal_length', size=8, color=color_map, legend_field='species', source=df)

# HoverTool oluşturuyoruz
hover = HoverTool(tooltips=[('Sepal Length', '@sepal_length'), ('Petal Length', '@petal_length')], renderers=[scatter])

# Figure'a HoverTool'u ekleyoruz
p.add_tools(hover)

# Legend'i konumlandırıyoruz
p.legend.location = 'top_left'

# Plot'u gösteriyoruz
show(p)

Bokeh, Python tabanlı bir görselleştirme kütüphanesidir ve verileri etkileşimli ve profesyonel görünümlü grafiklere dönüştürmek için kullanılmaktadır. Bokeh, geniş bir grafik çeşitliliğine sahip olarak kullanıcılara çizgi grafikler, scatter plotlar, bar grafikler, alan grafikleri, histogramlar, haritalar ve daha fazlası için fırsat vermektedir.

Bokeh’in en önemli özelliklerinden bir diğeri ise yukarıda görüldüğü üzere etkileşimli grafikler konusunda kullanıcılara fırsat vermesidir. Grafiklere kullanıcılar tarafından fareyle etkileşim eklenebilir, araç ipuçları, kaydırma ve yakınlaştırma gibi özellikler kullanılabilmektedir. Böylece kullanıcılar verileri daha ayrıntılı bir şekilde inceleyebilir ve grafikler üzerinde gezinebilir.

Renk paletleri ve renk eşleme yöntemleri de Bokeh’in güçlü özelliklerinden bir diğeridir. Bu sayede veriler renklendirilerek kategoriler veya değer aralıkları vurgulanabilir ve görselleştirmenin anlaşılması daha kolay hale gelebilmektedir.

Sonuç olarak, Bokeh, verileri çekici ve etkileşimli grafiklere dönüştürme imkanı sunan güçlü bir kütüphanedir. Bokeh’in geniş grafik seçenekleri, etkileşimli özellikleri ve renklendirme yetenekleri sayesinde veri analizini ve sunumunu daha etkileyici hale getirebilirsiniz.

Faydalı olması dileğiyle.

--

--

Mustafa Erdogan
Academy Team

I am Data Scientist and I have more than 4 years of experience in applications of Artificial Intelligence, and Machine Learning.