Altair repeated chart, add different subplot/chart title - altair

I can't believe I haven't been able to google the answer for this .... in the documented example of repeated charts, how would I add a different sub-chart titles?
import altair as alt
from vega_datasets import data
iris = data.iris.url
alt.Chart(iris).mark_point().encode(
alt.X(alt.repeat("column"), type='quantitative'),
alt.Y(alt.repeat("row"), type='quantitative'),
color='species:N'
).properties(
width=200,
height=200,
title="Chart title",
).repeat(
row=['petalLength', 'petalWidth'],
column=['sepalLength', 'sepalWidth']
).interactive()
adds the same title to each sub-chart. Can I pass in a list of titles here? The figure in this question shows that the same chart title would show up in all columns. The same seems to be the case for my data/code:

I don't think it is possible to change title for repeated charts, but depending on your application you might be able to workaround this by using a transform_fold + faceting instead:
import altair as alt
from vega_datasets import data
iris = data.iris.url
alt.Chart(iris).mark_point().encode(
alt.X('species:N'),
alt.Y('value:Q'),
color='species:N'
).transform_fold(
['petalLength', 'petalWidth', 'sepalLength', 'sepalWidth']
).facet(
'key:N'
)

Related

Altair dropdown for linear or log scale

I'd like for be able to toggle between log and linear scale in my altair plot. I'd also like to avoid multiple columns of transformed data if possible. I've tried this but get an error AttributeError: 'Scale' object has no attribute 'selection'
import altair as alt
from vega_datasets import data
cars_data = data.cars()
input_dropdown = alt.binding_select(options=['linear','log'], name='Scale')
selection = alt.selection_single(fields=['Miles_per_Gallon'], bind=input_dropdown)
scale = alt.condition(selection, alt.Scale(type = 'linear'), alt.Scale(type = 'log'))
alt.Chart(cars_data).mark_point().encode(
x='Horsepower:Q',
y = alt.Y('Miles_per_Gallon:Q',
scale=scale),
tooltip='Name:N'
).add_selection(
scale
)
I've tried a variety of different things but can't seem to make it work. Any suggestions are greatly appreciated.

Altair show overlapping images

I want to show overlapping images using altair.
Here's a demo code.
import altair as alt
import pandas as pd
source = pd.DataFrame([{"x": [0,0,0], "y": [0,0,0],
"img": ["https://vega.github.io/vega-datasets/data/gimp.png",
"https://vega.github.io/vega-datasets/data/7zip.png",
"https://vega.github.io/vega-datasets/data/ffox.png"]},])
chart=alt.Chart(source).mark_image(width=100,height=100,).encode(x='x',y='y',url='img')
chart
What I see as an output is not what I expected:
I wonder what's the issue here(?).
You probably meant to construct your dataframe this way:
source = pd.DataFrame({"x": [0,0,0], "y": [0,0,0],
"img": ["https://vega.github.io/vega-datasets/data/gimp.png",
"https://vega.github.io/vega-datasets/data/7zip.png",
"https://vega.github.io/vega-datasets/data/ffox.png"]})
i.e. it should have three rows rather than one row. If you do this, the chart works, and the last image appears on top of the others, as expected.

Show only some bar labels for matplotlib bar chart

I have a bar chart with a lot of columns (around 100). I want to show only some of the bar labels (they are ordered in such a way that this is a perfectly reasonable way to present the data). Is there a simple way to do this, say show every 3rd or 5th label? I know I can manually pull together the list, but I figure there's likely an elegant option.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(100)
groupings = np.arange(0,100)
x_pos = [i for i, _ in enumerate(groupings)]
plt.bar(x_pos,data)
plt.xticks(x_pos,groupings)

Bokeh plot line not updating after checking CheckboxGroup in server mode (python callback)

