Altair add selector to change color scheme - altair

I have a simple plot withe the color scheme dark2
import altair as alt
from vega_datasets import data
source = data.cars.url
alt.Chart(source).mark_circle(size=60).encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color='Origin:N',
).configure_range(
category={'scheme': 'dark2'}
)
I'd like to add a dropdown selector that allows the user to switch between dark2 and accent. I've tried a variety of different approaches but nothing seems to be correct. Any help is greatly appreciated.

Was able to figure out the solution by using the approach below
import altair as alt
from vega_datasets import data
cars = data.cars()
input_dropdown = alt.binding_select(options=['accent','dark2'], name='Color Scheme')
param = alt.Parameter(name="schemeselect", value = "accent", bind = input_dropdown)
alt.Chart(cars,params = [param]).mark_circle(size=60).encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.Color('Origin', scale=alt.Scale(scheme={"expr": "schemeselect"})),
)

Related

Controlling Streamlit st_aggrid (AgGrid) layout by placing grid inside an st.container, st.column, or st.empty

Python 3.8.10
Ubuntu 20.04
Using st_aggrid (the Python port of AgGrid for Streamlit.)
Streamlit allows for layout control using st.column, st.empty, and st.container. The format is (for example)...
col1, col2 = st.columns(2)
original = Image.open(image)
col1.header("Original")
col1.image(original, use_column_width=True)
grayscale = original.convert('LA')
col2.header("Grayscale")
col2.image(grayscale, use_column_width=True)
Notice that col1 and col2 replace the st. in all the commands.
I.e. without columns it would be...
import streamlit as st
original = Image.open(image)
st.header("Original")
st.image(original, use_column_width=True)
grayscale = original.convert('LA')
st.header("Grayscale")
st.image(grayscale, use_column_width=True)
...and things would all just appear one on top of the other on the page.
st_aggrid Grid's are created and placed using the command ...
instruments_gb = GridOptionsBuilder.from_dataframe(instruments_df)
if st.session_state["enable_sidebar"]:instruments_gb.configure_side_bar()
instruments_gb.configure_selection(st.session_state["selection_mode"])
instruments_gb.configure_selection(st.session_state["selection_mode"], use_checkbox=True, groupSelectsChildren=st.session_state["groupSelectsChildren"], groupSelectsFiltered=st.session_state["groupSelectsFiltered"])
instruments_gb.configure_selection(st.session_state["selection_mode"], use_checkbox=False, rowMultiSelectWithClick=True, suppressRowDeselection=True)
instruments_gb.configure_grid_options(domLayout='normal')
instruments_gridOptions = instruments_gb.build()
AgGrid(
instruments_df,
gridOptions=instruments_gridOptions,
height=st.session_state["grid_height"],
width='100%',
data_return_mode=st.session_state["return_mode_value"],
update_mode=st.session_state["update_mode_value"],
fit_columns_on_grid_load=True,
allow_unsafe_jscode=True, #Set it to True to allow js function to be injected
enable_enterprise_modules=True,
)
This will create and display the Grid. Note that st. is not used anywhere within the commands.
How can I place an st_aggrid Grid inside a Streamlit
container/placeholder?
Alternatively, can the Grid be placed in a
specific location on the page, without using Streamlit containers?
Here is an example on how to place aggrid inside the container.
import streamlit as st
import numpy as np
from st_aggrid import AgGrid
import pandas as pd
data = {
'country': ['norway', 'russia', 'china', 'japan'],
'capital': ['oslo', 'moscow', 'beijing', 'tokyo']
}
df = pd.DataFrame(data)
with st.container():
st.write("This is inside the container")
AgGrid(df, height=200)
st.bar_chart(np.random.randn(50, 3))
st.write("This is outside the container.")
Output

Updating bqplot image widget

