Python: draw multiple positive/negative Bar Charts by conditions
This is my first time drawing bar charts in python.
My df op:
key descript score
0 noodles taste 5
1 noodles color -2
2 noodles health 3
3 apple color 7
4 apple hard 9
My code:
import matplotlib.pyplot as plt
op['positive'] = op['score'] > 0
op['score'].plot(kind='barh', color=op.positive.map({True: 'r', False: 'k'}), use_index=True)
plt.show()
plt.savefig('sample1.png')
Output:
But this is not what I expected. I would like to draw two charts by different keys in this case with index and maybe use different colors like below:
How can I accomplish this?
python matplotlib bar-chart
add a comment |
This is my first time drawing bar charts in python.
My df op:
key descript score
0 noodles taste 5
1 noodles color -2
2 noodles health 3
3 apple color 7
4 apple hard 9
My code:
import matplotlib.pyplot as plt
op['positive'] = op['score'] > 0
op['score'].plot(kind='barh', color=op.positive.map({True: 'r', False: 'k'}), use_index=True)
plt.show()
plt.savefig('sample1.png')
Output:
But this is not what I expected. I would like to draw two charts by different keys in this case with index and maybe use different colors like below:
How can I accomplish this?
python matplotlib bar-chart
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52
add a comment |
This is my first time drawing bar charts in python.
My df op:
key descript score
0 noodles taste 5
1 noodles color -2
2 noodles health 3
3 apple color 7
4 apple hard 9
My code:
import matplotlib.pyplot as plt
op['positive'] = op['score'] > 0
op['score'].plot(kind='barh', color=op.positive.map({True: 'r', False: 'k'}), use_index=True)
plt.show()
plt.savefig('sample1.png')
Output:
But this is not what I expected. I would like to draw two charts by different keys in this case with index and maybe use different colors like below:
How can I accomplish this?
python matplotlib bar-chart
This is my first time drawing bar charts in python.
My df op:
key descript score
0 noodles taste 5
1 noodles color -2
2 noodles health 3
3 apple color 7
4 apple hard 9
My code:
import matplotlib.pyplot as plt
op['positive'] = op['score'] > 0
op['score'].plot(kind='barh', color=op.positive.map({True: 'r', False: 'k'}), use_index=True)
plt.show()
plt.savefig('sample1.png')
Output:
But this is not what I expected. I would like to draw two charts by different keys in this case with index and maybe use different colors like below:
How can I accomplish this?
python matplotlib bar-chart
python matplotlib bar-chart
edited Jan 2 at 5:59
tripleee
94.2k13133186
94.2k13133186
asked Jan 2 at 2:47
cherrytree1cherrytree1
184
184
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52
add a comment |
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52
add a comment |
1 Answer
1
active
oldest
votes
Try:
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
i += 1
Output:
Update added moving of labels for yaxis - Thanks to this SO solution by @ ImportanceOfBeingErnest
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
plt.setp(ax[i].get_yticklabels(), transform=ax[i].get_yaxis_transform())
i += 1
Output:
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end useplt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000676%2fpython-draw-multiple-positive-negative-bar-charts-by-conditions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try:
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
i += 1
Output:
Update added moving of labels for yaxis - Thanks to this SO solution by @ ImportanceOfBeingErnest
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
plt.setp(ax[i].get_yticklabels(), transform=ax[i].get_yaxis_transform())
i += 1
Output:
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end useplt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
|
show 2 more comments
Try:
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
i += 1
Output:
Update added moving of labels for yaxis - Thanks to this SO solution by @ ImportanceOfBeingErnest
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
plt.setp(ax[i].get_yticklabels(), transform=ax[i].get_yaxis_transform())
i += 1
Output:
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end useplt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
|
show 2 more comments
Try:
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
i += 1
Output:
Update added moving of labels for yaxis - Thanks to this SO solution by @ ImportanceOfBeingErnest
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
plt.setp(ax[i].get_yticklabels(), transform=ax[i].get_yaxis_transform())
i += 1
Output:
Try:
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
i += 1
Output:
Update added moving of labels for yaxis - Thanks to this SO solution by @ ImportanceOfBeingErnest
fig, ax = plt.subplots(1,op.key.nunique(), figsize=(15,5), sharex=True)
i = 0
#Fix some data issues/typos
op['key']=op.key.str.replace('noodels','noodles')
for n, g in op.assign(positive=op['score'] >= 0).groupby('key'):
g.plot.barh(y='score', x='descript', ax=ax[i], color=g['positive'].map({True:'red',False:'blue'}), legend=False)
.set_xlabel(n)
ax[i].set_ylabel('Score')
ax[i].spines['top'].set_visible(False)
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].spines['left'].set_position('zero')
plt.setp(ax[i].get_yticklabels(), transform=ax[i].get_yaxis_transform())
i += 1
Output:
edited Jan 2 at 14:46
answered Jan 2 at 3:13
Scott BostonScott Boston
56.7k73158
56.7k73158
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end useplt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
|
show 2 more comments
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end useplt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
Try to find a way to move those yaxis tick lables over so that you don't have 'Score' and 'color' in the bar. I'll take another look at this tomorrow. Maybe one of the matplotlib wizards here can modify and move that text over.
– Scott Boston
Jan 2 at 5:59
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
It's very neat! Thank you :) It's not necessary to have yaxis tick lables, so I just hide it. I have one question, when I tried to draw the bar charts, I actually have more than 100 unique keys. I change subplots from (1,op.key.nunique()) to (op.key.nunique(),1) and change the figsize but the charts is pretty messy since they are too small and stick together. How do I solve this? I just want every picture as big as yours.
– cherrytree1
Jan 2 at 7:12
1
1
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end use
plt.tight_layout()
– Scott Boston
Jan 2 at 14:02
@cherrytree1 You are going to have to adjust the size of your figure to fit 100 images vertically. Your fig size is the total size of the chart which includes all 100 of your subplots. I you try figsize=(15, 500) at the end use
plt.tight_layout()
– Scott Boston
Jan 2 at 14:02
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
Sorry for bothering again. When I tried the code today, not sure why it cannot display the color properly. It shows all red when I tried it today.
– cherrytree1
Jan 7 at 3:39
1
1
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
Upgrade matplotlib, and pandas
– Scott Boston
Jan 8 at 5:37
|
show 2 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000676%2fpython-draw-multiple-positive-negative-bar-charts-by-conditions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Typo in data? "noodels" vs "noodles"?
– Scott Boston
Jan 2 at 5:50
@ScottBoston yeah, it's a typo :)
– cherrytree1
Jan 2 at 5:52