Bokeh - Stacked and grouped charts - bar-chart

Is it possible to create a plot in bokeh that is both stacked and grouped? Kinda like http://www.highcharts.com/demo/column-stacked-and-grouped/.
The dataset is something like this
count date class user
39 2016/12/28 4 user1
26 2016/12/28 4 user2
3 2016/12/28 4 user2
8 2016/12/28 4 user1
1 2016/12/28 4 user1
22 2016/12/28 4 user1
26 2016/12/28 4 user2
1 2016/12/28 4 user1
7 2016/12/28 4 user2
12 2016/12/28 4 user3
23 2016/12/28 4 user3
31 2016/12/28 4 user3
2 2016/12/31 4 user1
1 2016/12/31 4 user2
27 2016/12/31 4 user2
What I want to do is visualize the counts by stacking across class and grouping across user with the label for x-axis being the dates.

Yes you can. Assuming you have your data in a pandas dataframe (df).
Here is an example in the bokeh documentation:
Grouping Bar plots
from bokeh.charts import Bar, output_file, show
p = Bar(df, label='date', values='count', stack='class', group='user',
)
output_file("bar.html")
show(p)

I know I'm late, but the example under stacking and grouping in the following article from the official bokeh documentation covers this:
https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html

Related

MYSQL I am trying to return a value where I need to compare one value against the minimum value for the same field when grouped against another field

Basically I am trying to calculate shots received in golf for various four balls, here is my data:-
DatePlayed PlayerID HCap Groups Hole01 Hole02 Hole03 Shots
----------------------------------------------------------------------
2018-11-10 001 15 2 7 3 6
2018-11-10 004 20 1 7 4 6
2018-11-10 025 20 2 7 4 5
2018-11-10 047 17 1 8 3 6
2018-11-10 048 20 2 8 4 6
2018-11-10 056 17 1 6 3 5
2018-11-10 087 18 1 7 3 5
I want to retrieve the above lines with an additional column which is to be calculated depending on the value in the group column, which is the players (Handicap - (the lowest handicap in the group)) x .75
I can achieve it in a group by but need to aggregate everything, is there a way I can return the value as above?, here is query that returns the value:
SELECT
PlayerID,
MIN(Handicap),
MIN(Hole01) AS Hole01,
MIN(Hole02) AS Hole02,
MIN(Hole03) AS Hole03,
MIN(CourseID) AS CourseID,
Groups,
ROUND(
MIN((Handicap -
(SELECT MIN(Handicap) FROM Results AS t
WHERE DatePlayed='2018-11-10 00:00:00' AND t.Groups=Results.Groups)) *.75))
AS Shots
FROM
Results
WHERE
Results.DatePlayed='2018=11=10 00:00:00'
GROUP BY
DatePlayed, Groups, PlayerID
.
PlayerID MIN(Handicap)Hole01 Hole02 Hole03 CourseID Groups Shots
-----------------------------------------------------------------
4 20 7 4 6 1 1 2
47 17 8 3 6 1 1 0
56 17 6 3 5 1 1 0
87 18 7 3 5 1 1 1
1 15 7 3 6 1 2 0
25 20 7 4 5 1 2 4
48 20 8 4 6 1 2 4
Sorry about any formatting really couldn't see how to get my table in here, any help will be much appreciated, I am using the latest mysql from ubuntu 18.04
Not an answer; too long for a comment...
First off, I happily know nothing about golf, so what follows might not be optimal, but it must, at least, be a step in the right direction...
A normalized schema might look something like this...
rounds
round_id DatePlayed PlayerID HCap Groups
1 2018-11-10 1 15 2
2 2018-11-10 4 20 1
round_detail
round_id hole shots
1 1 7
1 2 3
1 3 6
2 1 7
2 2 4
2 3 6
Hi Guys I have found the solution, basically I need to drop the MIN immediately after the ROUND of the equation and therefore it does not need a Group By.
SELECT
PlayerID,
Handicap,
Hole01,
Hole02,
Hole03,
CourseID,
Groups,
ROUND((Handicap -
(SELECT MIN(Handicap) FROM Results AS t
WHERE DatePlayed='2018-11-10 00:00:00'
AND t.Groups=Results.Groups))
*.75) AS Shots
FROM
Results
WHERE
Results.DatePlayed='2018=11=10 00:00:00'

SQL Find All user that have two history in a certain order

