How to force plotly R to plot missing values with category axis - r-plotly

I want to plot a simple bar chart in plotly R and by default it will skip the NA observations. In ggplot we have a parameter to disable the default NA removal, or we can customize the axis limits. However I cannot get it done in plotly.
dt_plot <- data.frame(categories = letters[1:10], values = c(rep(NA_integer_, 3), 1:5, rep(NA_integer_, 2)))
plot_ly(data = dt_plot) %>%
add_bars(x = ~categories, y = ~values)
I want to show the x axis as the consistent letters 1:10, because I'm actually including this plot in a shiny app with dynamic data selection. Some data have values in all x values, some only have values in a subset. I want to keep the plot to be consistent and always show complete x values.
There is a similar question here, but the answer doesn't apply to my case, because I'm using a category type x axis:
https://plot.ly/r/reference/#layout-xaxis
If the axis type is "category", it should be numbers, using the scale where each category is assigned a serial number from zero in the order it appears.
I tried different range combinations but it didn't work. plotly seemed always remove NA observations first.
There is a related issue where Carson Sievert suggested a hack, but it didn't really work me either.
# this do show all the x values but the plot is wrong
layout(xaxis = list(type = "category", tickvals = 1:10/10, ticktext = letters[1:10], range = c(0, 1)))
By inspecting the plot object, it looks like the NA data is removed before constructing the plot:
{
"visdat": {
"7abc7354f619": ["function () ", "plotlyVisDat"]
},
"cur_data": "7abc7354f619",
"attrs": {
"7abc7354f619": {
"alpha_stroke": 1,
"sizes": [10, 100],
"spans": [1, 20],
"x": {},
"y": {},
"type": "bar",
"inherit": true
}
},
"layout": {
"margin": {
"b": 40,
"l": 60,
"t": 25,
"r": 10
},
"xaxis": {
"domain": [0, 1],
"automargin": true,
"range": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
"title": "categories",
"type": "category",
"categoryorder": "array",
"categoryarray": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
},
"yaxis": {
"domain": [0, 1],
"automargin": true,
"title": "values"
},
"hovermode": "closest",
"showlegend": false
},
"source": "A",
"config": {
"showSendToCloud": false
},
"data": [
{
"x": ["d", "e", "f", "g", "h"],
"y": [1, 2, 3, 4, 5],
"type": "bar",
"marker": {
"color": "rgba(31,119,180,1)",
"line": {
"color": "rgba(31,119,180,1)"
}
},
"error_y": {
"color": "rgba(31,119,180,1)"
},
"error_x": {
"color": "rgba(31,119,180,1)"
},
"xaxis": "x",
"yaxis": "y",
"frame": null
}
],
...

There is info in reference: https://plotly.com/r/reference/layout/xaxis/#layout-xaxis-range, but not so obvious.
But first of all: categorical variable needs to be factor.
Second you need to specify range from 0 to number of levels -1. To better looking use +-0.5 on ends
dt_plot <- data.frame(categories = letters[1:10], values = c(rep(NA_integer_, 3), 1:5, rep(NA_integer_, 2)))
dt_plot$categories <- as.factor(dt_plot$categories)
plot_ly(data = dt_plot) %>%
add_bars(x = ~categories, y = ~values)%>%
layout(xaxis = list(range = list(-0.5, 9.5)))

Related

plotly mapbox - create clusters in mapview

I am building Dash App that uses plotly scattermapbox graph object. In the current map view each point is represented as a circle. As a user zooms-in and out, I'd like to cluster the points and create groupings. Here's my code for reference.
import dash
from dash import dcc
import pandas as pd
df = pd.DataFrame({
'x': [1, 2, 3],
'Lat': [37.774322, 37.777035, 37.773033],
'Long': [-122.489761, -122.485555, -122.491220]
})
layout = html.Div(
dcc.Graph(id="map"),
dcc.Input(id="inp")
)
#app.callback(
Output('map','figure'),
Input('inp','value')
)
def fin(val):
# do something
data = []
data.append({
"type": "scattermapbox",
"lat": df["Lat"],
"lon": df["Long"],
"name": "Location",
"showlegend": False,
"hoverinfo": "text",
"mode": "markers",
"clickmode": "event+select",
"customdata": df.loc[:,cd_cols].values,
"marker": {
"symbol": "circle",
"size": 8,
"opacity": 0.7,
"color": "black"
}
}
)
layout = {
"autosize": True,
"hovermode": "closest",
"mapbox": {
"accesstoken": MAPBOX_KEY,
"bearing": 0,
"center": {
"lat": xxx,
"lon": xxx
},
"pitch": 0,
"zoom": zoom,
"style": "satellite-streets",
},
}
return ({'data': data, 'layout': layout})
try using plotly.graph_objects.scattermapbox.Cluster. Hope this helps:
from dash import dcc, html, Dash, Output, Input
import pandas as pd
import plotly.graph_objects as go
app = Dash(__name__)
df = pd.DataFrame({
'x': [1, 2, 3],
'Lat': [37.774322, 37.777035, 37.773033],
'Long': [-122.489761, -122.485555, -122.491220]
})
#app.callback(
Output('map','figure'),
Input('inp','value')
)
def fin(val):
data = []
data.append({
"type": "scattermapbox",
"lat": df["Lat"],
"lon": df["Long"],
"name": "Location",
"showlegend": False,
"hoverinfo": "text",
"mode": "markers",
"clickmode": "event+select",
"customdata": df.loc[:,['Lat', 'Long']].values,
"marker": {
"symbol": "circle",
"size": 8,
"opacity": 0.7,
"color": "black"
},
"cluster": {'maxzoom': 14}
}
)
layout = {
"autosize": True,
"hovermode": "closest",
"mapbox": {
"bearing": 0,
"center": {
"lat": 37.774322,
"lon": -122.489761
},
"pitch": 0,
"zoom": 7,
"style": "open-street-map",
},
}
return ({'data': data, 'layout': layout})
app.layout = html.Div(
[dcc.Graph(id="map"),
dcc.Input(id="inp")]
)
if __name__ == '__main__':
app.run_server(debug=True)
Notice the added cluster parameters I added to data.
p.s - make sure you are using a new version of dash for this to work. I used the latest version - dash-2.7.1.

