def test_wrong_dimensions(): with pytest.raises(ValueError) as err_msg: fig = px.scatter(px.data.tips(), x="tip", y=[1, 2, 3]) assert "All arguments should have the same length." in str( err_msg.value) # the order matters with pytest.raises(ValueError) as err_msg: fig = px.scatter(px.data.tips(), x=[1, 2, 3], y="tip") assert "All arguments should have the same length." in str( err_msg.value) with pytest.raises(ValueError): fig = px.scatter(px.data.tips(), x=px.data.iris().index, y="tip")
def test_multiindex_raise_error(): index = pd.MultiIndex.from_product([[1, 2, 3], ["a", "b"]], names=["first", "second"]) df = pd.DataFrame(np.random.random((6, 3)), index=index, columns=["A", "B", "C"]) # This is ok fig = px.scatter(df, x="A", y="B") with pytest.raises(TypeError) as err_msg: fig = px.scatter(df, x=df.index, y="B") assert "pandas MultiIndex is not supported by plotly express" in str( err_msg.value)
def test_scatter(): iris = px.data.iris() fig = px.scatter(iris, x="sepal_width", y="sepal_length") assert fig.data[0].type == "scatter" assert np.all(fig.data[0].x == iris.sepal_width) assert np.all(fig.data[0].y == iris.sepal_length) # test defaults assert fig.data[0].mode == "markers"
def test_arrayattrable_numpy(): tips = px.data.tips() fig = px.scatter(tips, x="total_bill", y="tip", hover_data=[np.random.random(tips.shape[0])]) assert (fig.data[0]["hovertemplate"] == "total_bill=%{x}<br>tip=%{y}<br>hover_data_0=%{customdata[0]}") tips = px.data.tips() fig = px.scatter( tips, x="total_bill", y="tip", hover_data=[np.random.random(tips.shape[0])], labels={"hover_data_0": "suppl"}, ) assert (fig.data[0]["hovertemplate"] == "total_bill=%{x}<br>tip=%{y}<br>suppl=%{customdata[0]}")
def test_int_col_names(): # DataFrame with int column names lengths = pd.DataFrame(np.random.random(100)) fig = px.histogram(lengths, x=0) assert np.all(np.array(lengths).flatten() == fig.data[0].x) # Numpy array ar = np.arange(100).reshape((10, 10)) fig = px.scatter(ar, x=2, y=8) assert np.all(fig.data[0].x == ar[:, 2])
def test_repeated_name(): iris = px.data.iris() fig = px.scatter( iris, x="sepal_width", y="sepal_length", hover_data=["petal_length", "petal_width", "species_id"], custom_data=["species_id", "species"], ) assert fig.data[0].customdata.shape[1] == 4
def test_arguments_not_modified(): iris = px.data.iris() petal_length = iris.petal_length hover_data = [iris.sepal_length] fig = px.scatter(iris, x=petal_length, y="petal_width", hover_data=hover_data) assert iris.petal_length.equals(petal_length) assert iris.sepal_length.equals(hover_data[0])
def test_with_index(): tips = px.data.tips() fig = px.scatter(tips, x=tips.index, y="total_bill") assert fig.data[0]["hovertemplate"] == "index=%{x}<br>total_bill=%{y}" fig = px.scatter(tips, x=tips.index, y=tips.total_bill) assert fig.data[0]["hovertemplate"] == "index=%{x}<br>total_bill=%{y}" fig = px.scatter(tips, x=tips.index, y=tips.total_bill, labels={"index": "number"}) assert fig.data[0]["hovertemplate"] == "number=%{x}<br>total_bill=%{y}" # We do not allow "x=index" with pytest.raises(ValueError) as err_msg: fig = px.scatter(tips, x="index", y="total_bill") assert "To use the index, pass it in directly as `df.index`." in str( err_msg.value) tips = px.data.tips() tips.index.name = "item" fig = px.scatter(tips, x=tips.index, y="total_bill") assert fig.data[0]["hovertemplate"] == "item=%{x}<br>total_bill=%{y}"
def test_custom_data_scatter(): iris = px.data.iris() # No hover, no custom data fig = px.scatter(iris, x="sepal_width", y="sepal_length", color="species") assert fig.data[0].customdata is None # Hover, no custom data fig = px.scatter( iris, x="sepal_width", y="sepal_length", color="species", hover_data=["petal_length", "petal_width"], ) for data in fig.data: assert np.all(np.in1d(data.customdata[:, 1], iris.petal_width)) # Hover and custom data, no repeated arguments fig = px.scatter( iris, x="sepal_width", y="sepal_length", hover_data=["petal_length", "petal_width"], custom_data=["species_id", "species"], ) assert np.all(fig.data[0].customdata[:, 0] == iris.species_id) assert fig.data[0].customdata.shape[1] == 4 # Hover and custom data, with repeated arguments fig = px.scatter( iris, x="sepal_width", y="sepal_length", hover_data=["petal_length", "petal_width", "species_id"], custom_data=["species_id", "species"], ) assert np.all(fig.data[0].customdata[:, 0] == iris.species_id) assert fig.data[0].customdata.shape[1] == 4 assert ( fig.data[0].hovertemplate == "sepal_width=%{x}<br>sepal_length=%{y}<br>petal_length=%{customdata[2]}<br>petal_width=%{customdata[3]}<br>species_id=%{customdata[0]}" )
def plot_resultatsSummary(self, with_std=False): obj = self.obj if not with_std: e = (obj.resultatsSummary(withStd=F).T.iplot( kind="scatter", mode="markers", asFigure=T).update_config( plotlyServerURL="").update_layout(width=600)) else: g = (obj.resultatsSummary( withStd=T, withStdCol=T).T.rename_axis(index="model").reset_index()) dff = (g.dropCols(["Tr(std)", "Val(std)"]) >> df.gather( "Var", "Values", ["Tr", "Val"])).assign( ci=pd.concat([g.loc[:, "Tr(std)"], g.loc[:, "Val(std)"]], ignore_index=T)) e = (px.scatter(dff, x="model", y="Values", color="Var", error_y="ci")) return e
def test_several_dataframes(): df = pd.DataFrame(dict(x=[0, 1], y=[1, 10], z=[0.1, 0.8])) df2 = pd.DataFrame(dict(time=[23, 26], money=[100, 200])) fig = px.scatter(df, x="z", y=df2.money, size="x") assert fig.data[0].hovertemplate == "z=%{x}<br>y=%{y}<br>x=%{marker.size}" fig = px.scatter(df2, x=df.z, y=df2.money, size=df.z) assert fig.data[ 0].hovertemplate == "x=%{x}<br>money=%{y}<br>size=%{marker.size}" # Name conflict with pytest.raises(NameError) as err_msg: fig = px.scatter(df, x="z", y=df2.money, size="y") assert "A name conflict was encountered for argument y" in str( err_msg.value) with pytest.raises(NameError) as err_msg: fig = px.scatter(df, x="z", y=df2.money, size=df.y) assert "A name conflict was encountered for argument y" in str( err_msg.value) # No conflict when the dataframe is not given, fields are used df = pd.DataFrame(dict(x=[0, 1], y=[3, 4])) df2 = pd.DataFrame(dict(x=[3, 5], y=[23, 24])) fig = px.scatter(x=df.y, y=df2.y) assert np.all(fig.data[0].x == np.array([3, 4])) assert np.all(fig.data[0].y == np.array([23, 24])) assert fig.data[0].hovertemplate == "x=%{x}<br>y=%{y}" df = pd.DataFrame(dict(x=[0, 1], y=[3, 4])) df2 = pd.DataFrame(dict(x=[3, 5], y=[23, 24])) df3 = pd.DataFrame(dict(y=[0.1, 0.2])) fig = px.scatter(x=df.y, y=df2.y, size=df3.y) assert np.all(fig.data[0].x == np.array([3, 4])) assert np.all(fig.data[0].y == np.array([23, 24])) assert fig.data[ 0].hovertemplate == "x=%{x}<br>y=%{y}<br>size=%{marker.size}" df = pd.DataFrame(dict(x=[0, 1], y=[3, 4])) df2 = pd.DataFrame(dict(x=[3, 5], y=[23, 24])) df3 = pd.DataFrame(dict(y=[0.1, 0.2])) fig = px.scatter(x=df.y, y=df2.y, hover_data=[df3.y]) assert np.all(fig.data[0].x == np.array([3, 4])) assert np.all(fig.data[0].y == np.array([23, 24])) assert (fig.data[0].hovertemplate == "x=%{x}<br>y=%{y}<br>hover_data_0=%{customdata[0]}")
def test_px_templates(): import plotly_study.io as pio import plotly_study.graph_objects as go tips = px.data.tips() # use the normal defaults fig = px.scatter() assert fig.layout.template == pio.templates[pio.templates.default] # respect changes to defaults pio.templates.default = "seaborn" fig = px.scatter() assert fig.layout.template == pio.templates["seaborn"] # special px-level defaults over pio defaults pio.templates.default = "seaborn" px.defaults.template = "ggplot2" fig = px.scatter() assert fig.layout.template == pio.templates["ggplot2"] # accept names in args over pio and px defaults fig = px.scatter(template="seaborn") assert fig.layout.template == pio.templates["seaborn"] # accept objects in args fig = px.scatter(template={}) assert fig.layout.template == go.layout.Template(data_scatter=[{}]) # read colorway from the template fig = px.scatter( tips, x="total_bill", y="tip", color="sex", template=dict(layout_colorway=["red", "blue"]), ) assert fig.data[0].marker.color == "red" assert fig.data[1].marker.color == "blue" # default colorway fallback fig = px.scatter(tips, x="total_bill", y="tip", color="sex", template=dict()) assert fig.data[0].marker.color == px.colors.qualitative.D3[0] assert fig.data[1].marker.color == px.colors.qualitative.D3[1] # pio default template colorway fallback pio.templates.default = "seaborn" px.defaults.template = None fig = px.scatter(tips, x="total_bill", y="tip", color="sex") assert fig.data[0].marker.color == pio.templates["seaborn"].layout.colorway[0] assert fig.data[1].marker.color == pio.templates["seaborn"].layout.colorway[1] # pio default template colorway fallback pio.templates.default = "seaborn" px.defaults.template = "ggplot2" fig = px.scatter(tips, x="total_bill", y="tip", color="sex") assert fig.data[0].marker.color == pio.templates["ggplot2"].layout.colorway[0] assert fig.data[1].marker.color == pio.templates["ggplot2"].layout.colorway[1] # don't overwrite top margin when set in template fig = px.scatter(title="yo") assert fig.layout.margin.t is None fig = px.scatter() assert fig.layout.margin.t == 60 fig = px.scatter(template=dict(layout_margin_t=2)) assert fig.layout.margin.t is None # don't force histogram gridlines when set in template pio.templates.default = "none" px.defaults.template = None fig = px.scatter( tips, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram" ) assert fig.layout.xaxis2.showgrid assert fig.layout.xaxis3.showgrid assert fig.layout.yaxis2.showgrid assert fig.layout.yaxis3.showgrid fig = px.scatter( tips, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram", template=dict(layout_yaxis_showgrid=False), ) assert fig.layout.xaxis2.showgrid assert fig.layout.xaxis3.showgrid assert fig.layout.yaxis2.showgrid is None assert fig.layout.yaxis3.showgrid is None fig = px.scatter( tips, x="total_bill", y="tip", marginal_x="histogram", marginal_y="histogram", template=dict(layout_xaxis_showgrid=False), ) assert fig.layout.xaxis2.showgrid is None assert fig.layout.xaxis3.showgrid is None assert fig.layout.yaxis2.showgrid assert fig.layout.yaxis3.showgrid
def test_wrong_dimensions_mixed_case(): with pytest.raises(ValueError) as err_msg: df = pd.DataFrame(dict(time=[1, 2, 3], temperature=[20, 30, 25])) fig = px.scatter(df, x="time", y="temperature", color=[1, 3, 9, 5]) assert "All arguments should have the same length." in str( err_msg.value)
def test_numpy_labels(): fig = px.scatter(x=[1, 2, 3], y=[2, 3, 4], labels={"x": "time"}) # other labels will be kw arguments assert fig.data[0]["hovertemplate"] == "time=%{x}<br>y=%{y}"
def test_size_column(): df = px.data.tips() fig = px.scatter(df, x=df["size"], y=df.tip) assert fig.data[0].hovertemplate == "size=%{x}<br>tip=%{y}"
def test_data_frame_from_dict(): fig = px.scatter({"time": [0, 1], "money": [1, 2]}, x="time", y="money") assert fig.data[0].hovertemplate == "time=%{x}<br>money=%{y}" assert np.all(fig.data[0].x == [0, 1])
def plot(self, x=None, y=None, color=None, by=None, addTargetAuto=False, types=None, update_layout=None, roundVal=2, targetMode=None, *args, **xargs): datas = self.obj.get() target = self.obj.y.name if self.obj.y is not None else "" targetI = self.obj.get() >> df.pull( target) if target is not None and target != "" else None xIType, yIType, colorIType, byIType = None, None, None, None x, y, color, by = _get_and_checks([x, y, color, by], datas, [None, None, None, None, False]) if (all([ i is None for i in [x, y, color, by] ])): #or all([i is None for i in [x,y]])) and addTargetAuto == False raise Exception("plot impossible") if all([i is None for i in [x, y, color, by]]): types = types if types is not None else "bar" if types in ["hist", "histogram", "bar"]: argsx = xargs if not secureAddArgs(self.obj.viz.plot_class_balance, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.obj.viz.plot_class_balance""" ) argsx = removeBadArgs(self.obj.viz.plot_class_balance, argsx) return self.obj.viz.plot_class_balance( title=f"Counts of '{target}' target variable", yTitle="Count", **argsx) raise NotImplementedError(f"types '{types}' not again available") if targetMode is not None and targetMode in ["x", "y", "color", "by"]: if targetMode == "by": by = target elif targetMode == "color": color = target elif targetMode == "x": x = target elif targetMode == "y": y = target #exec(f"{targetMode}='{target}'",locals(),globals()) if x is not None: xI, xIType = _get_dtype_and_data(x, datas) if y is not None: yI, yIType = _get_dtype_and_data(y, datas) if color is not None: colorI, colorIType = _get_dtype_and_data(color, datas) if by is not None: byI, byIType = _get_dtype_and_data(by, datas) if all([i is None for i in [y, color, by] ]) and x is not None and addTargetAuto == False: if pd.api.types.is_numeric_dtype(xIType): types = types if types is not None else "histogram" if types in ["hist", "histogram"]: argsx = xargs if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.histogram, argsx) return pex.histogram(datas, x=x, **argsx) if types in ["bar"]: argsx = xargs if not secureAddArgs(pex.bar, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.bar""") argsx = removeBadArgs(pex.bar, argsx) return pex.bar(datas, x=x, **argsxg) if types in ["points", "scatter"]: sortOk = xargs.pop("sort", False) x_ = np.sort(xI) if sortOk else x sort_ = "sorted" if sortOk else "" title_ = f"{types} plot of '{x}' {sort_}" argsx = xargs if not secureAddArgs(pex.scatter, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.scatter""") argsx = removeBadArgs(pex.scatter, argsx) return pex.scatter(datas, x=x_, title=title_, **argsx).update_layout( yaxis_title="Range", xaxis_title=x) raise NotImplementedError( f"types '{types}' not again available") elif pd.api.types.is_categorical_dtype(xIType): types = types if types is not None else "bar" if types in ["hist", "histogram", "bar"]: catOrder = xI.cat.categories #print(catOrder) #print(xI.value_counts()) def fnCount(*args, **xargs): rep = xI.value_counts( *args, **xargs).sort_index(level=catOrder) #rep=rep.to_frame().rename_cols(["Count"]) return rep #fnCount=lambda *args,**xargs: xI.value_counts(*args,**xargs).sort_index(level=catOrder).as_frame() argsx = xargs if not secureAddArgs(self.plot_bar_count, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.plot_bar_count""") argsx = removeBadArgs(self.plot_bar_count, argsx) return self.plot_bar_count( fnCount, lambda *args, **xargs: xI.value_counts( ).sort_index(level=catOrder).to_frame().rename_cols( ["count"]).sort_index(level=catOrder).reset_index( ).rename_cols([x, "Count"]), ind="x", plot_kwargs=dict(y="Count", barmode="overlay", category_orders=dict( zip([x], [list(catOrder)]))), cbName=x, **argsx).update_layout(yaxis_title="Count", xaxis_title=x, title=f"Count by '{x}'") if all([i is None for i in [y, color, by] ]) and x is not None and addTargetAuto == True or ( all([i is None for i in [y, by]]) and x is not None and color is not None and addTargetAuto == False): # print("icici") color = target if color is None else color colorI = targetI if ("colorI" not in globals() or colorI is None) else colorI if pd.api.types.is_numeric_dtype(xIType): types = types if types is not None else "histogram" if types in ["hist", "histogram"]: argsx = xargs if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.histogram, argsx) return pex.histogram(datas, x=x, color=color, **argsx) if types in ["bar"]: argsx = xargs if not secureAddArgs(pex.bar, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.bar""") argsx = removeBadArgs(pex.bar, argsx) return pex.bar(datas, x=x, color=color, **argsxg) if types in ["points", "scatter"]: sortOk = xargs.pop("sort", False) x_ = np.sort(xI) if sortOk else x sort_ = "sorted" if sortOk else "" title_ = f"{types} plot of '{x}' {sort_}" argsx = xargs if not secureAddArgs(pex.scatter, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.scatter""") argsx = removeBadArgs(pex.scatter, argsx) return pex.scatter(datas, x=x_, title=title_, color=color, **argsx).update_layout( yaxis_title="Range", xaxis_title=x) raise NotImplementedError( f"types '{types}' not again available") elif pd.api.types.is_categorical_dtype(xIType): types = types if types is not None else "bar" if types in ["hist", "histogram", "bar"]: catOrder = xI.cat.categories #print(catOrder) #print(xI.value_counts()) def fnCount(*args, **xargs): rep = xI.value_counts( *args, **xargs).sort_index(level=catOrder) #rep=rep.to_frame().rename_cols(["Count"]) return rep #fnCount=lambda *args,**xargs: xI.value_counts(*args,**xargs).sort_index(level=catOrder).as_frame() argsx = xargs if not secureAddArgs(self.plot_bar_count, xargs): import warnings with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.plot_bar_count""") argsx = removeBadArgs(self.plot_bar_count, argsx) return pex.histogram(datas, x=x, color=color, barmode="group") # return self.plot_bar_count(fnCount,lambda *args,**xargs:xI.value_counts().sort_index(level=catOrder).to_frame().rename_cols(["count"]).sort_index(level=catOrder).reset_index().rename_cols([x,"Count"]),ind="x",plot_kwargs=dict(y="Count",barmode="overlay",category_orders=dict(zip([x],[list(catOrder)]))),cbName=x,**argsx).update_layout(yaxis_title="Count",xaxis_title=x,title=f"Count by '{x}'") raise NotImplementedError(f"types '{types}' not again available") if all([i is None for i in [x, color, by] ]) and y is not None and addTargetAuto == False: if pd.api.types.is_numeric_dtype(yIType): types = types if types is not None else "scatter" if types in ["points", "scatter"]: sortOk = xargs.pop("sort", False) y_ = np.sort(yI) if sortOk else yI sort_ = "sorted" if sortOk else "" title_ = f"{types} plot of '{y}' {sort_}" argsx = xargs if not secureAddArgs(pex.scatter, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.scatter""") argsx = removeBadArgs(pex.scatter, argsx) return pex.scatter(datas, y=y_, title=title_, **argsx).update_layout( xaxis_title="Range", yaxis_title=y) raise NotImplementedError( f"when only y and not target and types '{types}' -> not again available" ) if all([i is None for i in [x, y, by] ]) and color is not None and addTargetAuto == False: #print("ici") if pd.api.types.is_numeric_dtype(colorIType): raise NotImplementedError( f"when only color and types '{colorIType}' -> not again available" ) elif pd.api.types.is_categorical_dtype(colorIType): types = types if types is not None else "bar" if types in ["bar"]: argsx = xargs if not secureAddArgs(pex.bar, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.bar""") argsx = removeBadArgs(pex.bar, argsx) catOrder = colorI.cat.categories fnCount = lambda *args, **xargs: colorI.value_counts( *args, **xargs).sort_index(level=catOrder) title_ = f"Bar plot of '{color}'" rep = pex.bar(datas, x=color, color=color, barmode="overlay", category_orders=dict( zip([color], [list(catOrder)])), **argsx).update_layout(title=title_, xaxis_title=color, yaxis_title="Count") for i, y, z in zip(rep.data, fnCount(), fnCount(normalize=True) * 100): i.text = str(y) + " (" + str(np.round(z, roundVal)) + "%)" i.hovertemplate = f"{i.name}<br>Count={y}" return rep if types in ["count"]: argsx = xargs if not secureAddArgs(self.plot_bar_count, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.plot_bar_count""") argsx = removeBadArgs(self.plot_bar_count, argsx) catOrder = colorI.cat.categories fnCount = lambda *args, **xargs: colorI.value_counts( *args, **xargs).sort_index(level=catOrder) return self.plot_bar_count(fnCount, plot_kwargs=dict(color=color), **argsx).update_layout( xaxis_title=color, yaxis_title="Count") if types in ["hist", "histogram"]: argsx = xargs if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.bar, argsx) return pex.histogram(datas, x=color, color=color, **argsx).update_layout( xaxis_title=color, yaxis_title="Count") if all([i is None for i in [x, y, color] ]) and by is not None and addTargetAuto == False: if pd.api.types.is_numeric_dtype(byIType): raise NotImplementedError( f"when only color and types '{byIType}' -> not again available" ) elif pd.api.types.is_categorical_dtype(byIType): types = types if types is not None else "hist" ncols = xargs.pop("ncols", 4) if y is not None: pass multiple = False # if all([i is None for i in [y,by]]) and x is not None and color in [None,target] and addTargetAuto == True: # if pd.api.types.is_numeric_dtype(xIType): # types=types if types is not None else "hist" # if types in ["hist","histogram"]: # argsx=xargs # if not secureAddArgs(pex.histogram,xargs): # with showWarningsTmp: # warnings.warn(f""" # error in {xargs} not in pex.histogram""") # argsx=removeBadArgs(pex.histogram,argsx) # title_=f"Histogram of '{x}' colored by '{target}'" # argsx["title"]=title_ # return pex.histogram(datas,x=x,color=target,**argsx) # raise NotImplementedError(f"'{xIType}' -> not again available") if all([ i is None for i in [y, by] ]) and x is not None and color is not None and addTargetAuto == False: if pd.api.types.is_numeric_dtype(xIType): types = types if types is not None else "hist" if types in ["hist", "histogram"]: argsx = xargs if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.histogram, argsx) if not pd.api.types.is_categorical_dtype(colorIType): raise NotImplementedError( f"color '{colorIType}' and x -> not again available" ) title_ = f"Histogram of '{x}' colored by '{color}'" argsx["title"] = title_ catOrder = targetI.cat.categories argsx["category_orders"] = dict( zip([target, color], [list(catOrder), list(colorI.cat.categories)])) return pex.histogram(datas, x=x, color=color, **argsx) raise NotImplementedError(f"'{xIType}' -> not again available") if all([ i is None for i in [by, y] ]) and x is not None and color is not None and addTargetAuto == True: if pd.api.types.is_numeric_dtype(xIType): types = types if types is not None else "hist" if types in ["hist", "histogram"]: argsx = xargs if not pd.api.types.is_categorical_dtype(colorIType): raise NotImplementedError( f"color '{colorIType}' and x -> not again available" ) nbins = argsx.pop("nbins", None) by = target byI = targetI if nbins is not None: if isinstance(nbins, Iterable) and not isinstance( nbins, str) and len(nbins) > 1: if not secureAddArgs(createHistMultiBins, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in createHistMultiBins""" ) argsx = removeBadArgs(createHistMultiBins, argsx) title_ = f"Histogram of '{x}' by '{by}' colored by '{color}'" #print(title_) return createHistMultiBins(datas, x, color, colorI, by, byI, nbins, title=title_, **argsx) else: argsx["nbins"] = nbins if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.histogram, argsx) title_ = f"Histogram of '{x}' colored by '{color}' by '{by}'" argsx["title"] = title_ catOrder = targetI.cat.categories argsx["category_orders"] = dict( zip([target, color, by], [ list(catOrder), list(colorI.cat.categories), list(byI.cat.categories) ])) return pex.histogram(datas, x=x, color=color, facet_col=by, **argsx) raise NotImplementedError(f"'{xIType}' -> not again available") if all([ i is None for i in [color, y] ]) and x is not None and by is not None and addTargetAuto == True: if pd.api.types.is_numeric_dtype(xIType): types = types if types is not None else "hist" if types in ["hist", "histogram"]: argsx = xargs nbins = argsx.pop("nbins", None) if nbins is not None: if isinstance(nbins, Iterable) and not isinstance( nbins, str) and len(nbins) > 1: if not secureAddArgs(createHistMultiBins, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in createHistMultiBins""" ) argsx = removeBadArgs(createHistMultiBins, argsx) color = target colorI = targetI title_ = f"Histogram of '{x}' by '{by}' colored by '{color}'" #print(title_) return createHistMultiBins(datas, x, color, colorI, by, byI, nbins, title=title_, **argsx) else: argsx["nbins"] = nbins if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.histogram, argsx) title_ = f"Histogram of '{x}' by '{by}' colored by '{target}'" argsx["title"] = title_ catOrder = targetI.cat.categories argsx["category_orders"] = dict( zip([target, by], [list(catOrder), list(byI.cat.categories)])) return pex.histogram(datas, x=x, color=target, facet_col=by, **argsx) raise NotImplementedError(f"'{xIType}' -> not again available") if all([i is None for i in [x, y, by] ]) and color is not None and addTargetAuto == True: # print(pd.api.types.is_categorical_dtype(colorIType)) if pd.api.types.is_numeric_dtype(colorIType): raise NotImplementedError( f"when only color and types '{colorIType}' -> not again available" ) elif pd.api.types.is_categorical_dtype(colorIType): types = types if types is not None else "bar" if types in ["bar"]: argsx = xargs if not secureAddArgs(pex.bar, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.bar""") argsx = removeBadArgs(pex.bar, argsx) catOrder = targetI.cat.categories fnCount = lambda *args, **xargs: targetI.value_counts( *args, **xargs).sort_index(level=catOrder) title_ = f"Bar plot of '{target}'" datag = pd.crosstab(targetI, colorI).sort_index(level=catOrder) #print(datag) #rep=datag.iplot(kind="bar") #print(catOrder) #print(dict(zip([target,color],[list(catOrder),list(colorI.cat.categories)]))) rep = pex.histogram( datas, x=target, color=color, barmode="group", category_orders=dict( zip([target, color], [list(catOrder), list(colorI.cat.categories)])), **argsx).update_traces(showlegend=T).update_layout( showlegend=T, title=title_, xaxis_title=target, yaxis_title="Count") # for i,y,z in zip(rep.data,fnCount(),fnCount(normalize=True)*100): # i.text=str(y)+" ("+str(np.round(z,roundVal))+"%)" # i.hovertemplate=f"{i.name}<br>Count={y}" for j in rep.data: j.legendgroup return rep if types in ["count"]: argsx = xargs if not secureAddArgs(self.plot_bar_count, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.plot_bar_count""") argsx = removeBadArgs(self.plot_bar_count, argsx) catOrder = colorI.cat.categories fnCount = lambda *args, **xargs: colorI.value_counts( *args, **xargs).sort_index(level=catOrder) return self.plot_bar_count(fnCount, plot_kwargs=dict(color=color), **argsx).update_layout( xaxis_title=color, yaxis_title="Count") if types in ["hist", "histogram"]: argsx = xargs if not secureAddArgs(pex.histogram, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in pex.histogram""") argsx = removeBadArgs(pex.bar, argsx) return pex.histogram(datas, x=color, color=color, **argsx).update_layout( xaxis_title=color, yaxis_title="Count") if all([i is None for i in [y]]) and all( [i is not None for i in [color, x, by]]) and addTargetAuto == True: if pd.api.types.is_categorical_dtype( colorIType) and pd.api.types.is_categorical_dtype( xIType) and pd.api.types.is_categorical_dtype(byIType): types = types if types is not None else "point" if types in ["point", "pointplot"]: argsx = xargs if not secureAddArgs(self.plot_pointplot, xargs): with showWarningsTmp: warnings.warn(f""" error in {xargs} not in self.plot_pointplot""") argsx = removeBadArgs(self.plot_pointplot, argsx) return self.plot_pointplot(x=x, y=target, color=color, by=by, **argsx) raise NotImplementedError( f"when only color and types '{colorIType}' -> not again available" ) raise NotImplementedError( f"when color:'{colorIType}' x:'{xIType}' y: '{yIType}' by: '{byIType}' addTargetAuto: '{addTargetAuto}' -> not again available" )
def test_name_heuristics(): df = pd.DataFrame(dict(x=[0, 1], y=[3, 4], z=[0.1, 0.2])) fig = px.scatter(df, x=df.y, y=df.x, size=df.y) assert np.all(fig.data[0].x == np.array([3, 4])) assert np.all(fig.data[0].y == np.array([0, 1])) assert fig.data[0].hovertemplate == "y=%{marker.size}<br>x=%{y}"
def test_numpy(): fig = px.scatter(x=[1, 2, 3], y=[2, 3, 4], color=[1, 3, 9]) assert np.all(fig.data[0].x == np.array([1, 2, 3])) assert np.all(fig.data[0].y == np.array([2, 3, 4])) assert np.all(fig.data[0].marker.color == np.array([1, 3, 9]))
def test_wrong_column_name(): with pytest.raises(ValueError) as err_msg: fig = px.scatter(px.data.tips(), x="bla", y="wrong") assert "Value of 'x' is not the name of a column in 'data_frame'" in str( err_msg.value)
def test_missing_data_frame(): with pytest.raises(ValueError) as err_msg: fig = px.scatter(x="arg1", y="arg2") assert "String or int arguments are only possible" in str( err_msg.value)
def test_wrong_dimensions_of_array(): with pytest.raises(ValueError) as err_msg: fig = px.scatter(x=[1, 2, 3], y=[2, 3, 4, 5]) assert "All arguments should have the same length." in str( err_msg.value)