Pie Chart with Labels and facet in altair: not able to proper render the value labels - altair

Using the single chart example, I have a label for each piece of cake.
If I try to transform it in a faceted chart using this code
df=pd.read_csv("input.csv",keep_default_na=False)
base=alt.Chart(df).encode(
theta=alt.Theta(field="v", type="quantitative"),
color=alt.Color(field="k", type="nominal")
)
pie = base.mark_arc(outerRadius=100)
text = base.mark_text(radius=115,fill= "black").encode(alt.Text(field="v", type="quantitative", format=",.1f"))
alt.layer(pie, text, data=df).facet(column='label')
all the labels are all in the same wedge and then illegible (here the vega lite version vega lite version).
how to have a result similar to that of the single chart?
Thank you
f,n,k,v,label
1,3,0-5 %,99.7289972899729,Forest
1,4,5-10 %,0.27100271002710025,Forest
0,1,0-5 %,100.0,Non-Forest
254,5,0-5 %,99.0077177508269,unclassifiable
254,6,5-10 %,0.9922822491730982,unclassifiable

I must add:
stack=True as channel encoding option in the theta channel encoding;
and .resolve_scale( theta="independent" ) to the chart.
And it works (I learned this thanks to Mattijn van Hoek).
df=pd.read_csv("input.csv",keep_default_na=False)
base=alt.Chart(df).encode(
theta=alt.Theta(field="v", type="quantitative", stack=True),
color=alt.Color(field="k", type="nominal")
)
pie = base.mark_arc(outerRadius=100)
text = base.mark_text(radius=115,fill= "black").encode(alt.Text(field="v", type="quantitative", format=",.1f"))
alt.layer(pie, text, data=df).facet(column='label').resolve_scale(theta="independent")

Related

How to map discrete colours in a Plotly Sunburst chart in r

I am very new to using plotly in rstudio and have come up against a problem with mapping discrete colours (stored as hex codes in the field color) to each of the slices in my ids field.
I have included my code below:
df %>%
plot_ly(
color = I("black"),
marker = list(colors = ~color)) %>%
add_trace(ids = df$ids,
labels = df$labels,
parents = df$parents,
type = 'sunburst',
maxdepth = -1,
domain = list(column = 0)) %>%
layout(sunburstcolorway = df$color)
This is the resulting sunburst diagram I get using this code, which is obviously not ideal:
Ideally the first four levels would have the same colour, and then different hex colour codes are used for slices that are labelled "Poor","Moderate","GwC" or "Good".
A csv file of my data frame used above is available here.
I finally managed to nut out how to map my colour field to the background colours on the sunburst chart - have updated the code in original post. All that was required was to insert the following code segment:
plot_ly(
marker = list(colors = ~color))
Below is the output chart:

How to add text on interactive Scatter on Altair?

I try to adapt the Selection Detail Example from altair doc (https://altair-viz.github.io/gallery/select_detail.html#selection-detail-example).
I won't detailed my Dataframe structure which is identical with the one from the example (included variable names).
The native code is working well :
# Data is prepared, now make a chart
selector = alt.selection_single(empty='all', fields=['id'])
base = alt.Chart(data).properties(
width=250,
height=250
).add_selection(selector)
points = base.mark_point(filled=True, size=200,opacity=0.9).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='Taux de marge (%PM)'),
color=alt.condition(selector, 'id:O', alt.value('lightgray')),
tooltip = ['mean(y)','mean(x)']
)
timeseries = base.mark_bar(opacity=1).encode(
x=alt.X('time', title='Items'),
y=alt.Y('value', scale=alt.Scale(domain=(-1, 1)),stack=None),
color=alt.Color('id:O',scale=alt.Scale(domain=domain, range=range_))
#, legend=None)
).transform_filter(
selector
)
points | timeseries
No problem at this stage even if it could be useful to hide all the bars on right chart when no selection is made on the right chart (don't know if it's possible ?)
After that I try to add text to the scatter plot adding this at the end of the code :
text = points.mark_text(dy=-5).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='NBV (%CA)'),
text='id:O'
)
(points + text) | timeseries
which leads to the following error message :
Javascript Error: Duplicate signal name: "selector094_tuple"
This usually means there's a typo in your chart specification. See the javascript console for the full traceback.
If you have any idea on how to do, i would be grateful
Thanks
The issue is that you cannot add the same selection to two different layers, which you do implicitly by deriving text from points. Try this instead:
text = alt.Chart(data).mark_text(dy=-5).encode(
x=alt.X('mean(y)',title='Durée de perception',scale=alt.Scale(domain=(11, 23))),
y=alt.Y('mean(x)',title='NBV (%CA)'),
text='id:O'
)
(points + text) | timeseries