Mapbox: What color-code does queryRenderedFeatures return? How to convert the values to rgba, hex or hsl?

The example on mapbox.com returns nice information on the hovered feature, also the fill-color https://docs.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/
The fill-color returned looks like this:
"feature": {
"type": "Feature",
"layer": {
"id": "data",
"type": "fill",
"source": "jsx-source-1",
"paint": {
"fill-color": {
"r": 0.6398494117647059,
"g": 0.26332078431372546,
"b": 0.1670227450980392,
"a": 0.7
}
},
"layout": {}
},
"source": "jsx-source-1",
"state": {}
},
The label "r", "g", "b", "a" seems to be rbga color code, but the returned values are not. What is this?
Any idea how to convert this into rgba, hex, hsl?
I figured it out. Multiply the single values by 255 in order to get an rgb code, leave the "a" (alpha) as it is.

Timestamp in my trace event .json file does not match after loading in the chrome://tracing/

From the excerpt of my trace_file.json
[
{
"args": {
"core": 0,
"opKind": "aicconvolutiond32",
"opMemory": "TCM",
"opName": "Conv_323__2_fc__2_tile_0__1",
"opOperand": [
"Conv_323__2_fc__2_tile_0__1_res#ui8",
...
" Conv_323__2_fc__2_tile_0__1_vtcmin8_res#i8"
],
"opResource": "HMX",
"opShape": [
"Dest [1 x 1 x 1 x 5 x 2048]",
...
" Unnamed10 [1 x 5 x 4096]"
]
},
"cat": "Conv_323__2_fc__2_tile_0__1",
"dur": 1.041667,
"name": "Conv_323",
"ph": "X",
"pid": 103,
"tid": 2,
"ts": 617480883719.4166
},
{
"args": {
"core": 0,
"opKind": "aicconvolutiond32",
"opMemory": "TCM",
"opName": "Conv_323__2_fc__2_tile_0__1",
"opOperand": [
"Conv_323__2_fc__2_tile_0__1_res#ui8",
...
" Conv_323__2_fc__2_tile_0__1_vtcmin8_res#i8"
],
"opResource": "HMX",
"opShape": [
"Dest [1 x 1 x 1 x 5 x 2048]",
...
" Unnamed10 [1 x 5 x 4096]"
]
},
"cat": "Conv_323__2_fc__2_tile_0__1",
"dur": 1.041667,
"name": "Conv_323",
"ph": "X",
"pid": 104,
"tid": 2,
"ts": 617480883719.4166
},
{
"args": {
"core": 0,
"opKind": "aicconvolutiond32",
"opMemory": "TCM",
"opName": "Conv_323__2_fc__2_tile_1__1",
"opOperand": [
"Conv_323__2_fc__2_tile_1__1_res#ui8",
...
" Conv_323__2_fc__2_tile_1__1_vtcmin8_res#i8"
],
"opResource": "HMX",
"opShape": [
"Dest [1 x 1 x 1 x 5 x 2048]",
...
" Unnamed10 [1 x 5 x 4096]"
]
},
"cat": "Conv_323__2_fc__2_tile_1__1",
"dur": 0.260417,
"name": "Conv_323",
"ph": "X",
"pid": 103,
"tid": 2,
"ts": 617480883720.7188
},
{
"args": {
"core": 0,
"opKind": "aicconvolutiond32",
"opMemory": "TCM",
"opName": "Conv_323__2_fc__2_tile_1__1",
"opOperand": [
"Conv_323__2_fc__2_tile_1__1_res#ui8",
...
" Conv_323__2_fc__2_tile_1__1_vtcmin8_res#i8"
],
"opResource": "HMX",
"opShape": [
"Dest [1 x 1 x 1 x 5 x 2048]",
...
" Unnamed10 [1 x 5 x 4096]"
]
},
"cat": "Conv_323__2_fc__2_tile_1__1",
"dur": 0.260417,
"name": "Conv_323",
"ph": "X",
"pid": 104,
"tid": 2,
"ts": 617480883720.7188
}
]
Now when I load the same trace file in chrome://tracing/
I see the start time does not coincide with the value of ts in the trace file.
"ts": 617480883719.4166 in .json file and
Start in snapshot is 2,908,417 ns.
???
Can some one help me how chrome tracing is normalizing\factorizing that "ts" value?

