how to use seaborn objects scale with two visualisations with same kwargs? - seaborn

I'm trying to create bar plot with labels on bars. Position of labels and color of labels depends on column of dataframe. Also, I would like to color bars by column.
My data:
data = {
'Survived': ['0', '1'],
'count': [500, 100],
'label_position': ['R', 'L']
}
df = pd.DataFrame(data)
I tried to create following plot:
import seaborn.objects as so
p = (
so.Plot(df, x='count', y='Survived')
.add(so.Bar(alpha=1), color='Survived')
.add(
so.Text({"fontweight": "bold"}),
text='count',
halign='label_position',
color="label_position"
)
.scale(
halign={'L':'left', 'R':'right'},
color={'L':'black', 'R':'white'}
)
)
p.plot()
but this code raises following error:
PlotSpecError: Scale setup failed for the `color` variable. See the traceback above for more information.
because both visualizations have attribute color.
I'm able co color bars, or the text, but not both at once.
Colored bars:
color the bars
Colored text:
color the text
Is there any posibility to color both?

If we see the traceback above for more information as the exception message suggests, it says
ValueError: No entry in color dictionary for '0', '1'
So we could try adding entries for those keys:
(
so.Plot(df, x='count', y='Survived')
.add(so.Bar(alpha=1), color='Survived')
.add(
so.Text({"fontweight": "bold"}),
text='count',
halign='label_position',
color="label_position",
)
.scale(
halign={'L':'left', 'R':'right'},
color={'L':'black', 'R':'white', '0': 'black', '1': 'white'}, # <-----
)
)
That works but now we have some entries in the legend that we probably don't want. There's not in general a way to control what shows up in the legend independently of what actually gets mapped for Nominal scales, but for this particular plot the color encoding is redundant anyway so we don't actually need the legend:
(
so.Plot(df, x='count', y='Survived')
.add(so.Bar(alpha=1), color='Survived', legend=False) # <-----
.add(
so.Text({"fontweight": "bold"}),
text='count',
halign='label_position',
color="label_position",
)
.scale(
halign={'L':'left', 'R':'right'},
color={'L':'black', 'R':'white', '0': 'black', '1': 'white'},
)
)

Related

ChartJS line chart calls plugin each time I hover a point

I am using ChartJS v2.9.3.
I am trying to add to the time line chart a conditional vertical background color that is displayed depending on if dataset's y-value is above a threshold.
The thread Background colour of line charts in chart.js gave me the idea to use the following plugin
const backgroundPlugin = {
beforeDatasetDraw(chart, easing) {
const ctx = chart.chart.ctx;
const chartArea = chart.chartArea;
ctx.save();
const colors = [
'red',
'green',
'yellow',
'blue'
];
const randomNumber = Math.floor(Math.random() * colors.length);
// Set random background color to show how many times this function is called
ctx.fillStyle = colors[randomNumber];
console.log('refreshing background');
chart.getDatasetMeta(0).data.forEach((data, index, all) => {
// Check if value > threshold (here 350)
if (
chart.config.data.datasets[0].data[index].y > 350
) {
const nextPointX =
index === all.length - 1 ?
chartArea.left :
all[index + 1]._model.x;
// Create vertical rectangle of color between current point and next point
ctx.fillRect(
nextPointX,
chartArea.top,
Math.abs(all[index]._model.x - nextPointX),
chartArea.bottom - chartArea.top
);
}
});
ctx.restore();
}
};
The problem I observed is that every time I hover on one point of the line chart, the plugin's beforeDatasetDraw function gets called a huge number of time.
The problem can be seen on this JSFiddle : https://jsfiddle.net/avocado1/hgpukame/88/#
This is a problem for me because in my real case that causes a performance issue (I work with a more than 20.000 points datasets and I would like to have 5 different background colors depending on 5 different thresholds, meaning there could be 5 comparisons for each point of my dataset).
Would anyone have any clue on how to prevent hovering events to cause calls to my plugin ? (Or have any workaround to create a conditional background once and for all ?)

Amcharts custom variable color

I want a dynamic color on my chart. I use a imported css file with some identity colors.
Like this:
:root
{
--brand-color: {{$color}};
}
I am using the AmChart World chart as visualisation but the a4mchart.color() does not like variables. How do I make sure that it does take in variables? here my code:
let style = getComputedStyle(document.body);
let brandColor = style.getPropertyValue('--brand-color');
const chartWorld = am4core.create(this.$refs.chartdiv, am4maps.MapChart);
polygonSeries.fill = am4core.color(brandColor);
And this is what it returns:
Color {_value: {
alpha: 1
alternative: Color
darkColor: Color
hex: "#000000"
lightColor: Color
rgb: Object
rgba: "rgb(0,0,0)"
_value: {r: 0, g: 0, b: 0, a: 1}
__proto__: Object…}}
It didn't change anything but the BrandColor does return the right string when I log it: "#A4A2A3"
Please help
From my testing, getPropertyValue returns everything after the property name, including any whitespace, which causes the color to not get parsed correctly by AmCharts; your log is likely returning " #A4A2A3". You'll want to call trim on the string beforehand:
polygonSeries.mapPolygons.template.fill = am4core.color(brandColor.trim());
Note that you need to set the fill on the series' mapPolygon template for it to apply to your map regions.

