New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

plotly-calplot

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

plotly-calplot - pypi Package Compare versions

Comparing version
0.1.7
to
0.1.8
+38
plotly_calplot/date_extractors.py
from typing import Any, List, Tuple
import numpy as np
import pandas as pd
def get_month_names(data: pd.DataFrame, x: str) -> List[str]:
return list(data[x].dt.month_name().unique())
def get_date_coordinates(
data: pd.DataFrame, x: str
) -> Tuple[Any, List[float], List[int]]:
month_days = []
for m in data[x].dt.month.unique():
month_days.append(data.loc[data[x].dt.month == m].max()[x].day)
month_positions = (np.cumsum(month_days) - 15) / 7
weekdays_in_year = [i.weekday() for i in data[x]]
# sometimes the last week of the current year conflicts with next year's january
# pandas will give those weeks the number 52 or 53, but this is bad news for this plot
# therefore we need a correction, for a more in-depth explanation check
# https://stackoverflow.com/questions/44372048/python-pandas-timestamp-week-returns-52-for-first-day-of-year
weeknumber_of_dates = (
data[x].apply(lambda x: get_weeknumber_of_date(x)).values.tolist()
)
return month_positions, weekdays_in_year, weeknumber_of_dates
def get_weeknumber_of_date(d: pd.Timestamp) -> int:
"""
Pandas week returns ISO week number, this function
returns gregorian week date
"""
return int(d.strftime("%W"))
from typing import Any, List
import pandas as pd
from plotly import graph_objects as go
def decide_layout(
dark_theme: bool,
title: str,
month_names: List[str],
month_positions: Any,
) -> go.Layout:
if dark_theme:
layout = go.Layout(
title=title,
yaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
tickvals=[0, 1, 2, 3, 4, 5, 6],
autorange="reversed",
),
xaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=month_names,
tickvals=month_positions,
),
font={"size": 10, "color": "#fff"},
paper_bgcolor=("#333"),
plot_bgcolor=("#333"),
margin=dict(t=20, b=20),
showlegend=False,
)
else:
layout = go.Layout(
title=title,
yaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
tickvals=[0, 1, 2, 3, 4, 5, 6],
autorange="reversed",
),
xaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=month_names,
tickvals=month_positions,
),
font={"size": 10, "color": "#9e9e9e"},
plot_bgcolor=("#fff"),
margin=dict(t=20, b=20),
showlegend=False,
)
return layout
def create_month_lines(
cplt: List[go.Figure],
month_lines_color: str,
month_lines_width: int,
data: pd.DataFrame,
weekdays_in_year: List[float],
weeknumber_of_dates: List[int],
) -> go.Figure:
kwargs = dict(
mode="lines",
line=dict(color=month_lines_color, width=month_lines_width),
hoverinfo="skip",
)
for date, dow, wkn in zip(data, weekdays_in_year, weeknumber_of_dates):
if date.day == 1:
cplt += [go.Scatter(x=[wkn - 0.5, wkn - 0.5], y=[dow - 0.5, 6.5], **kwargs)]
if dow:
cplt += [
go.Scatter(
x=[wkn - 0.5, wkn + 0.5], y=[dow - 0.5, dow - 0.5], **kwargs
),
go.Scatter(x=[wkn + 0.5, wkn + 0.5], y=[dow - 0.5, -0.5], **kwargs),
]
return cplt
def update_plot_with_current_layout(
fig: go.Figure,
cplt: go.Figure,
row: int,
layout: go.Layout,
width: Any,
total_height: Any,
) -> go.Figure:
fig.update_layout(layout)
fig.update_xaxes(layout["xaxis"])
fig.update_yaxes(layout["yaxis"])
fig.update_layout(width=width, height=total_height)
fig.add_traces(cplt, rows=[(row + 1)] * len(cplt), cols=[1] * len(cplt))
return fig
from typing import List
import numpy as np
import pandas as pd
from plotly import graph_objects as go
def create_heatmap_without_formatting(
data: pd.DataFrame,
x: str,
y: str,
weeknumber_of_dates: List[int],
weekdays_in_year: List[float],
gap: int,
year: int,
colorscale: str,
name: str,
) -> List[go.Figure]:
raw_heatmap = [
go.Heatmap(
x=weeknumber_of_dates,
y=weekdays_in_year,
z=data[y],
xgap=gap, # this
ygap=gap, # and this is used to make the grid-like apperance
showscale=False,
colorscale=colorscale, # user can setup their colorscale
hovertemplate="%{customdata[0]} <br>%{customdata[1]}=%{z} <br>Week=%{x}",
customdata=np.stack((data[x].astype(str), [name] * data.shape[0]), axis=-1),
name=str(year),
)
]
return raw_heatmap
from pandas.core.frame import DataFrame
from plotly import graph_objects as go
from plotly_calplot.date_extractors import get_date_coordinates, get_month_names
from plotly_calplot.layout_formatter import (
create_month_lines,
decide_layout,
update_plot_with_current_layout,
)
from plotly_calplot.raw_heatmap import create_heatmap_without_formatting
def year_calplot(
data: DataFrame,
x: str,
y: str,
fig: go.Figure,
row: int,
year: int,
name: str = "y",
dark_theme: bool = False,
month_lines_width: int = 1,
month_lines_color: str = "#9e9e9e",
gap: int = 1,
width: int = 800,
colorscale: str = "greens",
title: str = "",
month_lines: bool = True,
total_height: int = None,
) -> go.Figure:
"""
Each year is subplotted separately and added to the main plot
"""
month_names = get_month_names(data, x)
month_positions, weekdays_in_year, weeknumber_of_dates = get_date_coordinates(
data, x
)
# the calendar is actually a heatmap :)
cplt = create_heatmap_without_formatting(
data, x, y, weeknumber_of_dates, weekdays_in_year, gap, year, colorscale, name
)
if month_lines:
cplt = create_month_lines(
cplt,
month_lines_color,
month_lines_width,
data[x],
weekdays_in_year,
weeknumber_of_dates,
)
layout = decide_layout(dark_theme, title, month_names, month_positions)
fig = update_plot_with_current_layout(fig, cplt, row, layout, width, total_height)
return fig
from datetime import date
import pandas as pd
from pandas.core.frame import DataFrame
def fill_empty_with_zeros(
selected_year_data: DataFrame, x: str, dark_theme: bool, year: int
) -> pd.DataFrame:
year_min_date = date(year=year, month=1, day=1)
year_max_date = date(year=year, month=12, day=31)
df = pd.DataFrame({x: pd.date_range(year_min_date, year_max_date)})
final_df = df.merge(selected_year_data, how="left")
if not dark_theme:
final_df = final_df.fillna(0)
return final_df
+10
-2
Metadata-Version: 2.1
Name: plotly-calplot
Version: 0.1.7
Version: 0.1.8
Summary: Calendar Plot made with Plotly

