I am trying to implement a flot line graph, I am able to display the graph without issue but when I try to change the xaxis so that it is represented by divisions of 1 nothing happens. Nothing I am doing has any effect on it. ie if I give it a minimum number of ticks etc the xaxis remains exactly the same. Could someone tell me where I am going wrong, have I not included an appropriate js file or is it in my code for setting up the xaxis. This chart will eventually be sales figures for a month, so I want to be able to show what they were each day.
The code I have is as follows:
<script src="<?php echo base_url('assets/js/admin/jquery.flot.js') ?>"></script>
<script src="<?php echo base_url('assets/js/admin/jquery.flot.canvas.js') ?>"></script>
<script src="<?php echo base_url('assets/js/admin/jquery.flot.time.js') ?>"></script>
30
<script type="text/javascript">
$(function() {
var d2 = [[1, 445.50], [2, 660.00], [3, 240.00], [4, 302.00], [5, 601.45], [6, 705.34], [7, 550.05], [8, 450.00], [9, 302.00], [10, 601.45], [11, 302.00], [12, 450.00], [13, 1300.00], [14, 601.45], [15, 302.00], [16, 450.00], [17, 450.00], [18, 340.00], [19, 630.00], [20, 450.00], [21, 302.00], [22, 550.00], [23, 440.00], [24, 100.00], [25, 230.00], [26, 200.00], [27, 302.00], [28, 450.00], [29, 430.00], [30, 230.00]];
$.plot("#placeholder", [{
color: '#F6772F',
data: d2,
yaxis: {},
xaxis: {ticks: 30}
}]);
});
</script>
You're mixing up the options with the data. The plot function is called like this:
$.plot(placeholder, series_array, options_object);
In your case you are placing the xaxis options within your series object; it should be in the plot options instead.
Related
mat = [[0, 1, 2, 3, 4, 5],
[6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]]
Lets say I want to extract upper left 2x2 matrix
[[0, 1,],
[6, 7, ]]
doing mat2=mat[:2][:2] doesnt work.
It extracts the rows correctly but not columns.Seems like I need to loop throughto get the columns.
Additionally I need to do a deepcopy to mat2 suchthat modifying mat2 dont change mat.
This is because [:2] returns a list containing the first 2 elements of your matrix.
For example :-
arr = [[1, 2], [1, 3]]
print(arr[:2]) # will print the first 2 elements of the array, that is [1, 2] and [1, 3], packed into a list. So, Output : [[1, 2], [1, 3]].
In the same way,
mat = [[0, 1, 2, 3, 4, 5],
[6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]]
mat2 = mat[:2] # => [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
# Now, if you again try to get the first 2 elements from mat2 you will get the first 2 elements of mat2, not the first 2 elements of the lists inside mat2.
mat3 = mat2[:2] # => [[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]
That is where you went wrong, but this concept is quite counter-intuitive, so no worries.
So the solution would be to get the first 2 elements from matrix mat and then loop over its elements and then get the first 2 elements from them.
Therefore, this should work for you:
list(x[:2] for x in mat[:2])
Or, as #warped pointed, if you can use numpy, you can do the following:
import numpy as np
mat = np.array(mat)
mat[:2, :2]
This question already has answers here:
Access n-th dimension in python [duplicate]
(5 answers)
Closed 2 years ago.
How can I simplify this:
import numpy as np
ex = np.arange(27).reshape(3, 3, 3)
def get_plane(axe, index):
return ex.swapaxes(axe, 0)[index] # is there a better way ?
I cannot find a numpy function to get a plane in a higher dimensional array, is there one?
EDIT
The ex.take(index, axis=axe) method is great, but it copies the array instead of giving a view, what I originally wanted.
So what is the shortest way to index (without copying) a n-th dimensional array to get a 2d slice of it, with index and axis?
Inspired by this answer, you can do something like this:
def get_plane(axe, index):
slices = [slice(None)]*len(ex.shape)
slices[axe]=index
return ex[tuple(slices)]
get_plane(1,1)
output:
array([[ 3, 4, 5],
[12, 13, 14],
[21, 22, 23]])
What do you mean by a 'plane'?
In [16]: ex = np.arange(27).reshape(3, 3, 3)
Names like plane, row, and column, are arbitrary conventions, not formally defined in numpy. The default display of this array looks like 3 'planes' or 'blocks', each with rows and columns:
In [17]: ex
Out[17]:
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
Standard indexing lets us view any 2d block, in any dimension:
In [18]: ex[0]
Out[18]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [19]: ex[0,:,:]
Out[19]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [20]: ex[:,0,:]
Out[20]:
array([[ 0, 1, 2],
[ 9, 10, 11],
[18, 19, 20]])
In [21]: ex[:,:,0]
Out[21]:
array([[ 0, 3, 6],
[ 9, 12, 15],
[18, 21, 24]])
There are ways of saying I want block 0 in dimension 1 etc, but first make sure you understand this indexing. This is the core numpy functionality.
In [23]: np.take(ex, 0, 1)
Out[23]:
array([[ 0, 1, 2],
[ 9, 10, 11],
[18, 19, 20]])
In [24]: idx = (slice(None), 0, slice(None)) # also np.s_[:,0,:]
In [25]: ex[idx]
Out[25]:
array([[ 0, 1, 2],
[ 9, 10, 11],
[18, 19, 20]])
And yes you can swap axes (or transpose), it that suits your needs.
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>
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/
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
}