Remove empty space from Streamlit Echarts

I am rendering a gauge component in the following way, within my Streamlit app:
option = {
"series": [
{
"type": "gauge",
"startAngle": 180,
"endAngle": 0,
"min": min_range_val,
"max": max_range_val,
"center": ["40%", "40%"],
"splitNumber": 5,
"axisLine": {
"lineStyle": {
"width": 6,
"color": [
[0.25, "#FF403F"],
[0.5, "#ffa500"],
[0.75, "#FDDD60"],
[1, "#64C88A"],
],
}
},
"pointer": {
"icon": "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
"length": "12%",
"width": 30,
"offsetCenter": [0, "-60%"],
"itemStyle": {"color": "auto"},
},
"axisTick": {"length": 10, "lineStyle": {"color": "auto", "width": 2}},
"splitLine": {"length": 15, "lineStyle": {"color": "auto", "width": 5}},
"axisLabel": {
"color": "#464646",
"fontSize": 12,
"distance": -60,
},
"title": {"offsetCenter": [0, "-20%"], "fontSize": 20},
"detail": {
"fontSize": 30,
"offsetCenter": [0, "0%"],
"valueAnimation": True,
"color": "auto",
"formatter": "{value}%",
},
"data": [{"value": value, "name": caption}],
}
]
}
st_echarts(option, width="450px", height="350px", key="gauge")
However, it seems like an additional empty extra white space is added at the bottom of the component (as from the following image).
How can I effectively remove that and keep only a tiny margin all around the gauge?
The following parameters must be added:
radius: '120%',
center: ['50%', '80%']
The latter one should be adjusted according to specific use cases.

How to display correct dates on the X-Axis

tl;dr: when I set the xAxis min and max to, say, 2013-01-01 14:30:00 and 2013-01-01 15:45, I need to see these times on the xAxis and not 14:00 and 15:00, or 01. 01. 2013 and 01. 01. 2013, or whatever automatically generated timestamps that are wrong, like here
I have a question here regarding the Kendo Dataviz Chart. I'm trying to display several scatter line graphs in one chart that depict how some technical indicators change in time. For that I need to display correct date and time to the scale of minuted. And I don't seem to be able to reach this seemingly simple goal, no matter how much I search or try.
Research done so far:
Answer from Telerik did little to help.
All examples and demos use day-granularity at maximum, so no help there.
Here is some example code, that I didn't manage to get advantage of: jsbin.com/AtusAGO/1/edit
The code:
Please try commenting and uncommenting lines 23 to 27 in the JSFiddle to see what happens (mostly nothing, really, and never what I'd like to achieve).
(function () {
$("#chart").kendoChart({
legend: {
visible: true,
position: "bottom"
},
seriesDefaults: {
type: "scatterLine",
markers: {
size: 0
}
},
xAxis: {
"type": "date",
labels: {
format: "hh:mm d. M. yyyy"
},
title: {
text: "Time"
},
min: "2012-02-05 00:35:00",
max: "2012-02-05 01:40:00",
baseUnitStep: "auto",
/*baseUnit: "fit",
maxDateGroups: 10,*/
autoBaseUnitSteps: {
minutes: [5]
}
},
series: [{
"name": "temp",
"yAxis": "temperature",
"data": [
[
"2012-02-05T00:35:00",
3],
[
"2012-02-05T00:55:00",
0],
[
"2012-02-05T01:00:00",
1],
[
"2012-02-05T01:05:00",
2],
[
"2012-02-05T01:10:00",
3],
[
"2012-02-05T01:15:00",
4],
[
"2012-02-05T01:20:00",
5],
[
"2012-02-05T01:40:00",
3]
]
}, {
"name": "hum",
"yAxis": "humidity",
"data": [
[
"2012-02-05T00:00:00",
80],
[
"2012-02-05T00:55:00",
100],
[
"2012-02-05T01:00:00",
10],
[
"2012-02-05T01:05:00",
20],
[
"2012-02-05T01:10:00",
50],
[
"2012-02-05T01:15:00",
40],
[
"2012-02-05T01:20:00",
50],
[
"2012-02-05T01:51:00",
30]
]
}],
yAxes: [{
"name": "humidity",
"title": {
"text": "Humidity [%]"
}
}, {
"name": "temperature",
"title": {
"text": "Temperature [\u00b0C]"
}
}]
});
}());
You can use the following data format:
series:{
data: [
{
date: new Date(2013,0,1,0,0,0),
value: 23
},
{
date: new Date(2013,0,2,0,0,0),
value: 24
}
],
field: "value",
categoryField: "date"
}
And in the labels, you can set it as
template: "#:kendo.toString(value,'dd/MM/yyyy hh:mm:ss')"