Python: draw multiple positive/negative Bar Charts by conditions












3















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:



Bar Chart



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:



expected Bar Chart



How can I accomplish this?










share|improve this question

























  • 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
















3















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:



Bar Chart



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:



expected Bar Chart



How can I accomplish this?










share|improve this question

























  • 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














3












3








3


1






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:



Bar Chart



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:



expected Bar Chart



How can I accomplish this?










share|improve this question
















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:



Bar Chart



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:



expected Bar Chart



How can I accomplish this?







python matplotlib bar-chart






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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



















  • 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












1 Answer
1






active

oldest

votes


















2














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:



enter image description here



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:



enter image description here






share|improve this answer


























  • 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 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






  • 1





    Upgrade matplotlib, and pandas

    – Scott Boston
    Jan 8 at 5:37











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
});


}
});














draft saved

draft discarded


















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









2














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:



enter image description here



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:



enter image description here






share|improve this answer


























  • 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 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






  • 1





    Upgrade matplotlib, and pandas

    – Scott Boston
    Jan 8 at 5:37
















2














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:



enter image description here



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:



enter image description here






share|improve this answer


























  • 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 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






  • 1





    Upgrade matplotlib, and pandas

    – Scott Boston
    Jan 8 at 5:37














2












2








2







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:



enter image description here



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:



enter image description here






share|improve this answer















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:



enter image description here



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:



enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








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 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






  • 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











  • 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 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






  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$