Having both X and Y axes' Scales in Altair respond to a selection interval

I'm bringing this question from Altair's github. (https://github.com/altair-viz/altair/issues/2456) Is there a way to get the Scale on Y-axis in the bottom chart to respond to the selection brush? I'd like to be able to pan around the top chart with a selection and see the zoomed-in results in the bottom chart. If I uncomment the alt.Y, then both the X and Y axes show Years and it's messed up. Is there a way to pass just an X or Y value in the 'brush' maybe? Thank you very much!
brush = alt.selection_interval(init={'x':[1950, 1970], 'y':[1500000, 2500000]}, encodings=['x', 'y'])
base = alt.Chart().mark_line().encode(
x=alt.X('Year:Q', title=None),
y='Deaths:Q',
color='Entity:N'
)
alt.vconcat(
base.add_selection(brush).encode().properties(height=150, width=150),
base.encode(
alt.X('Year:Q', scale=alt.Scale(domain=brush)),
#alt.Y('Deaths:Q', scale=alt.Scale(domain=brush)) # (un)commenting this line makes it work/fail only along the x-axis
).properties(
height=500, width=500
),
data='https://vega.github.io/vega-datasets/data/disasters.csv'
)
Yes, see Open the Chart in the Vega Editor
It filters the data of the 2nd chart using a filter transform on the brush param.

Binding mark_geoshape rotate property to slider selection

I'm trying to recreate something similar to this vega plot in Altair.
I've had luck building the mark_geoshape maps before when binding to something like color, which can be in encode function, but I cannot for the life of me figure out how to bind the slider to the rotate property of the chart, which lives in project.
I presumed I could do something like this, but no luck:
import altair as alt
from vega_datasets import data
# Data generators for the background
sphere = alt.sphere()
graticule = alt.graticule()
# Source of land data
source = alt.topo_feature(data.world_110m.url, 'countries')
slider = alt.binding_range(min=0, max=100, step=1, name='rotate:')
selector = alt.selection_single(name="SelectorName", fields=['rotate'],
bind=slider, init={'rotate': 180})
# Layering and configuring the components
alt.layer(
alt.Chart(sphere).mark_geoshape(),
alt.Chart(graticule).mark_geoshape(stroke='white', strokeWidth=0.5),
alt.Chart(source).mark_geoshape(fill='ForestGreen', stroke='black')
).project(
'orthographic',
).encode(
rotate=['rotate',180,180]
).properties(width=600, height=400, selection=selector).configure_view(stroke=None)
Any help would be much appreciated.
Thanks
leo
There is currently no way to do this in Altair: the Vega-Lite schema only supports constant rotation values. If you wish, you can do this in Vega; there is an example at https://vega.github.io/vega/docs/projections/.

How to change the color of an individual item of the plot chart in Flex?

I am creating a plot chart in Flex that takes in an array collection. The array collection has the following format:
var provinces:ArrayCollection = new ArrayCollection (
{PROVINCE:"Ha Noi", Male:50000, Female:20000},
{PROVINCE:"Ha Tay", Male:100000, Female:10000},
{PROVINCE:"Quang Ninh", Male:75250, Female:45021},
{PROVINCE:"Hai Phong", Male:10000, Female:25000});
I want to use different colors to display different provinces on the plot chart. Moreover, I want to create a legend for different provinces. Would anyone know how to do it? Some code example would be great.
Thank you.

Resources