I'm looking for a SQL request that I can't find in internet (and I didn't found a solution myself).
I have two different table user and history and a table user_history that link the two tables.
For example :
USER
id name
1 John
2 Edie
3 France
4 Gabriel
5 Ellen
History
id date_entered type
1 2017-07-01 36
2 2017-07-02 52
3 2017-07-03 25
4 2017-07-04 69
5 2017-07-05 85
6 2017-07-06 74
7 2017-07-07 45
8 2017-07-08 85
9 2017-07-09 25
10 2017-07-10 78
USER_HISTORY
id id_user id_history
1 1 1
2 1 2
3 1 3
4 1 4
5 2 5
6 2 6
7 1 7
8 1 8
9 2 9
10 1 10
In this example, all history are made by user 1 and 2 (user 2 have history 5,6 and 9).
So the question is :
What is the SQL request that get me all the users that have in their history an history type 25 and then some days LATER an history type 85 ?
In this example, only user 1 (John) is ok because he has a history type 25 on 2017-07-03 and then an history type 85 on 2017-07-08.
User 2 (Edie) is not ok because even if he has an history 25 and 85, the first one was 85 and the 25.
Is that clear ?
Can you help me please ?
You need to JOIN twice with HISTORY table, e.g.:
SELECT h1.id_user
FROM (
SELECT u.id_user, h.date_entered
FROM user_history u
JOIN history h ON u.id_history = h.id
WHERE h.type = 25) h1
JOIN (
SELECT u.id_user, h.date_entered
FROM user_history u
JOIN history h ON u.id_history = h.id
WHERE h.type = 85
) h2 ON h1.id_user = h2.id_user
WHERE h1.date_entered < h2.date_entered;
Here's the SQL Fiddle.

Concat results by days ranges

I have an apartment table:
Id: name:
1 apartment1
2 apartment2
3 apartment3
3 apartment4
And an availabilities table:
Id apartment_id availability_date remaning_number_places
1 1 01/02/2017 3
2 1 02/02/2017 2
3 1 03/02/2017 2
4 1 04/02/2017 2
5 2 01/02/2017 2
6 2 03/02/2017 2
7 2 04/02/2017 2
8 3 12/02/2017 2
9 3 03/02/2017 1
10 3 04/02/2017 1
11 4 12/02/2017 2
12 4 02/02/2017 2
I would like to do a search by starting and ending date with a minimum number of places, for example if I search from 01/02/2017 to 04/02/2017 I should have this result:
Apartment_ids availabilities starting_date ending_date nbr_places
[1] [1,2,3,4] 01/02/2017 04/02/2017 2
[2,4] [5,6,7,12] 01/02/2017 04/02/2017 2
The result must be a concatenation of contiguous days corresponding to given dates.
Thank you at advance.
EDIT : Trying to give more details hereunder:
I need an SQL query to look for an apartment availability for a given period.
As a result, if an apartment is available for the whole period I'm expecting to get it. In addition, I also need to get if more than one apartment are required to cover this given period. In that case, I'm expecting a contiguous list of apartments as a result.
Please, can someone help me build this query?

MySQL query - need assistance creating this query

I need some direction on how to create this MySQL query.
I have a table that looks like this.
id group name value
1 1 user mike
2 1 setting 1
3 2 user joe
4 2 setting 2
5 3 user jill
6 3 setting 1
7 4 user mark
8 4 setting 1
9 4 other 22
I would like to format the query to group users that have identical settings (IE mike and jill would be grouped in this example, not mark because of "other")
At the end of the day I am trying to consolidate and make the table look like this. If I can figure out the query to properly group them ,I will use PHP to combine the values and save it back to the DB.
id group name value
1 1 user mike OR jill
2 1 setting 1
3 2 user joe
4 2 setting 2
7 4 user mark
8 4 setting 1
9 4 other 22
Thank you!

How to select more rows with MySQL after sorting?

I have a table which have 10 results. Let's say the following:
id user number
-- ---- ------
1 user1 10
2 user2 5
3 user3 30
4 user4 45
5 user5 5
6 user6 22
7 user7 10
8 user8 40
9 user9 90
10 user10 65
I basically want to sort them, by the 'number' value.
So it should be something like this:
SORT id user number
---- -- ---- ------
1 2 user2 5
2 5 user5 5
3 1 user1 10
4 7 user7 10
5 6 user6 22
6 3 user3 30
7 8 user8 40
8 4 user4 45
9 10 user10 65
10 9 user9 90
After it's been sorted, I want to select * from (for example) the one with id = 6 (which's number is 22) and 2 other results which is above it (in this case: id = 7 and 1) and 2 other results under it (in this case: id = 3 and 8).
So the return result should be something like this, when I'm searching for id = 6:
SORT id user number
---- -- ---- ------
3 1 user1 10
4 7 user7 10
5 6 user6 22
6 3 user3 30
7 8 user8 40
I could esaily do this on server side, if I select everything, however there will be a huge data amount in here, so I'd rather just select those, which are appropriate to my search.
Is there any way to do this with MySQL?
Here is a typical way to get what you want:
select t.*
from ((select t.*
from table t
where number <= (select number where id = 6 limit 1)
order by number desc
limit 3
) union all
(select t.*
from table t
where id > (select number where id = 6 limit 1)
order by number asc
limit 2
)
) t
order by number;
This assumes that when duplicates appear, you still want 5 rows output. It also assumes that less than five rows is ok for the first two or last two rows. An index on id would help performance of this query.
Get UNION of 2 queries:
Get all records <= the desired number, in your case 22. Sort them in descending order and get top 3 results.
Get all records > the desired number in ascending order and get top 2 results
Get the UNION of these 2 results and order them in ascending order
HTH
EDIT: My idea to post this answer was to give an algorithm on how to approach such queries. Instead of selecting on number, you can get all records based on id and then UNION them.