Show 5 days along x axis with panning - flot

I'm trying to show only 5 points along the x axis, with panning enabled - I want the user to pan through the other points beyond 5.
I have disabled the zoom, but my problem seems to be that the more data I add, the points along the x axis starts to try and increase.
So if I load 20 points worth of data, instead of showing the 5 points which the user then should simply pan to the other 15, the x axis "zooms out" to show as many points as possible.
also, How do I set the start position? In that if there are 20 points, and only points are showing, how do I set the view to start at point 10 to 15, so the user pans back to the first 10 points, and pans forward for the remaining 5?

Use these options for your x axis:
xaxis: {
panRange: [0, 20],
min: 5,
max: 10
}
panRange defines the borders of the range to pan and min & max define the start range.
Edit: You can specify an array with ticknames:
var ticks = [
[1, 'one'],
[2, 'two'],
and use it like this:
xaxis: {
...
ticks: ticks,
See the code snippet below for a full example:
$(function() {
var data = [
[1, 2],
[2, 3],
[3, 1],
[4, 4],
[5, 2],
[6, 3],
[7, 3],
[8, 2],
[9, 1],
[10, 1],
[11, 3],
[12, 4],
[13, 2],
[14, 2],
[15, 4],
[16, 3],
[17, 3],
[18, 1],
[19, 4]
];
var ticks = [
[1, 'one'],
[2, 'two'],
[3, 'three'],
[4, 'four'],
[5, 'five'],
[6, 'six'],
[7, 'seven'],
[8, 'eight'],
[9, 'nine'],
[10, 'ten'],
[11, 'eleven'],
[12, 'twelve'],
[13, 'thirteen'],
[14, 'fourteen'],
[15, 'fifteen'],
[16, 'sixteen'],
[17, 'seventeen'],
[18, 'eighteen'],
[19, 'nineteen']
];
var options = {
series: {
points: {
show: true
},
lines: {
show: true
}
},
xaxis: {
panRange: [0, 20],
min: 5,
max: 10,
ticks: ticks,
tickDecimals: 0
},
yaxis: {
panRange: [0, 5],
min: 0,
max: 5,
tickDecimals: 0
},
zoom: {
interactive: false
},
pan: {
interactive: true
}
};
var plot = $.plot('#placeholder', [data], options);
});
#placeholder {
width: 400px;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.flotcharts.org/flot/jquery.flot.js"></script>
<script src="http://www.flotcharts.org/flot/jquery.flot.navigate.js"></script>
<div id="placeholder"></div>

Related

How to update a dictionary with different list elements in Python

I want to create a dictionary with the following structure:
{"filename_1.wav": {
"name": "sp1",
"embedding": [0, 1, 2, 3]
},
"filename_2.wav": {
"name": "sp2",
"embedding": [4, 5, 6, 7]
},
"filename_3.wav": {
"name": "sp3",
"embedding": [8, 9, 10, 11]
},
}
The keys name and embedding in the inner dictionary stay the same whereas their values change according to the filename.
This is my code so far:
outer_dict = {}
inner_dict = {}
audio_filenames = ['filename_1.wav', 'filename_2.wav', 'filename_3.wav']
embeddings = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
speaker_ids = ['sp1', 'sp2', 'sp3']
for audio in audio_filenames:
outer_dict[audio] = inner_dict
for e in embeddings:
for s in speaker_ids:
inner_dict['name'] = s
inner_dict['embedding'] = e
print(dict(outer_dict))
My output looks like this:
{'filename_1.wav': {
'name': 'sp3',
'embedding': [8, 9, 10, 11]},
'filename_2.wav': {
'name': 'sp3',
'embedding': [8, 9, 10, 11]},
'filename_3.wav': {
'name': 'sp3',
'embedding': [8, 9, 10, 11]}
}
As you can see, only the audio filenames are updated correctly, whereas from the speaker id and the embeddings lists only the last element is taken.
Can anyone please give me a hint regarding how I can update the speaker ids and the embeddings as well?
Thank you!
There are several issues here.
You are currently overwriting the same inner dictionary, and all outer_dictvalues are pointing to the same inner_dict object. You need to create a new inner_dict object for each entry in the outer dictionary.
Also, you do not want to use a nested for loop to assign the embeddings and speaker ids.
Instead, try assigning each key and its inner dictionary's values one-by-one. Here's an example:
outer_dict = {}
audio_filenames = ['filename_1.wav', 'filename_2.wav', 'filename_3.wav']
embeddings = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
speaker_ids = ['sp1', 'sp2', 'sp3']
for i in range(len(audio_filenames)):
inner_dict = {}
inner_dict['name'] = speaker_ids[i]
inner_dict['embedding'] = embeddings[i]
outer_dict[audio_filenames[i]] = inner_dict
print(outer_dict)
Using a comprehension-list expresion. If the three lists have the same length, then you can use this answer.
response_dict = {audio_filenames[index]: {'embedding': embeddings[index], 'name': speaker_ids[index]} for index, _ in enumerate(audio_filenames)}
print(response_dict)
Output:
{'filename_1.wav': {'embedding': [0, 1, 2, 3], 'name': 'sp1'},
'filename_2.wav': {'embedding': [4, 5, 6, 7], 'name': 'sp2'},
'filename_3.wav': {'embedding': [8, 9, 10, 11], 'name': 'sp3'}}
audio_filenames = ['filename_1.wav', 'filename_2.wav', 'filename_3.wav']
embeddings = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
speaker_ids = ['sp1', 'sp2', 'sp3']
Dict = {}
for a,b,c in zip(speaker_ids, embeddings, audio_filenames):
# print(a,b,c)
Dict[c] = {}
Dict[c]['name'] = a
Dict[c]['embedding'] = b
print Dict

How to find a column in a ndarray

Say i have a array
x = array([[ 0, 1, 2, 5],
[ 3, 4, 5, 5],
[ 6, 7, 8, 5],
[ 9, 10, 11, 5]])
I need to find the position/index of [3, 4, 5, 5]. In this case, it should return 1.
Create an array y that has all rows equal to the one you are looking for. Then, do an elementwise comparison x == y and find the rows where you get all True.
import numpy as np
x1 = np.array([[0, 1, 2, 5], [3, 4, 5, 5],
[6, 7, 8, 5], [9, 10, 11, 5]])
y1 = np.array([[3, 4, 5, 5]] * 4)
print(np.where(np.all(x1 == y1, axis=1))[0]) # => [1]
This approach returns an array of the indices where the desired row appears.
y2 = np.array([[1, 1, 1, 1]] * 4)
print(np.where(np.all(x1 == y2, axis=1))[0]) # => []
x2 = np.array([[3, 4, 5, 5], [3, 4, 5, 5],
[6, 7, 8, 5], [9, 10, 11, 5]])
print(np.where(np.all(x2 == y1, axis=1))[0]) # => [0 1]

How do I calculate all pairs of vector differences in numpy?

I know I can do np.subtract.outer(x, x). If x has shape (n,), then I end up with an array with shape (n, n). However, I have an x with shape (n, 3). I want to output something with shape (n, n, 3). How do I do this? Maybe np.einsum?
You can use broadcasting after extending the dimensions with None/np.newaxis to form a 3D array version of x and subtracting the original 2D array version from it, like so -
x[:, np.newaxis, :] - x
Sample run -
In [6]: x
Out[6]:
array([[6, 5, 3],
[4, 3, 5],
[0, 6, 7],
[8, 4, 1]])
In [7]: x[:,None,:] - x
Out[7]:
array([[[ 0, 0, 0],
[ 2, 2, -2],
[ 6, -1, -4],
[-2, 1, 2]],
[[-2, -2, 2],
[ 0, 0, 0],
[ 4, -3, -2],
[-4, -1, 4]],
[[-6, 1, 4],
[-4, 3, 2],
[ 0, 0, 0],
[-8, 2, 6]],
[[ 2, -1, -2],
[ 4, 1, -4],
[ 8, -2, -6],
[ 0, 0, 0]]])

Getting an unknown parse error with flot

Can someone please point out what I'm missing here? I'm trying to generate a flot chart with the following function (which is called on success of the $.getJSON function in the page). At the moment, the chart is not loading at all and I get a parse error. If I removed this function, the parse error disappears, so I'm sure it's this function causing the problem but I can't see where!
function plotLineGraph(theData){
var myData = theData['data'];
var myDates = theData['dates'];
var d1 = [
myData[0], myData[1], myData[2], myData[3], myData[4],
myData[5], myData[6], myData[7], myData[8], myData[9],
myData[10], myData[11], myData[12], myData[13], myData[14],
myData[15], myData[16], myData[17], myData[18], myData[19],
myData[20], myData[21], myData[22], myData[23], myData[24],
myData[25], myData[26], myData[27], myData[28], myData[29]
];
$.plot($("#placeholder"), [
{label: "rating", data: d1}
], {
series: {
lines: { show: true },
points: { show: true }
},
xaxis: {
ticks:[
myDates[0], myDates[1], myDates[2], myDates[3], myDates[4],
myDates[5], myDates[6], myDates[7], myDates[8], myDates[9],
myDates[10], myDates[11], myDates[12], myDates[13], myDates[14],
myDates[15], myDates[16], myDates[17], myDates[18], myDates[19],
myDates[20], myDates[21], myDates[22], myDates[23], myDates[24],
myDates[25], myDates[26], myDates[27], myDates[28], myDates[29]
]
},
yaxis: {
ticks: 5,
min: 0,
max: 5
},
grid: {
backgroundColor: { colors: ["#fff", "#eee"] }
}
});
}
EDIT:
The $.getJSON function returns the following JSON:
{
"data": [[1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], [19, 0], [20, 0], [21, 0], [22, 0], [23, 3], [24, 3], [25, 2], [26, 0], [27, 0], [28, 0], [29, 0], [30, 0]],
"dates": [[1, '10/9'], [2, '11/9'], [3, '12/9'], [4, '13/9'], [5, '14/9'], [6, '15/9'], [7, '16/9'], [8, '17/9'], [9, '18/9'], [10, '19/9'], [11, '20/9'], [12, '21/9'], [13, '22/9'], [14, '23/9'], [15, '24/9'], [16, '25/9'], [17, '26/9'], [18, '27/9'], [19, '28/9'], [20, '29/9'], [21, '30/9'], [22, '1/10'], [23, '2/10'], [24, '3/10'], [25, '4/10'], [26, '5/10'], [27, '6/10'], [28, '7/10'], [29, '8/10'], [30, '9/10']]
}
EDIT 2:
Thanks Brendan. The call is here (it is part of a larger function which uses the same syntax to correctly generate a few other pie charts):
$.getJSON('/last-month-daily-average-for-products/'
+ theProductUuid + '/', plotLineGraph);
As for the disassembling/reassembling of the JSON.... No particular reason, no. All I need to do is get the relevant data from the JSON into the correct parts of the flot function, so feel free to correct anything which is inefficient as well as incorrect!!
There's nothing wrong with any of the code you have provided. It works perfectly.
See it in action here: http://jsfiddle.net/ryleyb/eJ2h8/

Is there a way to add some margin between bars in a flot bar chart?

I've got two bars, one for inbound and one for outbound. They look like this:
Is there a way I could add some margin between them? Right now the values for them is
var d1 = [[0, 1], [3, 7], [6, 12], [9, 17]];
var d2 = [[1, 4], [4, 9], [7, 14], [10, 19]];
and as you could see I'm skipping one for each period, but I would also want some margin between :D
Set the barWidth parameter (in the bars object inside the series object inside the options object) to something less than 1.
bars: {
show: true,
align: "center",
barWidth: 0.8,
fill: true,
horizontal: true
}

Resources