Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make violin plots more robust to empty array inputs. #348

Merged
merged 1 commit into from Jan 12, 2021
Merged

Make violin plots more robust to empty array inputs. #348

merged 1 commit into from Jan 12, 2021

Conversation

JS3xton
Copy link
Contributor

@JS3xton JS3xton commented Nov 19, 2020

Make violin plots more robust to empty array inputs.

  • _plot_single_violin() was modified to handle empty violin_data inputs.
  • The logic in the plot violin functions that understands the data input was made more flexible to detect and correctly label empty lists.
  • Calculation of the default axes limits was updated to tolerate empty lists.

All unit tests pass in Python 3.8 + Anaconda 2020.07 and Python 2.7 + Anaconda 5.2.0.

Test scripts, detailed below, also now run without error and produce the expected outputs in Python 3.8 + Anaconda 2020.07 and Python 2.7 + Anaconda 5.2.0. (Some tests already ran successfully before, as noted in the scripts.) Test scripts previously used to test other violin plot functionality also still produce expected outputs.

test_plot_violin_empty_lists.py

import FlowCal
import numpy as np
import matplotlib.pyplot as plt

###
# 1D arrays
###
plt.figure()
FlowCal.plot.violin(data=np.random.random((9,)),  # <-- worked previously
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[[],[],[]],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=np.empty(shape=(0,)),
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.empty(shape=(0,))],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,))],  # <-- worked previously
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.empty(shape=(0,)),
                          np.random.random((9,)),
                          np.random.random((9,))],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[[],
                          np.random.random((9,)),
                          np.random.random((9,))],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,)),
                          np.random.random((9,)),
                          np.empty(shape=(0,))],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,)),
                          np.random.random((9,)),
                          []],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,)),  # <-- worked previously
                          np.random.random((9,)),
                          np.random.random((9,))],
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[[],
                          np.random.random((9,)),
                          np.random.random((9,))],
                    positions=[0,1,2],
                    xscale='log',
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,)),
                          [],
                          np.random.random((9,))],
                    positions=[0,1,2],
                    xscale='log',
                    yscale='linear')

###
# ND arrays
###
plt.figure()
FlowCal.plot.violin(data=np.random.random((9,3)),  # <-- worked previously
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=np.empty(shape=(0,3)),
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.empty(shape=(0,3))],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,3))],  # <-- worked previously
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.empty(shape=(0,3)),
                          np.random.random((9,3)),
                          np.random.random((9,3))],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[[],
                          np.random.random((9,3)),
                          np.random.random((9,3))],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,3)),
                          np.random.random((9,3)),
                          np.empty(shape=(0,3))],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,3)),
                          np.random.random((9,3)),
                          []],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,3)),  # <-- worked previously
                          np.random.random((9,3)),
                          np.random.random((9,3))],
                    channel=0,
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[[],
                          np.random.random((9,3)),
                          np.random.random((9,3))],
                    channel=0,
                    positions=[0,1,2],
                    xscale='log',
                    yscale='linear')
plt.figure()
FlowCal.plot.violin(data=[np.random.random((9,3)),
                          [],
                          np.random.random((9,3))],
                    channel=0,
                    positions=[0,1,2],
                    xscale='log',
                    yscale='linear')

plt.show()

test_plot_violin_dose_response_empty_lists_1D.py

import FlowCal
import numpy as np
import matplotlib.pyplot as plt

###
# 1D arrays
###
plt.figure()
FlowCal.plot.violin_dose_response(data=np.random.random((9,)),  # <-- worked previously
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],[],[]],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=np.empty(shape=(0,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.empty(shape=(0,))],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,))],  # <-- worked previously
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.empty(shape=(0,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.empty(shape=(0,))],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        []],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),  # <-- worked previously
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  positions=[0,1,2],
                                  xscale='log',
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        [],
                                        np.random.random((9,))],
                                  positions=[0,1,2],
                                  xscale='log',
                                  yscale='linear')
# test min and max
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),  # <-- worked previously
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  min_data=np.random.random((9,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  min_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  min_data=np.empty(shape=(0,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),  # <-- worked previously
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  max_data=np.random.random((9,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  max_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  max_data=np.empty(shape=(0,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),  # <-- worked previously
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  min_data=np.random.random((9,)),
                                  max_data=np.random.random((9,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  min_data=[],
                                  max_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,)),  # <-- worked previously
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  positions=[0,1,2],
                                  xscale='log',
                                  min_data=np.random.random((9,)),
                                  max_data=np.random.random((9,)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,)),
                                        np.random.random((9,))],
                                  positions=[0,1,2],
                                  xscale='log',
                                  min_data=[],
                                  max_data=[],
                                  yscale='linear')

plt.show()

test_plot_violin_dose_response_empty_lists_ND.py

import FlowCal
import numpy as np
import matplotlib.pyplot as plt

###
# ND arrays
###
plt.figure()
FlowCal.plot.violin_dose_response(data=np.random.random((9,3)),  # <-- worked previously
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=np.empty(shape=(0,3)),
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.empty(shape=(0,3))],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3))],  # <-- worked previously
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.empty(shape=(0,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.empty(shape=(0,3))],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        []],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),  # <-- worked previously
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  positions=[0,1,2],
                                  xscale='log',
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        [],
                                        np.random.random((9,3))],
                                  channel=0,
                                  positions=[0,1,2],
                                  xscale='log',
                                  yscale='linear')

# test min and max
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),  # <-- worked previously
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  min_data=np.random.random((9,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  min_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  min_data=np.empty(shape=(0,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),  # <-- worked previously
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  max_data=np.random.random((9,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  max_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  max_data=np.empty(shape=(0,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),  # <-- worked previously
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  min_data=np.random.random((9,3)),
                                  max_data=np.random.random((9,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  min_data=[],
                                  max_data=[],
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[np.random.random((9,3)),  # <-- worked previously
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  positions=[0,1,2],
                                  xscale='log',
                                  min_data=np.random.random((9,3)),
                                  max_data=np.random.random((9,3)),
                                  yscale='linear')
plt.figure()
FlowCal.plot.violin_dose_response(data=[[],
                                        np.random.random((9,3)),
                                        np.random.random((9,3))],
                                  channel=0,
                                  positions=[0,1,2],
                                  xscale='log',
                                  min_data=[],
                                  max_data=[],
                                  yscale='linear')

plt.show()

@JS3xton
Copy link
Contributor Author

JS3xton commented Nov 19, 2020

Fixes #342 and #343.

@JS3xton JS3xton merged commit 804c675 into taborlab:develop Jan 12, 2021
@JS3xton JS3xton deleted the violin-robust-empty-lists branch January 12, 2021 01:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant