tikzplotly 0.1.3__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {tikzplotly-0.1.3/src/tikzplotly.egg-info → tikzplotly-0.1.4}/PKG-INFO +2 -1
  2. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/pyproject.toml +3 -2
  3. tikzplotly-0.1.4/src/tests/test_heatmaps.py +206 -0
  4. tikzplotly-0.1.4/src/tikzplotly/__about__.py +1 -0
  5. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_color.py +16 -0
  6. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_dataContainer.py +2 -0
  7. tikzplotly-0.1.4/src/tikzplotly/_heatmap.py +145 -0
  8. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_save.py +11 -0
  9. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_tex.py +11 -1
  10. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_utils.py +20 -1
  11. {tikzplotly-0.1.3 → tikzplotly-0.1.4/src/tikzplotly.egg-info}/PKG-INFO +2 -1
  12. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly.egg-info/SOURCES.txt +5 -3
  13. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly.egg-info/requires.txt +1 -0
  14. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly.egg-info/top_level.txt +1 -0
  15. tikzplotly-0.1.3/src/tikzplotly/__about__.py +0 -1
  16. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/LICENSE +0 -0
  17. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/README.md +0 -0
  18. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/setup.cfg +0 -0
  19. {tikzplotly-0.1.3 → tikzplotly-0.1.4/src}/tests/test_line_charts.py +0 -0
  20. {tikzplotly-0.1.3 → tikzplotly-0.1.4/src}/tests/test_markers.py +0 -0
  21. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/__init__.py +0 -0
  22. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_annotations.py +0 -0
  23. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_axis.py +0 -0
  24. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_dash.py +0 -0
  25. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_data.py +0 -0
  26. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_marker.py +0 -0
  27. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly/_scatter.py +0 -0
  28. {tikzplotly-0.1.3 → tikzplotly-0.1.4}/src/tikzplotly.egg-info/dependency_links.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tikzplotly
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Convert plotly figures to LaTeX / tikz figures
5
5
  Author-email: Thomas Saigre <tikzplotly@outlook.fr>
6
6
  License: The MIT License (MIT)
@@ -42,6 +42,7 @@ Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
43
  Requires-Dist: numpy
44
44
  Requires-Dist: plotly
45
+ Requires-Dist: PIL
45
46
  Provides-Extra: dev
46
47
  Requires-Dist: pandas; extra == "dev"
47
48
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tikzplotly"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Convert plotly figures to LaTeX / tikz figures"
9
9
  readme = "README.md"
10
10
  authors = [{name = "Thomas Saigre", email = "tikzplotly@outlook.fr"}]
