Skip to content

Commit 990041a

Browse files
committed
add validations and tests
- add validation functions and tests for annotated_heatmap and tables - add docstrings for all functions - fix annotated_heatmap annotations so the font color logic is followed when a text matrix is supplied.
1 parent 93e334b commit 990041a

File tree

2 files changed

+478
-100
lines changed

2 files changed

+478
-100
lines changed

plotly/tests/test_core/test_tools/test_figure_factory.py

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,305 @@ def test_datetime_candlestick(self):
686686
self.assertEqual(candle, exp_candle)
687687

688688

689+
class TestAnnotatedHeatmap(TestCase):
690+
691+
def test_unequal_z_text_size(self):
692+
693+
# check: PlotlyError if z and text are not the same dimmensions
694+
695+
kwargs = {'z': [[1, 2], [1, 2]], 'text': [[1, 2, 3], [1, 2]]}
696+
self.assertRaises(PlotlyError,
697+
tls.FigureFactory.create_annotated_heatmap,
698+
**kwargs)
699+
700+
kwargs = {'z': [[1, 2], [1, 2]], 'text': [[1, 2], [1, 2], [1, 2]]}
701+
self.assertRaises(PlotlyError,
702+
tls.FigureFactory.create_annotated_heatmap,
703+
**kwargs)
704+
705+
def test_simple_annotated_heatmap(self):
706+
707+
# we should be able to create a heatmap with annotated values with a
708+
# logical text color
709+
710+
z = [[1, 0, .5], [.25, .75, .45]]
711+
a_heat = tls.FigureFactory.create_annotated_heatmap(z)
712+
expected_a_heat = {
713+
'data': [{'showscale': False,
714+
'type': 'heatmap',
715+
'z': [[1, 0, 0.5], [0.25, 0.75, 0.45]]}],
716+
'layout': {'annotations': [{'font': {'color': '#000000'},
717+
'showarrow': False,
718+
'text': '1',
719+
'x': 0,
720+
'xref': 'x1',
721+
'y': 0,
722+
'yref': 'y1'},
723+
{'font': {'color': '#FFFFFF'},
724+
'showarrow': False,
725+
'text': '0',
726+
'x': 1,
727+
'xref': 'x1',
728+
'y': 0,
729+
'yref': 'y1'},
730+
{'font': {'color': '#000000'},
731+
'showarrow': False,
732+
'text': '0.5',
733+
'x': 2,
734+
'xref': 'x1',
735+
'y': 0,
736+
'yref': 'y1'},
737+
{'font': {'color': '#FFFFFF'},
738+
'showarrow': False,
739+
'text': '0.25',
740+
'x': 0,
741+
'xref': 'x1',
742+
'y': 1,
743+
'yref': 'y1'},
744+
{'font': {'color': '#000000'},
745+
'showarrow': False,
746+
'text': '0.75',
747+
'x': 1,
748+
'xref': 'x1',
749+
'y': 1,
750+
'yref': 'y1'},
751+
{'font': {'color': '#000000'},
752+
'showarrow': False,
753+
'text': '0.45',
754+
'x': 2,
755+
'xref': 'x1',
756+
'y': 1,
757+
'yref': 'y1'}],
758+
'xaxis': {'gridcolor': 'rgb(0, 0, 0)',
759+
'showticklabels': False,
760+
'side': 'top',
761+
'ticks': ''},
762+
'yaxis': {'showticklabels': False, 'ticks': '',
763+
'ticksuffix': ' '}}}
764+
self.assertEqual(a_heat, expected_a_heat)
765+
766+
def test_more_kwargs(self):
767+
768+
# we should be able to create an annotated heatmap with x and y axes
769+
# lables, a defined colorscale, and supplied text.
770+
771+
z = [[1, 0], [.25, .75], [.45, .5]]
772+
text = [['first', 'second'], ['third', 'fourth'], ['fifth', 'sixth']]
773+
a = tls.FigureFactory.create_annotated_heatmap(z,
774+
x=['A', 'B'],
775+
y=['One', 'Two',
776+
'Three'],
777+
text=text,
778+
colorscale=[[0,
779+
'#ffffff'],
780+
[1,
781+
'#e6005a']]
782+
)
783+
expected_a = {'data': [{'colorscale': [[0, '#ffffff'], [1, '#e6005a']],
784+
'showscale': False,
785+
'type': 'heatmap',
786+
'x': ['A', 'B'],
787+
'y': ['One', 'Two', 'Three'],
788+
'z': [[1, 0], [0.25, 0.75], [0.45, 0.5]]}],
789+
'layout': {'annotations': [{'font': {'color': '#FFFFFF'},
790+
'showarrow': False,
791+
'text': 'first',
792+
'x': 'A',
793+
'xref': 'x1',
794+
'y': 'One',
795+
'yref': 'y1'},
796+
{'font': {'color': '#000000'},
797+
'showarrow': False,
798+
'text': 'second',
799+
'x': 'B',
800+
'xref': 'x1',
801+
'y': 'One',
802+
'yref': 'y1'},
803+
{'font': {'color': '#000000'},
804+
'showarrow': False,
805+
'text': 'third',
806+
'x': 'A',
807+
'xref': 'x1',
808+
'y': 'Two',
809+
'yref': 'y1'},
810+
{'font': {'color': '#FFFFFF'},
811+
'showarrow': False,
812+
'text': 'fourth',
813+
'x': 'B',
814+
'xref': 'x1',
815+
'y': 'Two',
816+
'yref': 'y1'},
817+
{'font': {'color': '#FFFFFF'},
818+
'showarrow': False,
819+
'text': 'fifth',
820+
'x': 'A',
821+
'xref': 'x1',
822+
'y': 'Three',
823+
'yref': 'y1'},
824+
{'font': {'color': '#FFFFFF'},
825+
'showarrow': False,
826+
'text': 'sixth',
827+
'x': 'B',
828+
'xref': 'x1',
829+
'y': 'Three',
830+
'yref': 'y1'}],
831+
'xaxis': {'gridcolor': 'rgb(0, 0, 0)',
832+
'side': 'top', 'ticks': ''},
833+
'yaxis': {'ticks': '', 'ticksuffix': ' '}}}
834+
self.assertEqual(a, expected_a)
835+
836+
837+
class TestTable(TestCase):
838+
839+
def test_fontcolor_input(self):
840+
841+
# check: PlotlyError if fontcolor input is incorrect
842+
843+
kwargs = {'text': [['one', 'two'], [1, 2], [1, 2], [1, 2]],
844+
'fontcolor': '#000000'}
845+
self.assertRaises(PlotlyError,
846+
tls.FigureFactory.create_table, **kwargs)
847+
848+
kwargs = {'text': [['one', 'two'], [1, 2], [1, 2], [1, 2]],
849+
'fontcolor': ['red', 'blue']}
850+
self.assertRaises(PlotlyError,
851+
tls.FigureFactory.create_table, **kwargs)
852+
853+
def test_simple_table(self):
854+
855+
# we should be able to create a striped table by suppling a text matrix
856+
857+
text = [['Country', 'Year', 'Population'], ['US', 2000, 282200000],
858+
['Canada', 2000, 27790000], ['US', 1980, 226500000]]
859+
table = tls.FigureFactory.create_table(text)
860+
expected_table = {'data': [{'colorscale': [[0, '#66b2ff'], [0.5, '#e6e6e6'], [1, '#ffffff']],
861+
'opacity': 0.7,
862+
'showscale': False,
863+
'type': 'heatmap',
864+
'z': [[0, 0, 0], [0.5, 0.5, 0.5], [1, 1, 1], [0.5, 0.5, 0.5]]}],
865+
'layout': {'annotations': [{'align': 'left',
866+
'font': {'color': '#000000'},
867+
'showarrow': False,
868+
'text': '<b>Country</b>',
869+
'x': -0.45,
870+
'xanchor': 'left',
871+
'xref': 'x1',
872+
'y': 0,
873+
'yref': 'y1'},
874+
{'align': 'left',
875+
'font': {'color': '#000000'},
876+
'showarrow': False,
877+
'text': '<b>Year</b>',
878+
'x': 0.55,
879+
'xanchor': 'left',
880+
'xref': 'x1',
881+
'y': 0,
882+
'yref': 'y1'},
883+
{'align': 'left',
884+
'font': {'color': '#000000'},
885+
'showarrow': False,
886+
'text': '<b>Population</b>',
887+
'x': 1.55,
888+
'xanchor': 'left',
889+
'xref': 'x1',
890+
'y': 0,
891+
'yref': 'y1'},
892+
{'align': 'left',
893+
'font': {'color': '#000000'},
894+
'showarrow': False,
895+
'text': 'US',
896+
'x': -0.45,
897+
'xanchor': 'left',
898+
'xref': 'x1',
899+
'y': 1,
900+
'yref': 'y1'},
901+
{'align': 'left',
902+
'font': {'color': '#000000'},
903+
'showarrow': False,
904+
'text': '2000',
905+
'x': 0.55,
906+
'xanchor': 'left',
907+
'xref': 'x1',
908+
'y': 1,
909+
'yref': 'y1'},
910+
{'align': 'left',
911+
'font': {'color': '#000000'},
912+
'showarrow': False,
913+
'text': '282200000',
914+
'x': 1.55,
915+
'xanchor': 'left',
916+
'xref': 'x1',
917+
'y': 1,
918+
'yref': 'y1'},
919+
{'align': 'left',
920+
'font': {'color': '#000000'},
921+
'showarrow': False,
922+
'text': 'Canada',
923+
'x': -0.45,
924+
'xanchor': 'left',
925+
'xref': 'x1',
926+
'y': 2,
927+
'yref': 'y1'},
928+
{'align': 'left',
929+
'font': {'color': '#000000'},
930+
'showarrow': False,
931+
'text': '2000',
932+
'x': 0.55,
933+
'xanchor': 'left',
934+
'xref': 'x1',
935+
'y': 2,
936+
'yref': 'y1'},
937+
{'align': 'left',
938+
'font': {'color': '#000000'},
939+
'showarrow': False,
940+
'text': '27790000',
941+
'x': 1.55,
942+
'xanchor': 'left',
943+
'xref': 'x1',
944+
'y': 2,
945+
'yref': 'y1'},
946+
{'align': 'left',
947+
'font': {'color': '#000000'},
948+
'showarrow': False,
949+
'text': 'US',
950+
'x': -0.45,
951+
'xanchor': 'left',
952+
'xref': 'x1',
953+
'y': 3,
954+
'yref': 'y1'},
955+
{'align': 'left',
956+
'font': {'color': '#000000'},
957+
'showarrow': False,
958+
'text': '1980',
959+
'x': 0.55,
960+
'xanchor': 'left',
961+
'xref': 'x1',
962+
'y': 3,
963+
'yref': 'y1'},
964+
{'align': 'left',
965+
'font': {'color': '#000000'},
966+
'showarrow': False,
967+
'text': '226500000',
968+
'x': 1.55,
969+
'xanchor': 'left',
970+
'xref': 'x1',
971+
'y': 3,
972+
'yref': 'y1'}],
973+
'height': 320,
974+
'xaxis': {'dtick': 1,
975+
'gridwidth': 2,
976+
'showticklabels': False,
977+
'tick0': -0.5,
978+
'ticks': '',
979+
'zeroline': False},
980+
'yaxis': {'autorange': 'reversed',
981+
'dtick': 1,
982+
'gridwidth': 2,
983+
'showticklabels': False,
984+
'tick0': 0.5,
985+
'ticks': '',
986+
'zeroline': False}}}
987+
689988
# class TestDistplot(TestCase):
690989

691990
# def test_scipy_import_error(self):

0 commit comments

Comments
 (0)