@@ -9,9 +9,17 @@ Home-page: https://github.com/brunorosilva/plotly-calplot

Author-email: b.rosilva1@gmail.com
Requires-Python: >=3.7.1,<4.0.0
Requires-Python: >=3.8,<4.0.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Requires-Dist: flake8 (>=4.0.1,<5.0.0)
Requires-Dist: isort (>=5.10.1,<6.0.0)
Requires-Dist: mypy (>=0.942,<0.943)
Requires-Dist: numpy (>=1.22.3,<2.0.0)
Requires-Dist: pandas (>=1.0.5,<2.0.0)
Requires-Dist: plotly (>=5.4.0,<6.0.0)
Requires-Dist: pytest (>=7.1.1,<8.0.0)
Requires-Dist: pytest-cov (>=3.0.0,<4.0.0)
Requires-Dist: vulture (>=2.3,<3.0)
Project-URL: Repository, https://github.com/brunorosilva/plotly-calplot

@@ -18,0 +26,0 @@ Description-Content-Type: text/markdown

+3
-1

@@ -1,1 +0,3 @@

from .calplot import calplot
from .calplot import calplot # noqa: F401
__version__ = "0.0.2"

@@ -1,3 +0,1 @@

import numpy as np
import pandas as pd
from pandas.core.frame import DataFrame

