I am not able to change the column width in horizontal sns.barplot and make the figure look good - bar-chart

I am trying to generate an horizontal barplot from this dataframe:
Question Answer Value in % postpand
0 a Yes 34.2 postpand
1 a No 65.8 postpand
2 b Positive 32.1 postpand
3 b Negative 65.0 postpand
4 b No Change 2.9 postpand
5 c Yes 70.4 postpand
6 c No 14.5 postpand
7 d Yes 84.2 postpand
8 d No 15.8 postpand
9 e Yes 70.4 postpand
10 e No 29.2 postpand
11 f Yes 49.2 postpand
12 f No 50.4 postpand
(please, disregard de column "postpand")
Now making the figure...
ax = sns.barplot(x="Value in %", y="Question", data=df, hue="Answer")
plt.ylabel("Question and Answer", fontsize=40)
plt.xlabel("Value in %", fontsize=40)
ax.set_xlim (xmax=100)
plt.show()
So for me, there seems to be several things unpleasant about this figure:
First, I would like the bars to be so thick as to occupy the space more fully, and also to be centered with the categories in y-axis.
Second, the legend is hiding the bars.
For the thickness of the bars, I found a code that might be helpful to change their width in the x-axis. I had to "adapt" it to height, since it is horizontal, but I think I got to not give an error jus by pure luck. So now this is the code:
sns.set(font_scale=3, style="whitegrid")
ax = sns.barplot(x="Value in %", y="Question", data=df, hue="Answer")
def change_height(ax, new_value) :
for patch in ax.patches :
current_height = patch.get_height()
diff = current_height - new_value
# we change the bar height
patch.set_height(new_value)
# we recenter the bar
patch.set_y(patch.get_y() + diff * 0.5)
change_height(ax, .35)
plt.ylabel("Question and Answer", fontsize=40)
plt.xlabel("Value in %", fontsize=40)
ax.set_xlim (xmax=100)
plt.show()
However, this is not a nice looking figure either. I have played with several combinations of parametres ("diff * 0.5", and "change_height(ax, .35)") with no better results. Still not occupying the space beautifully and still uncentered...
Anyone could guide me in what I could do?
Many thanks in advance for your help, guys!

Related

altair bar chart text issue

this is my code ...please correct so that label will show correct count.
tool tip is showing correct count.
bars =alt.Chart(r).transform_fold(
['Reservation_count', 'ON_ACCOUNT'],
as_=['column', 'value']
).mark_bar().encode(
x='month:N',
y='value:Q',
color=alt.Color('column:N', scale=alt.Scale(range=["#f50520", "#bab6b7"])),
tooltip=alt.Tooltip(['ON_ACCOUNT','Reservation_count']),
)
text = bars.mark_text(
align='left',
color='black',
baseline='middle',
dx=0,dy=-8 # Nudges text to right so it doesn't appear on top of the bar
).encode(
text=alt.Text('ON_ACCOUNT:Q', format='.0f')
)
rule = alt.Chart(r).mark_rule(color='red').encode(
y='mean(Reservation_count):Q'
)
(bars+text+rule).properties(width=490,height=310)
below is my data:
month ON_ACCOUNT Reservation_count
0 1 22 134
1 2 32 137
2 3 22 135
3 4 21 113
4 5 18 120
5 6 17 90
6 7 26 83
7 8 11 86
8 9 11 102
9 10 2 68
please help me with this altair bar chart..two columns are there Reservation_count and ON_ACCOUNT LABEL IS showing the same number for both ...
Thanks
for example last bar showing 2,2 both labels it should be top 2 and bottom 68
The short version answer to your question is to use text=alt.Text('value:Q', format='.0f').
But there are a few more issues with your code:
You are expanding your text layer from the bar plot, which already has the color parameter set. This will ignore the color setting of the text layer.
You can use a data encoding free from any color specification. You can then use this encoding to build your bar and text layers with their color settings.
I encountered the text ordering issue discussed here, and none of the given solutions worked out. However, changing the plot from vertical bar to horizontal bars seem to resolve the issue. This is potentially a bug.
Since you are plotting the mean of Reservation_count parameter on a stacked plot, the information might be misleading. I would suggest a layered bar instead of a stacked one. Surprisingly, this seems to solve the issue of text order.
Here is the code:
base =alt.Chart(r).transform_fold(
['Reservation_count', 'ON_ACCOUNT'],
as_=['column', 'value']
)
bars = base.mark_bar().encode(
x='month:N',
y=alt.X('value:Q', stack=None), # stack =None enables layered bar
color=alt.Color('column:N', scale=alt.Scale(range=["#f50520", "#bab6b7"])),
tooltip=alt.Tooltip(['ON_ACCOUNT','Reservation_count']),
#order=alt.Order('color_Category_sort_index:Q'),
)
text = base.mark_text(
align='center',
color='black',
baseline='middle',
dx=0,dy=-8, # Nudges text to right so it doesn't appear on top of the bar
#order=alt.Order('color_Category_sort_index:Q'),
).encode(
x='month:N',
y='value:Q',
text=alt.Text('value:Q', format='.0f')
)
rule = alt.Chart(r).mark_rule(color='red').encode(
y='mean(Reservation_count):Q'
)
(bars+text+rule).properties(width=490,height=310)

Minimum expected length of a message

A bag contains 16 balls of following colors: 8 red, 4 blue, 2 green, 1 black and 1 white. Anisha picks a ball randomly from the bag and messages Babu its color using a string of zeros and ones. She replaces the ball in the bag and repeats this experiment many times. What is the minimum expected length of the message she has to convey to Babu per experiment?
(a)3/2
(b)log 5
(c)15/8
(d)31/16
(e)2
According to me, since the ball is taken out with replacement. At any time, there are 16 balls of 5 different colors in the bag. To encode 5 colors, ceiling of log5 (base 2) i.e. 3 bits should be needed but the answer given is (15/8). Can someone point out my mistake and provide some hint for the correct solution?
using static huffman compression you can encode the more common colours in fewer bits than the rare colours, that being the case on can expect that common colours will usually be chosen.
eg:
red 1
blue 01
green 001
white 0001
black 0000
on average from 16 draws there will be
8 reds = 8 bits
4 blues = 8 bits
2 greens = 6 bits
1 white = 4 bits
1 black = 4 bits
for a total of 30/16 bits on average
Your answer is right as the maximum value needed for encoding. But consider the following coding scheme 1 - red (1/2 prob), 01 - blue (1/4 prob), 00 - green (1/8 prob), 001 - black (1/16 prob), 000 - white (1/16 prob) multiply message length by probability and you should have 1 + 5/8 ( not 15/8 ... though)

dividing by two in binary numbers

how can I divide a binary number (in 2 complement) by 2 .
I've tried bit shifting but I have a problem with negative odd numbers, how can I solve it?
for example :
(-7/2) 11001/2 => (shifts the number one place to the right) => 11100 (-4)
Can you use after the . ? Like this?
1 0011 . 1000
Part 1 2 3 4
Part 1: Negative number
Part 2: Makes 3
Part 3: Separate by .
part 4: Makes 0.5
The negative part works like:
.1000 = 0.5
.0100 = 0.25
.1100 = 0.75
.0010 = 0.125
So instead of multiply by 2 to shift to left. You can do a divide by 2 to the right. So after the dot /2 and before the dot x2.
Hope you can use this information.

Want secondary Y axis to start with0.8 and end to 1

I want my secondary Y axis to start with 0.8 and end with 1 with an interval of 0.02.
(i.e. 0.8,0.82,0.84,............1).What values I have to set in Secondary Y axis properties??
hey I myself got the answer of these question.. What I have done is.. Interval---> 0.02 Interval Type--->Number Labels Format--->0.00\ I hope this will help others.