@@ -25,7 +25,8 @@ classifiers = [
25
25
  keywords = ["plotly", "latex", "tikz", "figure", "conversion", "graphics"]
26
26
  dependencies = [
27
27
  "numpy",
28
- "plotly"
28
+ "plotly",
29
+ "PIL"
29
30
  ]
30
31
 
31
32
  [project.optional-dependencies]
@@ -0,0 +1,206 @@
1
+ # From https://plotly.com/python/heatmaps/
2
+ import os
3
+ import tikzplotly
4
+
5
+ from tikzplotly._tex import tex_create_document, tex_begin_environment, tex_end_environment, tex_end_all_environment
6
+
7
+ import plotly
8
+ import plotly.express as px
9
+ import pandas as pd
10
+ import plotly.graph_objects as go
11
+ import numpy as np
12
+ import datetime
13
+ import numpy as np
14
+ np.random.seed(1)
15
+
16
+ def fig1():
17
+ fig = px.imshow([[1, 20, 30],
18
+ [20, 1, 60],
19
+ [30, 60, 1]])
20
+ # fig.show()
21
+ return fig, "Heatmaps with Plotly Express"
22
+
23
+ def fig2():
24
+ df = px.data.medals_wide(indexed=True)
25
+ fig = px.imshow(df)
26
+ # fig.show()
27
+ return fig, "Heatmaps with Plotly Express 2"
28
+
29
+ def fig3():
30
+ z = [[.1, .3, .5, .7, .9],
31
+ [1, .8, .6, .4, .2],
32
+ [.2, 0, .5, .7, .9],
33
+ [.9, .8, .4, .2, 0],
34
+ [.3, .4, .5, .7, 1]]
35
+
36
+ fig = px.imshow(z, text_auto=True)
37
+ # fig.show()
38
+ return fig, "Displaying Text on Heatmaps"
39
+
40
+ def fig4():
41
+ z = [[.1, .3, .5, .7, .9],
42
+ [1, .8, .6, .4, .2],
43
+ [.2, 0, .5, .7, .9],
44
+ [.9, .8, .4, .2, 0],
45
+ [.3, .4, .5, .7, 1]]
46
+
47
+ fig = px.imshow(z, text_auto=True, aspect="auto")
48
+ # fig.show()
49
+ return fig, "Controlling Aspect Ratio"
50
+
51
+ def fig5():
52
+ data=[[1, 25, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, 5, 20]]
53
+ fig = px.imshow(data,
54
+ labels=dict(x="Day of Week", y="Time of Day", color="Productivity"),
55
+ x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
56
+ y=['Morning', 'Afternoon', 'Evening']
57
+ )
58
+ fig.update_xaxes(side="top")
59
+ # fig.show()
60
+ return fig, "Customizing the axes and labels on a heatmap"
61
+
62
+ def fig6():
63
+
64
+ fig = go.Figure(data=go.Heatmap(
65
+ z=[[1, 20, 30],
66
+ [20, 1, 60],
67
+ [30, 60, 1]]))
68
+ # fig.show()
69
+ return fig, "Basic Heatmap with plotly.graph\\_objects"
70
+
71
+ def fig7():
72
+ fig = go.Figure(data=go.Heatmap(
73
+ z=[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
74
+ x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
75
+ y=['Morning', 'Afternoon', 'Evening'],
76
+ hoverongaps = False))
77
+ # fig.show()
78
+ return fig, "Heatmap with Categorical Axis Labels"
79
+
80
+ def fig8():
81
+ import plotly.graph_objects as go
82
+
83
+ # Build the rectangles as a heatmap
84
+ # specify the edges of the heatmap squares
85
+ phi = (1 + np.sqrt(5) )/2. # golden ratio
86
+ xe = [0, 1, 1+(1/(phi**4)), 1+(1/(phi**3)), phi]
87
+ ye = [0, 1/(phi**3), 1/phi**3+1/phi**4, 1/(phi**2), 1]
88
+
89
+ z = [ [13,3,3,5],
90
+ [13,2,1,5],
91
+ [13,10,11,12],
92
+ [13,8,8,8]
93
+ ]
94
+
95
+ fig = go.Figure(data=go.Heatmap(
96
+ x = np.sort(xe),
97
+ y = np.sort(ye),
98
+ z = z,
99
+ type = 'heatmap',
100
+ colorscale = 'Viridis'))
101
+
102
+ # Add spiral line plot
103
+
104
+ def spiral(th):
105
+ a = 1.120529
106
+ b = 0.306349
107
+ r = a*np.exp(-b*th)
108
+ return (r*np.cos(th), r*np.sin(th))
109
+
110
+ theta = np.linspace(-np.pi/13,4*np.pi,1000); # angle
111
+ (x,y) = spiral(theta)
112
+
113
+ fig.add_trace(go.Scatter(x= -x+x[0], y= y-y[0],
114
+ line =dict(color='white',width=3)))
115
+
116
+ axis_template = dict(range = [0,1.6], autorange = False,
117
+ showgrid = False, zeroline = False,
118
+ linecolor = 'black', showticklabels = False,
119
+ ticks = '' )
120
+
121
+ fig.update_layout(margin = dict(t=200,r=200,b=200,l=200),
122
+ xaxis = axis_template,
123
+ yaxis = axis_template,
124
+ showlegend = False,
125
+ width = 700, height = 700,
126
+ autosize = False )
127
+
128
+ # fig.show()
129
+ return fig, "Heatmap with Unequal Block Sizes"
130
+
131
+
132
+ def fig9():
133
+ import plotly.graph_objects as go
134
+
135
+
136
+ programmers = ['Alex','Nicole','Sara','Etienne','Chelsea','Jody','Marianne']
137
+
138
+ base = datetime.datetime.today()
139
+ dates = base - np.arange(180) * datetime.timedelta(days=1)
140
+ z = np.random.poisson(size=(len(programmers), len(dates)))
141
+
142
+ fig = go.Figure(data=go.Heatmap(
143
+ z=z,
144
+ x=dates,
145
+ y=programmers,
146
+ colorscale='Viridis'))
147
+
148
+ fig.update_layout(
149
+ title='GitHub commits per day',
150
+ xaxis_nticks=36)
151
+
152
+ # fig.show()
153
+ return fig, "Heatmap with Datetime Axis"
154
+
155
+
156
+ def fig11(): # from @JasonGross, see issue https://github.com/thomas-saigre/tikzplotly/issues/6
157
+ data = np.random.rand(10,10)
158
+ fig = px.imshow(data, color_continuous_scale='Viridis', title='Heatmap Example with Plotly Express')
159
+ # fig.show()
160
+ return fig, "Heatmap Example with Plotly Express"
161
+
162
+ if __name__ == "__main__":
163
+
164
+ print("Tikzploty : ", tikzplotly.__version__)
165
+ print("Plotly : ", plotly.__version__)
166
+ print("Test line charts")
167
+
168
+ file_directory = os.path.dirname(os.path.abspath(__file__))
169
+
170
+ functions = [
171
+ ("1", fig1),
172
+ ("2", fig2),
173
+ # ("3", fig3), # texttemplate not supported
174
+ ("4", fig4),
175
+ ("5", fig5),
176
+ ("6", fig6),
177
+ ("7", fig7),
178
+ # ("8", fig8), # Not supported
179
+ ("9", fig9),
180
+ ("11", fig11)
181
+
182
+ ]
183
+
184
+ main_tex_content = tex_create_document(options="twocolumn", compatibility="newest")
185
+ main_tex_content += "\\usepackage[left=1cm, right=1cm, top=1cm, bottom=1cm]{geometry}\n"
186
+ main_tex_content += "\n"
187
+ stack_env = []
188
+ main_tex_content += tex_begin_environment("document", stack_env) + '\n'
189
+
190
+ for i, f in functions:
191
+ print(f"Figure {i}")
192
+ fig, title = f()
193
+ data = fig.data
194
+ save_path = os.path.join(file_directory, "outputs", "test_heatmap", "fig{}.tex".format(i))
195
+ tikzplotly.save(save_path, fig, img_name=os.path.join(file_directory, "outputs", "test_heatmap", "fig{}.png".format(i)))
196
+ main_tex_content += tex_begin_environment("figure", stack_env)
197
+ main_tex_content += " \\input{fig" + str(i) + ".tex}\n"
198
+ main_tex_content += " \\caption{" + title + "}\n"
199
+ main_tex_content += tex_end_environment(stack_env) + '\n'
200
+
201
+ main_tex_content += "\n" + tex_end_all_environment(stack_env)
202
+
203
+ main_tex_path = os.path.join(file_directory, "outputs", "test_heatmap", "main.tex")
204
+ print("Save main tex file : ", main_tex_path)
205
+ with open(main_tex_path, "w") as f:
206
+ f.write(main_tex_content)
@@ -0,0 +1 @@
1
+ __version__ = "0.1.4"
@@ -54,6 +54,22 @@ def convert_color(color):
54
54
  warn(f"Color {color} type is not supported yet. Returning the same color.")
55
55
  return color, 1
56
56
 
57
+ def hex2rgb(hex_color):
58
+ """Convert a hex color to a RGB color.
59
+
60
+ Parameters
61
+ ----------
62
+ hex_color
63
+ hex color string
64
+
65
+ Returns
66
+ -------
67
+ RGB color string
68
+ """
69
+ hex_color = hex_color.lstrip("#")
70
+ return str(int(hex_color[:2], 16)) + ", " + str(int(hex_color[2:4], 16)) + ", " + str(int(hex_color[4:], 16))
71
+
72
+ DEFAULT_COLORSCALE = ((0.0, '#0d0887'), (0.1111111111111111, '#46039f'), (0.2222222222222222, '#7201a8'), (0.3333333333333333, '#9c179e'), (0.4444444444444444, '#bd3786'), (0.5555555555555556, '#d8576b'), (0.6666666666666666, '#ed7953'), (0.7777777777777778, '#fb9f3a'), (0.8888888888888888, '#fdca26'), (1.0, '#f0f921'))
57
73
 
58
74
 
59
75
  ALICEBLUE = rgb_str(240, 248, 255)
@@ -51,6 +51,8 @@ class DataContainer:
51
51
  tuple (macro_name, y_label), where macro_name is the name of the data in LaTeX and y_label the name of the y data in LaTeX
52
52
  """
53
53
  for data in self.data:
54
+ if len(data.x) != len(x):
55
+ continue
54
56
  are_equals = data.x == x
55
57
  if type(are_equals) == bool:
56
58
  if are_equals:
@@ -0,0 +1,145 @@
1
+ from copy import deepcopy
2
+ import numpy as np
3
+ import io
4
+ from PIL import Image
5
+ from warnings import warn
6
+ from ._tex import tex_addplot, get_tikz_colorscale
7
+ from ._axis import Axis
8
+ from ._color import DEFAULT_COLORSCALE
9
+ from ._utils import get_ticks_str
10
+
11
+ def crop_image(img_data):
12
+ """Crops an image to the smallest bounding box that contains all non-white pixels.
13
+
14
+ Parameters
15
+ ----------
16
+ img_data
17
+ A PIL Image object.
18
+
19
+ Returns
20
+ -------
21
+ cropped_image : PIL Image
22
+ """
23
+ image_np = np.array(img_data)
24
+ non_white_rows = np.any(image_np != [255, 255, 255, 255], axis=1)
25
+ non_white_cols = np.any(image_np != [255, 255, 255, 255], axis=0)
26
+
27
+ top, bottom = np.where(non_white_rows)[0][[0, -1]]
28
+ left, right = np.where(non_white_cols)[0][[0, -1]]
29
+ cropped_image = Image.fromarray(image_np[top:bottom+1, left:right+1])
30
+
31
+ return cropped_image
32
+
33
+ def resize_image(img, nb_row, nb_col):
34
+ """Resizes an image to a given number of rows and columns.
35
+
36
+ Parameters
37
+ ----------
38
+ img
39
+ A PIL Image object.
40
+ nb_row
41
+ The number of rows of the resized image.
42
+ nb_col
43
+ The number of columns of the resized image.
44
+
45
+ Returns
46
+ -------
47
+ resized_image : PIL Image
48
+ """
49
+ resized_image = Image.new("RGBA", size = (nb_col, nb_row))
50
+ block_size = (img.width // nb_col, img.height // nb_row)
51
+
52
+ if block_size[0] != img.width / nb_col or block_size[1] != img.height / nb_row:
53
+ warn("png image has not been reduced, see https://github.com/thomas-saigre/tikzplotly/issues/6#issuecomment-2106180586")
54
+ return img
55
+
56
+ for i in range(nb_row):
57
+ for j in range(nb_col):
58
+ color = img.getpixel((j * block_size[0], i * block_size[1]))
59
+ resized_image.putpixel((j, i), color)
60
+
61
+ return resized_image
62
+
63
+
64
+ def draw_heatmap(data, fig, img_name, axis: Axis):
65
+ """Draw a heatmap, and return the tikz code.
66
+
67
+ Parameters
68
+ ----------
69
+ data
70
+ data array to be plotted
71
+ fig
72
+ whole plotly figure
73
+ img_name
74
+ name of the image file to be created
75
+ axis
76
+ axis object previously created
77
+
78
+ Returns
79
+ -------
80
+ string of tikz code for the scatter trace
81
+ """
82
+
83
+ code = ""
84
+
85
+ figure_data = np.array(data.z)
86
+
87
+ # We create a new figure with only the data, and export it as a png
88
+ fig_copy = deepcopy(fig)
89
+ fig_copy.update_layout(coloraxis_showscale=False, coloraxis_colorbar=None, xaxis_visible=False, yaxis_visible=False)
90
+ try:
91
+ fig_copy.update_traces(showscale=False)
92
+ except ValueError as e:
93
+ pass
94
+
95
+ if data.texttemplate is not None:
96
+ warn("Text template is not supported yet.")
97
+ fig_copy.update_traces(texttemplate=None)
98
+ fig_copy.update_layout(title=None)
99
+
100
+ img_bytes = fig_copy.to_image(format="png") # The image created by plotly keeps places around the heatmap
101
+ cropped_image = crop_image(Image.open(io.BytesIO(img_bytes))) # so we crop all the white around the figure
102
+ resized_image = resize_image(cropped_image, *figure_data.shape) # and we resize it so each square is a 1px x 1px square
103
+ resized_image.save(img_name)
104
+
105
+
106
+ xmin = -0.5
107
+ xmax = -0.5 + figure_data.shape[1]
108
+ ymin = -0.5 + figure_data.shape[0]
109
+ ymax = -0.5 # NB : the axis is reversed
110
+
111
+
112
+ if not (fig.layout.coloraxis.showscale == False): # If the value is True or None
113
+ axis.add_option("colorbar", None)
114
+
115
+ if (x := data.x) is not None:
116
+ xtick, xticklabels = get_ticks_str(x, fig.layout.xaxis.nticks)
117
+ axis.add_option("xtick", xtick)
118
+ axis.add_option("xticklabels", xticklabels)
119
+
120
+ if (y := data.y) is not None:
121
+ ytick, yticklabels = get_ticks_str(y, fig.layout.yaxis.nticks)
122
+ axis.add_option("ytick", ytick)
123
+ axis.add_option("yticklabels", yticklabels)
124
+
125
+ if (colorscale := data.colorscale) is not None:
126
+ axis.add_option("colormap", get_tikz_colorscale(colorscale))
127
+ elif (colorscale := fig.layout.coloraxis.colorscale) is not None:
128
+ axis.add_option("colormap", get_tikz_colorscale(colorscale))
129
+ elif data.showscale is not False:
130
+ warn("No colorscale found, using default")
131
+ axis.add_option("colormap", get_tikz_colorscale(DEFAULT_COLORSCALE))
132
+
133
+ tmp = np.where(figure_data == None, np.nan, figure_data)
134
+ axis.add_option("point meta max", tmp.max())
135
+ axis.add_option("point meta min", tmp.min())
136
+ axis.add_option("xmin", xmin)
137
+ axis.add_option("xmax", xmax)
138
+ axis.add_option("ymin", ymax)
139
+ axis.add_option("ymax", ymin)
140
+ axis.add_option("tick align", "outside")
141
+ axis.add_option("tick pos", "left")
142
+
143
+ code += tex_addplot(img_name, type="graphics", type_options=f"includegraphics cmd=\pgfimage,xmin={xmin}, xmax={xmax}, ymin={ymin}, ymax={ymax}")
144
+
145
+ return code
@@ -2,6 +2,7 @@ from pathlib import Path
2
2
  from .__about__ import __version__
3
3
  from ._tex import *
4
4
  from ._scatter import draw_scatter2d
5
+ from ._heatmap import draw_heatmap
5
6
  from ._axis import Axis
6
7
  from ._color import *
7
8
  from ._annotations import str_from_annotation
@@ -15,6 +16,7 @@ def get_tikz_code(
15
16
  tikz_options = None,
16
17
  axis_options = None,
17
18
  include_disclamer = True,
19
+ img_name = "heatmap.png",
18
20
  ):
19
21
  """Get the tikz code of a figure.
20
22
 
@@ -28,6 +30,8 @@ def get_tikz_code(
28
30
  options given to the axis environment, by default None
29
31
  include_disclamer, optional
30
32
  include a disclamer in the code, by default True
33
+ img_name, optional
34
+ name of the PNG file for heatmap, by default "heatmap.png"
31
35
 
32
36
  Returns
33
37
  -------
@@ -59,6 +63,10 @@ def get_tikz_code(
59
63
  colors_set.add(convert_color(trace.line.color)[:3])
60
64
  if trace.fillcolor is not None:
61
65
  colors_set.add(convert_color(trace.fillcolor)[:3])
66
+
67
+ elif trace.type == "heatmap":
68
+ data_str.append( draw_heatmap(trace, fig, img_name, axis) )
69
+
62
70
  else:
63
71
  warn(f"Trace type {trace.type} is not supported yet.")
64
72
 
@@ -110,5 +118,8 @@ def save(filepath: str | Path, *args, encoding: str | None = None, **kwargs):
110
118
  Additional arguments are passed to the backend.
111
119
  """
112
120
  code = get_tikz_code(*args, **kwargs)
121
+ directory = Path(filepath).parent
122
+ if not directory.exists():
123
+ directory.mkdir(parents=True)
113
124
  with open(filepath, "w") as fd:
114
125
  fd.write(code)
@@ -1,3 +1,4 @@
1
+ from ._color import hex2rgb
1
2
 
2
3
  def tex_comment(text):
3
4
  """Create a LaTeX comment.
@@ -190,4 +191,13 @@ def tex_text(text):
190
191
  """Convert a string to LaTeX,
191
192
  escaping the special characters %, _, &, #, $, {, }, ~.
192
193
  """
193
- return text.replace("%", "\\%").replace("_", "\\_").replace("&", "\\&").replace("#", "\\#").replace("$", "\\$").replace("{", "\\{").replace("}", "\\}").replace("~", "\\textasciitilde ")
194
+ return text.replace("%", "\\%").replace("_", "\\_").replace("&", "\\&").replace("#", "\\#").replace("$", "\\$").replace("{", "\\{").replace("}", "\\}").replace("~", "\\textasciitilde ")
195
+
196
+ def get_tikz_colorscale(colorscale, name="mycolor"):
197
+
198
+ code = "{" + str(name) + "}{\n"
199
+ for dist, color in colorscale:
200
+ rgb_color = hex2rgb(color)
201
+ code += f" rgb255({dist}cm)=({rgb_color})".replace(" ", "") + ";\n"
202
+ code += "}"
203
+ return code
@@ -1,6 +1,7 @@
1
1
  import re
2
2
  import warnings
3
3
  from math import floor
4
+ import numpy as np
4
5
 
5
6
  rep_digit = {'0': 'Z', '1': 'O', '2': 'T', '3': 'Th', '4': 'F', '5': 'Fi', '6': 'S', '7': 'Se', '8': 'E', '9': 'N'}
6
7
  rep_digit = dict((re.escape(k), v) for k, v in rep_digit.items())
@@ -110,4 +111,22 @@ def option_dict_to_str(options_dict, sep=" "):
110
111
  options += f"{key}={value},{sep}"
111
112
  if options == "":
112
113
  return None
113
- return options.strip()[:-1]
114
+ return options.strip()[:-1]
115
+
116
+ def get_ticks_str(data, nticks):
117
+ indices = np.arange(len(data))
118
+ if nticks is not None:
119
+ data_ = data[::len(data)//(nticks-1)]
120
+ data = np.append(data_, [data[-1]])
121
+ indices_ = indices[::len(indices)//(nticks-1)]
122
+ indices = np.append(indices_, [indices[-1]])
123
+
124
+ ticks = "{"
125
+ ticklabels = "{"
126
+ for i, val in zip(indices, data):
127
+ ticks += str(i) + ","
128
+ ticklabels += str(val) + ","
129
+ ticks = ticks[:-1] + "}"
130
+ ticklabels = ticklabels[:-1] + "}"
131
+
132
+ return ticks, ticklabels
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tikzplotly
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Convert plotly figures to LaTeX / tikz figures
5
5
  Author-email: Thomas Saigre <tikzplotly@outlook.fr>
6
6
  License: The MIT License (MIT)
@@ -42,6 +42,7 @@ Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
43
  Requires-Dist: numpy
44
44
  Requires-Dist: plotly
45
+ Requires-Dist: PIL
45
46
  Provides-Extra: dev
46
47
  Requires-Dist: pandas; extra == "dev"
47
48
 
@@ -1,6 +1,9 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ src/tests/test_heatmaps.py
5
+ src/tests/test_line_charts.py
6
+ src/tests/test_markers.py
4
7
  src/tikzplotly/__about__.py
5
8
  src/tikzplotly/__init__.py
6
9
  src/tikzplotly/_annotations.py
@@ -9,6 +12,7 @@ src/tikzplotly/_color.py
9
12
  src/tikzplotly/_dash.py
10
13
  src/tikzplotly/_data.py
11
14
  src/tikzplotly/_dataContainer.py
15
+ src/tikzplotly/_heatmap.py
12
16
  src/tikzplotly/_marker.py
13
17
  src/tikzplotly/_save.py
14
18
  src/tikzplotly/_scatter.py
@@ -18,6 +22,4 @@ src/tikzplotly.egg-info/PKG-INFO
18
22
  src/tikzplotly.egg-info/SOURCES.txt
19
23
  src/tikzplotly.egg-info/dependency_links.txt
20
24
  src/tikzplotly.egg-info/requires.txt
21
- src/tikzplotly.egg-info/top_level.txt
22
- tests/test_line_charts.py
23
- tests/test_markers.py
25
+ src/tikzplotly.egg-info/top_level.txt
@@ -1,5 +1,6 @@
1
1
  numpy
2
2
  plotly
3
+ PIL
3
4
 
4
5
  [dev]
5
6
  pandas
@@ -1 +0,0 @@
1
- __version__ = "0.1.3"
File without changes
File without changes
File without changes