I'm working on a project that uses ipywidgets and bqplot to display and interact with an image.
Using ipywidgets and open cv I can modify an image, save it and update the value of the widget. But I also need the on_click_element aspect of bqplot, so I use the widget from the last one. I still have problems figuring out how to do the same thing with the widget in bqplot.
I would like to avoid to redraw the hole thing, but if needed it would have to close and redraw only the widget image since this is part of a bigger set of widgets. For example I would like to binarize the image using an arbitrary treshold.
From here I got the information on how to use the bqplot image widget: https://github.com/bqplot/bqplot/blob/master/examples/Marks/Object%20Model/Image.ipynb
I use something very similar to this to create the widget that I display.
from IPython.display import display
import ipywidgets as widgets
import bqplot as bq
with open('chelsea.png', 'rb') as f:
raw_image = f.read()
ipyimage = widgets.Image(value=raw_image, format='png')
x_sc = bq.LinearScale()
y_sc = bq.LinearScale()
bq_image = bq.Image(image=ipyimage, scales={'x':x_sc, 'y':y_sc})
img_ani = bq.Figure(marks=[bq_image], animation_duration=400)
display(img_ani)
After this I can't update the figure without redrawing the hole thing.
Any ideas?
jupyter 5.7.8,
ipython 7.5.0,
ipywidgets 7.5.1,
bqplot 0.12.10
Update the bqplot image mark by assigning a new image....
with open("chelsea2.png", 'rb') as f:
raw_image2 = f.read()
# ipyimage.value = raw_image2 # This doesn't seems to sync with widget display. Would require a redisplay of bqplot figure
# create new ipywidgets image and assign it to bqplot image
ipyimage2 = widgets.Image(value=raw_image2, format='png')
bq_image.image = ipyimage2

How to display/save a Layered graph in altair by running code from Python console

After creating three different charts with altair graph API and then merging them as per altair documentation.
(underlay+base+overlay).save("layeredChart.html")
An html file is generated with name layeredChart.html
On opening the html file error comes:
JavaScript Error: Duplicate signal name: "selector002_tuple"
This usually means there's a typo in your chart specification. See the javascript console for the full traceback.
What can be the reason for error in html file generation with altair though works fine with jupyter notebook??
Code:
import altair as alt
#altair plot
alt.data_transformers.disable_max_rows()
#Selection tool
selection = alt.selection_single(fields = ['Country/Region'])
#Underlay
base = alt.Chart(de_long).mark_line(strokeWidth=4,opacity=0.7).encode(
x = alt.X('Day'),
y = alt.Y('De',scale=alt.Scale(type='log')),
color = alt.Color('Country/Region',legend=None)
).properties(
width=800,
height=650
).interactive()
print(alt.renderers.names())
#Chart
chart1 = base.encode(
color=alt.condition(selection,'Country/Region:N',alt.value('lightgray'))).add_selection(selection)
#Overlay
overlay = base.encode(
color = 'Country/Region',
opacity = alt.value(0.5),
tooltip = ['Country/Region:N','Name:N']
).transform_filter(selection)
finalChart = (base+chart1+overlay)
finalChart.save("final.html")
This error generally means that you've called add_selection() with the same selection on multiple layers, which is not supported by the Vega-Lite renderer.
Here is a Minimal Reproducible Example of this error:
import altair as alt
import pandas as pd
df = pd.DataFrame({'x': range(10)})
selection = alt.selection_single()
base = alt.Chart(df).encode(x='x').add_selection(selection)
base.mark_line() + base.mark_point()
Javascript Error: Duplicate signal name: "selector001_tuple"
This usually means there's a typo in your chart specification. See the javascript console for the full traceback.
The way to fix it is to add the selection to only one of the layers; for example:
base = alt.Chart(df).encode(x='x')
base.mark_line() + base.mark_point().add_selection(selection)

How to fix fusion charts displaying black color in 3d charts on safari?