How to control a kiwi drive robot?

I'm on the FIRST robotics team at my high school, and we are working on developing a kiwi drive robot, where there are three omni wheels mounted in a equilateral triangle configuration, like this:
The problem is programming the robot to drive the motors such that that the robot moves in the direction of a given joystick input. For example, to move "up", motors 1 and 2 would be powered equally, while motor 3 would be off. The joystick position is given as a vector, and I was thinking that if the motors were expressed as vectors too, vector projection might be what I need. However, I'm not sure if this is right, and if it is, how I would apply it. I also have a feeling that there may be multiple solutions to one joystick position. Any help would be greatly appreciated.
I've built 9 robots during my time at school (1 FIRST, 8 RoboCup). We used the same omnidrive layout as you do. Beta's answer looks correct but add rotation to all wheels afterwards:
W1 = -1/2 X - sqrt(3)/2 Y + R
W2 = -1/2 X + sqrt(3)/2 Y + R
W3 = X + R
[This is Beta's formula with some added Rotation]
You need to think about the available ranges for your motors. I am guessing it can take a PWM signal of +/-255, so either the input or the output has to be adjusted somewhat. (It's not that hard...)
A good paper with details
To answer your specific questions: Vector projection is essentially what you are doing here. You apply it by having a matrix M, your input from the joystick I and your output to the motors O. Thus O = M * I;
M = [(-0.5 -sqrt(3)/2 +1)
(-0.5 +sqrt(3)/2 +1)
(1 0 +1)]
First let's define some terms. In keeping with the usual convention, the X axis will point to the right and the y axis will point up (so that the thrust of wheel 3 is along the X axis). We'll call the motion of the wheels W1, W2 and W3, each defined so that Wi > 0 means that the wheel rotates in the clockwise direction. In your example, if W1 < 0, W2 = W1 and W3 = 0, the robot will move in the +Y direction.
If all three wheels rotated at the same rate (W1 = W2 = W3) the robot would rotate in place. I'm guessing you don't want that, so the sum of the rotations must be zero: W1 + W2 + W3 = 0.
The motion of each wheel contributes to the motion of the robot; they add as vectors:
W1 = -1/2 X - sqrt(3)/2 Y
W2 = -1/2 X + sqrt(3)/2 Y
W3 = X
So if you know the desired X and Y from the joystick, you have W1, W2 and W3. As we've already seen, the difference between W1 and W2 is what drives Y motion. Their sum drives motion in X.
Though this system can be solved mathematically, in 2002, FIRST Team 857 chose to solve it mechanically. Our control system used three joysticks mounted with their X-axes forming an equilateral triangle, and handles replaced with ball-socket arms connected with a Y-shaped yoke. Map the X-axis of each stick directly to a motor speed, and the control system has been solved. As an advantage, this system is very intuitive for laypeople to run--push the yoke in the direction you want to go, rotate it to turn.
As you have recognized, the first part of this will be finding an appropriate equation to represent the resultant motion for any motor settings. Depending on the level of control and feedback you have on your motor speeds, I would suggest the process you go thorough should start with writing a vector equation: (define positive X as straight ahead)
-M1Cos(30)+M2Cos(30)=X (the negative is because 1 and 2 must be powered the same magnitude, but opposite polarities for forward motion)
M1Sin(30)+M2Sin(30)-M3 = Y (as anticlockwise motion on 1 and 2 will result in the robot moving left in the Y and anticlockwise motion on 3 will result in the robot moving to the right)
The other input that you need to add into this is the desired rotation of the robot, thankfully, M1+M2+M3 = W (Rotational velocity)
Your joystick input will give you X,Y and W, so you have 3 equations with 3 unknowns.
From here it is simultaneous equations, so you may end up with multiple solutions, but these can generally be restricted based on possible motor speeds and the like.
An example of this is the rec::robotino::com::OmniDrive Class - the source code for this method is available too...