Getting custom colors and thresholds to work with D3 RelationshipGraph

Based on this example:
https://cdn.rawgit.com/hkelly93/d3-relationshipGraph/master/examples/index.html
D3 should allow me to create this chart and define colors and thresholds for when values change color. The function accepts some custom settings:
var graph = d3.select('#graph').relationshipGraph({
maxChildCount: 10,
valueKeyName: 'Story title',
thresholds: [6, 8, 10],
colors: ['red', 'yellow', 'green'],
showTooltips: true
})
But I'm not getting a graph with three colors when I load data fitting into all 3 ranges. I want 0-6 to appear red, 7-8 to appear yellow, and 9-10 to appear green. Here's the data loaded (excerpt):
[
{"parent": "2012-October", "organization": "WEWASAFO", "value": 10, "Story title": "NUTRITION"},
{"parent": "2012-April", "organization": "Jitegemee", "value": 5, "Story title": "Life in the street"},
{"parent": "2011-May", "organization": "KENYA YOUTH BUSINESS TRUST (KYBT)", "value": 2, "Story title": "BUSINESS"}
]
Everything else parses correctly, except combining custom colors an custom thresholds on the same chart. Either one alone works, but not both together.
The source repo is here with some docs:
https://github.com/hkelly93/d3-relationshipgraph
From that documentation:
thresholds: [100, 200, 300], // The thresholds for the color changes. If the values are strings, the colors are determined by the value of the child being equal to the threshold. If the thresholds are numbers, the color is determined by the value being less than the threshold.
colors: ['red', 'green', 'blue'], // The custom color set to use for the child blocks. These can be color names, HEX values, or RGBA values.
It doesn't explicitly state that the child colors correspond to the order that the thresholds appear. And all blocks appear red in this example.
I tested the code here: https://jsfiddle.net/cgrx3e9m/
This turned out to be a bug in the module itself. I notified the author and he fixed the way it sorts thresholds so it matches up with corresponding colors now.

Kendo UI Bar Chart Labels Rotation

I have a Kendo UI (Telerik) bar chart with long label names. When I set the label rotation to anything outside of 0,180,90,360 the labels slant but they use the center of the text as the slant point instead of the start of the text. This causes all the labels to be off by a full bar.
http://snag.gy/m2XxJ.jpg
Is there a way to get the chart to use the start of the label as the rotation point instead of the center?
The only way I've gotten the labels to line up properly when using rotation, is to also set the padding.
Sample categoryAxis
categoryAxis: { field: 'name', labels: { rotation: -60, padding: { right: 10 }}}
JSbin sample http://jsbin.com/zoloc/1/edit
Kendo Documentation http://docs.telerik.com/kendo-ui/api/dataviz/chart#configuration-categoryAxis.labels.padding
You can use both rotation and margin to arrange the category axis text like this,
.CategoryAxis(axis => axis
.Categories(model => model.StudentName).Labels(labels => labels.Rotation(330).Margin(-5,45,0,0).Visible(true))
.MajorGridLines(lines => lines.Visible(false))
.Line(line => line.Visible(false))
)
Response from Telerik:
You have a valid point. Excel for example rotates the text around its left edge.
We'll look into this issue, but for the moment I can only suggest the multi-line option in the upcoming Q2 release.
You'll be able to split the labels by using a new-line character:
categories: ["J.R. SIMPLOT\nCOMPANY", ...]

Kendo Categorical chart to display only points with non numeric x-axis

I am using kendo UI dataviz charts to display data that has text(symbols) on x-axis and a numerical value on the y-axis. I have serverside datasource that provides the data. How can I achieve this?
I tried to use Scatter charts but they are XY charts and need numerical values on both x and y axis. I can display the data as a linecharts which are categorical but the line connecting the markers is meaningless in my case and I don't need that displayed.
here's an example of my data
var data = [{id:"1", number:"1.23", label:"A"},{id:"2", number:"4.11", label:"B"}]
You could use simple line chart and set
markers visible
series.opacity to 0
series: [{
field: "value",
type: "line",
opacity: 0,
markers: {
size: 5,
visible: true,
}
}]
http://docs.kendoui.com/api/dataviz/chart#configuration-series.opacity

Resources