minValue and maxValue as Time Range in hAxis in Google Chart - datetime

I need to set time range for my hAxis to have minValue of 09:00 and maxValue 17:00 with increment of 1 hour (i.e. 9, 10, 11, 12, 13, 14, ... , 17)
Currently my data is formatted as H:m (for example: 09:35, 10:20)
var formatter3 = new google.visualization.DateFormat({pattern: 'H:m'});
formatter3.format(data,0);
And below are my options:
var options = {
curveType: "function",
title : '',
hAxis:{slantedTextAngle: 90,textStyle:{fontSize:8}},
colors : ['red','#3366CC', '#999999'],
vAxes: {
0: {logScale: false, format:'0.0000'},
1: {logScale: false}
},
hAxis: {
format: 'H:m',
minValue: new Date(null, null, null, 9, 0, 0),
maxValue: new Date(null, null, null, 17, 0, 0),
viewWindow:{min: new Date(null, null, null, 9, 0, 0),
max: new Date(null, null, null, 17, 0, 0)},
series: {
0: {targetAxisIndex:0, type: "line"},
1: {targetAxisIndex:0, type: "line"},
2: {targetAxisIndex:1, type: "bars"}
}
};
However , it is still not working. Please advise. Thanks!

Unfortunately, the minValue, maxValue, and baseline value are ignored for date and time values. I am not sure that this is a recent bug but I just noticed it a week ago. You might try to experiment with the viewWindow min and max, and the gridlines.count option to get the desired result. Or you might be able to convert all your date values to strings, if the values are evenly spaced, in which case axes will use your explicit values.
Another new feature that could work for you is that you can provide an explicit array of tick values, with a ticks: [...] option. In the current release of gviz, the formatting is done using your format option, and that should be enough for your needs. In an upcoming release, you can also specify the formatting of each tick value.
So it might be best to specify the times in your example using timeofday values like so:
hAxis: {
ticks: [[9, 0, 0], [10, 0, 0], [11, 0, 0], [12, 0, 0], ...]
}
I think you could do the same kind of thing with datetime values instead, if that's what your data values are.

Related

dealing with lists and arrays when using toJson function - in R

I am working with a pre-specified API definition, which I need to adhere to:
"myTable": {
"split": [
{
"total": 0,
"perItem": [
0,
0,
0
]
}
]
the results from my function are a list (since I am using an apply):
Export
[[1]]
[[1]]$total
[1] 13
[[1]]$perItem
1 2 3
5 7 0
but when I convert this to .json, it is not the same format as the predefined API definition:
toJSON(Export)
[{"total":[13],"perPlan":[5,7,0]}]
I was wondering how I can convert the output of the apply to have the predefined API?
I tried converting this to array:
toJSON(array(Export), simplify = TRUE)
[{"total":[13],"perPlan":[5,7,0]}]
but this still has the additional [] around the content of total.
According to the API specification your input should also "embed" your data into this split and mytable list, which can be done with:
Export <- list(list(total = 13,
perItem = c(5, 7, 0)))
for_JSON <- list(mytable = list(split = Export))
toJSON(for_JSON, simplify = TRUE, pretty = TRUE)
which gives:
{
"mytable": {
"split": [
{
"total": 13,
"perItem": [5, 7, 0]
}
]
}
}
This looks like what the API wants.

Use xarray open_mfdataset on files with no time dimension included

I have a list of NetCDF files that I would like to open with the xarray.open_mfdataset function.
This would normally be trivial, however I am running into an issue because the files I cam trying to open do not have any "time" dimension included in them:
data
Out[51]:
<xarray.Dataset>
Dimensions: (lat: 850, lon: 1500)
Coordinates:
* lat (lat) float64 54.98 54.94 54.9 54.86 ... 21.14 21.1 21.06 21.02
* lon (lon) float64 -126.0 -125.9 -125.9 -125.9 ... -66.1 -66.06 -66.02
Data variables:
Data (lat, lon) float32 ...
When I try to open my list of files with open_mfdataset, I of course get an error:
xr.open_mfdataset(files)
ValueError: Could not find any dimension coordinates to use to order the datasets for concatenation
I however do have a list of dates corresponding to each file:
dates
Out[54]:
array([datetime.datetime(2009, 1, 1, 0, 0),
datetime.datetime(2009, 1, 2, 0, 0),
datetime.datetime(2009, 1, 3, 0, 0), ...,
datetime.datetime(2019, 12, 29, 0, 0),
datetime.datetime(2019, 12, 30, 0, 0),
datetime.datetime(2019, 12, 31, 0, 0)], dtype=object)
I assume there is some way I add a time dimension to each file and open them all with open_mfdataset, possibly with the "preprocess" argument.
Thanks for any help.
Here is my solution:
Create a function which adds a time dimension to a DataArray, and fill it with a arbitrary date:
def add_time_dim(xda):
xda = xda.expand_dims(time = [datetime.now()])
return xda
Then, pass this function to the preprocess argument when running the open_mfdataset functions:
data = xr.open_mfdataset(files, preprocess = add_time_dim)
Finally, fill the time dimension with my dates:
data['time'] = dates

How to create custom hover tool with value mapping

I am trying to create a custom hover tool using which takes the y-value of the plot and maps the value to different value.
The code I could come up with so far to achieve this functionality is
from bokeh.models import HoverTool
import holoviews as hv
df = pd.DataFrame(
{
"zero": [0, 0, 0, 0, 0, 0, 0],
"one": [1, 1, 1, 1, 1, 1, 1],
"two": [2, 2, 2, 2, 2, 2, 2],
}
)
mapping = {i: c for i, c in enumerate(df.columns)}
def col_mapping(num):
return mapping[int(num)]
hover = HoverTool(tooltips=[("x", "$x"), ("y", "$y")])
img = hv.Image((df.index, np.arange(df.shape[1]), df.T)).opts(tools=[hover])
img
x and y will be float values. So the idea is to map the y coordinates to its corresponding value in the mapping dictionary
Let me know how I can get a new value in the hover tool so that when the value is b/w 0 and 1 it will be
Thanks
Here's how I'd do it:
code = f"return ({json.dumps(mapping)})[Math.floor(special_vars.y)];"
hover = HoverTool(tooltips=[("x", "$x"), ("y", "$y"), ('mapped_y', '$y{0}')],
formatters={'$y': CustomJSHover(code=code)})
If you need a some more complicated code than that of col_mapping, then you'd have to use a ColumnDataSource and just add to it the fully transformed column.

gdi, get width of asian characters

int dx[8];
int fit;
SIZE the_size;
res = GetTextExtentExPointW(dc, L"WWWWWWWW", 8, -1, &fit, &dx[0], &the_size);
This works, dx is filled with numbers 7 14 21 etc. But when I try to do the same for asian characters, like L"薔薇薔薇薔薇薔薇", this function fails. I even created a font for this, it doesn't change anything.
HFONT hFont = CreateFont(14,
0,
0,
0,
FW_DONTCARE,
FALSE, //fdwItalic
FALSE, //fdwUnderline
FALSE, //fdwStrikeOut
SHIFTJIS_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
NONANTIALIASED_QUALITY,
VARIABLE_PITCH,
TEXT("MS PGothic"));
if (hFont == NULL) FUCK();
SelectObject(dc, hFont);
The forth parameter should be the maximum width allowed, not -1. Use a large value instead. Check to make sure GetTextExtentExPointW succeeded.
if(GetTextExtentExPointW(dc, L"薔薇薔薇薔薇薔薇", 8, 1000, &fit, &dx[0], &the_size))
{
...
}
Note that a Unicode code point may require 4 bytes, or 2 wchar_t for each code point.

Iterating Through a Dictionary in Swift

I am a little confused on the answer that Xcode is giving me to this experiment in the Swift Programming Language Guide:
// Use a for-in to iterate through a dictionary (experiment)
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
I understand that as the dictionary is being transversed, the largest number is being set to the variable, largest. However, I am confused as to why Xcode is saying that largest is being set 5 times, or 1 time, or 3 times, depending on each test.
When looking through the code, I see that it should be set 6 times in "Prime" alone (2, 3, 5, 7, 11, 13). Then it should skip over any numbers in "Fibonacci" since those are all less than the largest, which is currently set to 13 from "Prime". Then, it should be set to 16, and finally 25 in "Square", yielding a total of 8 times.
Am I missing something entirely obvious?
Dictionaries in Swift (and other languages) are not ordered. When you iterate through the dictionary, there's no guarantee that the order will match the initialization order. In this example, Swift processes the "Square" key before the others. You can see this by adding a print statement to the loop. 25 is the 5th element of Square so largest would be set 5 times for the 5 elements in Square and then would stay at 25.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25]
]
var largest = 0
for (kind, numbers) in interestingNumbers {
println("kind: \(kind)")
for number in numbers {
if number > largest {
largest = number
}
}
}
largest
This prints:
kind: Square
kind: Prime
kind: Fibonacci
let dict : [String : Any] = ["FirstName" : "Maninder" , "LastName" : "Singh" , "Address" : "Chandigarh"]
dict.forEach { print($0) }
Result would be
("FirstName", "Maninder")
("LastName", "Singh")
("Address", "Chandigarh")
This is a user-defined function to iterate through a dictionary:
func findDic(dict: [String: String]) {
for (key, value) in dict {
print("\(key) : \(value)")
}
}
findDic(dict: ["Animal": "Lion", "Bird": "Sparrow"])
// prints…
// Animal : Lion
// Bird : Sparrow
If you want to iterate over all the values:
dict.values.forEach { value in
// print(value)
}
Here is an alternative for that experiment (Swift 3.0). This tells you exactly which kind of number was the largest.
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var whichKind: String? = nil
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
whichKind = kind
largest = number
}
}
}
print(whichKind)
print(largest)
OUTPUT:
Optional("Square")
25
You can also use values.makeIterator() to iterate over dict values, like this:
for sb in sbItems.values.makeIterator(){
// do something with your sb item..
print(sb)
}
You can also do the iteration like this, in a more swifty style:
sbItems.values.makeIterator().forEach{
// $0 is your dict value..
print($0)
}
sbItems is dict of type [String : NSManagedObject]

Resources