I've implemented fusion charts in angular and node.js application. The charts appear black on safari but works fine with all other browsers.
I have researched and found out that it is something with the path of gradient colors because only 3D charts appear to not work properly. I have tried removing the base tag from main.html but that upsets my routing. Is there any other way I can fix this issue without disturbing my routing?
import { FusionChartsModule } from "angular-fusioncharts";
import FusionCharts from "fusioncharts/core";
import * as Candy from "fusioncharts/themes/fusioncharts.theme.candy";
import * as FusionTheme from "fusioncharts/themes/fusioncharts.theme.fusion";
import * as Gammel from "fusioncharts/themes/fusioncharts.theme.gammel";
import * as Umber from "fusioncharts/themes/fusioncharts.theme.umber";
import Doughtnut2d from "fusioncharts/viz/doughnut2d";
import MsArea from "fusioncharts/viz/msarea";
import MsBar3d from "fusioncharts/viz/msbar3d";
import MsColumn2d from "fusioncharts/viz/mscolumn2d";
import MsColumn3d from "fusioncharts/viz/mscolumn3d";
import MsColumnLine3d from "fusioncharts/viz/mscolumnline3d";
import MsLine from "fusioncharts/viz/msline";
import OverlappedCoulmn2d from "fusioncharts/viz/overlappedcolumn2d";
import Pie2d from "fusioncharts/viz/pie2d";
import Pie3d from "fusioncharts/viz/pie3d";
import StackedColumn2d from "fusioncharts/viz/stackedcolumn2d";
import StackedColumn3d from "fusioncharts/viz/stackedcolumn3d";
FusionChartsModule.fcRoot(
FusionCharts,
Pie2d,
Pie3d,
StackedColumn2d,
OverlappedCoulmn2d,
MsColumn2d,
MsBar3d,
MsColumn3d,
Doughtnut2d,
StackedColumn3d,
MsLine,
MsArea,
MsColumnLine3d,
Gammel,
Candy,
Umber,
FusionTheme,
);
This is the way I am including Fusion Charts library into my application. If there is any options I can change to fix SVG paths.
Thank you!

Python, Bokeh, "oops! something went wrong" when mapping

I'm working my way through the Bokeh user guide and am getting stuck on the Mapping Geo Data section.
I've pretty much copy and pasted the code, but for some reason keep getting the following:
The code as follows:
from bokeh.io import output_file, show
from bokeh.models import (
GMapPlot, GMapOptions, ColumnDataSource, Circle, Range1d, PanTool, WheelZoomTool, BoxSelectTool
)
map_options = GMapOptions(lat=30.29, lng=-97.73, map_type="roadmap", zoom=11)
plot = GMapPlot(x_range=Range1d(), y_range=Range1d(), map_options=map_options)
plot.title.text = "Austin"
# For GMaps to function, Google requires you obtain and enable an API key:
#
# https://developers.google.com/maps/documentation/javascript/get-api-key
#
# Replace the value below with your personal API key:
plot.api_key = "GOOGLE_API_KEY"
source = ColumnDataSource(
data=dict(
lat=[30.29, 30.20, 30.29],
lon=[-97.70, -97.74, -97.78],
)
)
circle = Circle(x="lon", y="lat", size=15, fill_color="blue", fill_alpha=0.8, line_color=None)
plot.add_glyph(source, circle)
plot.add_tools(PanTool(), WheelZoomTool(), BoxSelectTool())
output_file("gmap_plot.html")
show(plot)
I read that sometimes this happens because the API key is not correct - or even entered - mine is definitely correct so I am not sure what I am doing wrong?
Enabled Google APIs:
This is almost definitively an issue with gmaps' API key. It would be useful to follow the error message's advice and check the javascript console for errors. You would know immediately then what the problem is.
I couldn't get the code snippets from the docs working, for any version from 0.12.14-0.12.16... Anyway. I got the below working:
import pandas as pd
import os
os.chdir(r'PATH')
file = 'FILE_NAME.csv'
df = pd.read_csv(file, skipinitialspace=True)
group = df[["ColA", "ColB", "ColC", "ColD"]]
my_source = ColumnDataSource(group)
#my_source.column_names
from bokeh.plotting import figure, output_file, show, gmap
from bokeh.models import GMapOptions, ColumnDataSource
import numpy as np
lat_lims = df.Latitude
#lat_lims
lon_lims = df.Longitude
#lon_lims
map_options = GMapOptions(lat=np.mean(lat_lims), lng=np.mean(lon_lims), zoom=6)
p = gmap(MY_API_KEY, map_options)
p.circle("Longitude",
"Latitude",
source=my_source,
size=5)
show(p)
I had similar problem. There are at least 15 API for google MAP.
This issue can be resolved by activating
Maps JavaScript API
Google

Resources