@@ -7,166 +5,6 @@ from plotly import graph_objects as go

from plotly_calplot.single_year_calplot import year_calplot
from plotly_calplot.utils import fill_empty_with_zeros
def get_weeknumber_of_date(d):
"""
Pandas week returns some strange values, this function fixes'em
"""
if d.month == 1 and d.week > 50:
return 0
elif d.month == 12 and d.week < 10:
return 53
else:
return d.week
def year_calplot(
data: DataFrame,
x,
y,
name,
year,
fig,
row,
month_lines,
month_lines_width,
month_lines_color,
colorscale,
gap,
title,
dark_theme,
width,
total_height,
):
"""
Each year is subplotted separately and added to the main plot
"""
month_names = list(data[x].dt.month_name().unique())
month_days = []
for month in data[x].dt.month.unique():
month_days.append(data.loc[data[x].dt.month == month].max()[x].day)
month_positions = (np.cumsum(month_days) - 15) / 7
weekdays_in_year = [i.weekday() for i in data[x]]
# sometimes the last week of the current year conflicts with next year's january
# pandas will give those weeks the number 52 or 53, but this is bad news for this plot
# therefore we need a correction, for a more in-depth explanation check
# https://stackoverflow.com/questions/44372048/python-pandas-timestamp-week-returns-52-for-first-day-of-year
weeknumber_of_dates = (
data[x].apply(lambda x: get_weeknumber_of_date(x)).values.tolist()
)
# the calendar is actually a heatmap :)
cplt = [
go.Heatmap(
x=weeknumber_of_dates,
y=weekdays_in_year,
z=data[y],
xgap=gap, # this
ygap=gap, # and this is used to make the grid-like apperance
showscale=False,
colorscale=colorscale, # user can setup their colorscale
hovertemplate="%{customdata[0]} <br>%{customdata[1]}=%{z} <br>Week=%{x}",
customdata=np.stack((data[x].astype(str), [name] * data.shape[0]), axis=-1),
name=str(year),
)
]
if month_lines:
kwargs = dict(
mode="lines",
line=dict(color=month_lines_color, width=month_lines_width),
hoverinfo="skip",
)
for date, dow, wkn in zip(data[x], weekdays_in_year, weeknumber_of_dates):
if date.day == 1:
cplt += [
go.Scatter(x=[wkn - 0.5, wkn - 0.5], y=[dow - 0.5, 6.5], **kwargs)
]
if dow:
cplt += [
go.Scatter(
x=[wkn - 0.5, wkn + 0.5], y=[dow - 0.5, dow - 0.5], **kwargs
),
go.Scatter(
x=[wkn + 0.5, wkn + 0.5], y=[dow - 0.5, -0.5], **kwargs
),
]
# if row == 0:
if dark_theme:
layout = go.Layout(
title=title,
yaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
tickvals=[0, 1, 2, 3, 4, 5, 6],
autorange="reversed",
),
xaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=month_names,
tickvals=month_positions,
),
font={"size": 10, "color": "#fff"},
paper_bgcolor=("#333"),
plot_bgcolor=("#333"),
margin=dict(t=20, b=20),
showlegend=False,
)
fig.update_layout(layout)
fig.update_xaxes(layout["xaxis"])
fig.update_yaxes(layout["yaxis"])
else:
layout = go.Layout(
title=title,
yaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
tickvals=[0, 1, 2, 3, 4, 5, 6],
autorange="reversed",
),
xaxis=dict(
showline=False,
showgrid=False,
zeroline=False,
tickmode="array",
ticktext=month_names,
tickvals=month_positions,
),
font={"size": 10, "color": "#9e9e9e"},
plot_bgcolor=("#fff"),
margin=dict(t=20, b=20),
showlegend=False,
)
fig.update_layout(layout)
fig.update_xaxes(layout["xaxis"])
fig.update_yaxes(layout["yaxis"])
fig.update_layout(width=width, height=total_height)
fig.add_traces(cplt, rows=[(row + 1)] * len(cplt), cols=[1] * len(cplt))
return fig
def fill_empty_with_zeros(selected_year_data: DataFrame, x, dark_theme, year: int):
year_min_date = "01-01-" + str(year)
year_max_date = "31-12-" + str(year)
df = pd.DataFrame({x: pd.date_range(year_min_date, year_max_date)})
final_df = df.merge(selected_year_data, how="left")
if not dark_theme:
final_df = final_df.fillna(0)
return final_df
def calplot(

@@ -188,3 +26,3 @@ data: DataFrame,

space_between_plots: float = 0.08,
):
) -> go.Figure:
"""

@@ -198,3 +36,3 @@ Yearly Calendar Heatmap

one value column for displaying in the plot
x : str

@@ -243,3 +81,3 @@ The name of the date like column in data

according to the amount of years in data
space_between_plots: float = 0.08

@@ -246,0 +84,0 @@ controls the vertical space between the plots

[tool.poetry]
name = "plotly_calplot"
version = "0.1.7"
version = "0.1.8"
description = "Calendar Plot made with Plotly"

@@ -11,5 +11,12 @@ authors = ["Bruno Rodrigues Silva <b.rosilva1@gmail.com>"]

[tool.poetry.dependencies]
python = "^3.7.1"
python = ">=3.8,<4.0.0"
plotly = "^5.4.0"
pandas = "^1.0.5"
isort = "^5.10.1"
flake8 = "^4.0.1"
vulture = "^2.3"
mypy = "^0.942"
numpy = "^1.22.3"
pytest = "^7.1.1"
pytest-cov = "^3.0.0"

@@ -16,0 +23,0 @@ [tool.poetry.dev-dependencies]

@@ -11,7 +11,15 @@ # -*- coding: utf-8 -*-

install_requires = \
['pandas>=1.0.5,<2.0.0', 'plotly>=5.4.0,<6.0.0']
['flake8>=4.0.1,<5.0.0',
'isort>=5.10.1,<6.0.0',
'mypy>=0.942,<0.943',
'numpy>=1.22.3,<2.0.0',
'pandas>=1.0.5,<2.0.0',
'plotly>=5.4.0,<6.0.0',
'pytest-cov>=3.0.0,<4.0.0',
'pytest>=7.1.1,<8.0.0',
'vulture>=2.3,<3.0']
setup_kwargs = {
'name': 'plotly-calplot',
'version': '0.1.7',
'version': '0.1.8',
'description': 'Calendar Plot made with Plotly',

@@ -27,3 +35,3 @@ 'long_description': '# Calendar Heatmap with Plotly\nMaking it easier to visualize and costumize time relevant or time series data with plotly interaction.\n\nThis plot is a very similar to the contribuitions available on Github and Gitlab profile pages and to [Calplot](https://github.com/tomkwok/calplot) - which is a pyplot implementation of the calendar heatmap, thus it is not interactive right off the bat.\n\nThe first mention I could find of this plot being made with plotly was in [this forum post](https://community.plotly.com/t/colored-calendar-heatmap-in-dash/10907/16) and it got my attention as something it should be easily available to anyone.\n\n# Installation\n``` bash\npip install plotly-calplot\n```\n\n# Examples\n\nIn [this Medium article](https://medium.com/@brunorosilva/5fc322125db7) I covered lot\'s of usage methods for this library.\n``` python\nfrom plotly_calplot import calplot\n\nfig = calplot(df, x="date", y="value")\nfig.show()\n# you can also adjust layout and your usual plotly stuff\n```\n\n<img src="https://github.com/brunorosilva/plotly-calplot/blob/main/assets/images/example.png?raw=true">\n',

'install_requires': install_requires,
'python_requires': '>=3.7.1,<4.0.0',
'python_requires': '>=3.8,<4.0.0',
}

@@ -30,0 +38,0 @@