I have just initiated myself to Bokeh library and I would like to add interactivity in my dashboard. To do so, I want to use CheckboxGroup widget in order to select which one of a pandas DataFrame column to plot.
I have followed tutorials but I must have misunderstood the use of ColumnDataSource as I cannot make a simple example work...
I am aware of previous questions on the matter, and one that seems relevant on the StackOverflow forum is the latter :
Bokeh not updating plot line update from CheckboxGroup
Sadly I did not succeed in reproducing the right behavior.
I have tried to reproduce an example following the same updating structure presented in Bokeh Server plot not updating as wanted, also it keeps shifting and axis information vanishes by #bigreddot without success.
import numpy as np
import pandas as pd
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.palettes import Spectral
from bokeh.layouts import row
from bokeh.models.widgets import CheckboxGroup
from bokeh.io import curdoc
# UPDATE FUNCTION ------------------------------------------------
# make update function
def update(attr, old, new):
feature_selected_test = [feature_checkbox.labels[i] for i in feature_checkbox.active]
# add index to plot
feature_selected_test.insert(0, 'index')
# create new DataFrame
new_df = dummy_df.filter(feature_selected_test)
plot_src.data = ColumnDataSource.from_df(data=new_df)
# CREATE DATA SOURCE ------------------------------------------------
# create dummy data for debugging purpose
index = list(range(0, 890))
index.extend(list(range(2376, 3618)))
feature_1 = np.random.rand(len(index))
feature_2 = np.random.rand(len(index))
feature_3 = np.random.rand(len(index))
feature_4 = np.random.rand(len(index))
dummy_df = pd.DataFrame(dict(index=index, feature_1=feature_1, feature_2=feature_2, feature_3=feature_3,feature_4=feature_4))
# CREATE CONTROL ------------------------------------------------------
# list available data to plot
available_feature = list(dummy_df.columns[1:])
# initialize control
feature_checkbox = CheckboxGroup(labels=available_feature, active=[0, 1], name='checkbox')
feature_checkbox.on_change('active', update)
# INITIALIZE DASHBOARD ---------------------------------------------------
# initialize ColumnDataSource object
plot_src = ColumnDataSource(dummy_df)
# create figure
line_fig = figure()
feature_selected = [feature_checkbox.labels[i] for i in feature_checkbox.active]
# feature_selected = ['feature_1', 'feature_2', 'feature_3', 'feature_4']
for index_int, col_name_str in enumerate(feature_selected):
line_fig.line(x='index', y=col_name_str, line_width=2, color=Spectral[11][index_int % 11], source=plot_src)
curdoc().add_root(row(feature_checkbox, line_fig))
The program should work with a copy/paste... well without interactivity...
Would someone please help me ? Thanks a lot in advance.
You are only adding glyphs for the initial subset of selected features:
for index_int, col_name_str in enumerate(feature_selected):
line_fig.line(x='index', y=col_name_str, line_width=2, color=Spectral[11][index_int % 11], source=plot_src)
So that is all that is ever going to show.
Adding new columns to the CDS does not automatically make anything in particular happen, it's just extra data that is available for glyphs or hover tools to potentially use. To actually show it, there have to be glyphs configured to display those columns. You could do that, add and remove glyphs dynamically, but it would be far simpler to just add everything once up front, and use the checkbox to toggle only the visibility. There is an example of just this in the repo:
https://github.com/bokeh/bokeh/blob/master/examples/app/line_on_off.py
That example passes the data as literals the the glyph function but you could put all the data in CDS up front, too.

Altair plot, show vertical bars

import pandas as pd
import altair as alt
dicta = {
'date':['2019-06-29', '2019-06-30', '2019-07-01', '2019-07-02', '2019-07-03'],
'amount':[-9.35, -6.42, -13.55, -12.88, -12.24] }
dataset = pd.DataFrame(dicta)
alt.Chart(dataset).mark_bar().encode(
x = "date:T",
y = "amount:N"
)
I'm not sure why this generates horizontal bars, instead of vertical bars by default.
How can I change it? I would like to see a bar per day, up to the amount for the day.
Found the answer. I encoded the numerical column with N. But this is for nominal data, and got Altair confused. Need to use Q/ Quantitative

Resources