tikzplotly 0.1.7__tar.gz → 0.2.0__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.
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/PKG-INFO +11 -6
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/README.md +7 -4
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/pyproject.toml +4 -2
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tests/test_heatmaps.py +9 -9
- tikzplotly-0.2.0/src/tests/test_histograms.py +284 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tests/test_line_charts.py +26 -1
- tikzplotly-0.2.0/src/tikzplotly/__about__.py +1 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_axis.py +86 -36
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_heatmap.py +1 -1
- tikzplotly-0.2.0/src/tikzplotly/_histogram.py +132 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_save.py +9 -7
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_tex.py +30 -1
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_utils.py +49 -4
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly.egg-info/PKG-INFO +11 -6
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly.egg-info/SOURCES.txt +3 -0
- tikzplotly-0.2.0/tests/test_histograms.py +95 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/tests/test_scatter.py +72 -3
- tikzplotly-0.2.0/tests/test_tikzplotly.py +39 -0
- tikzplotly-0.1.7/src/tikzplotly/__about__.py +0 -1
- tikzplotly-0.1.7/tests/test_tikzplotly.py +0 -6
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/LICENSE +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/setup.cfg +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tests/test_markers.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/__init__.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_annotations.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_color.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_dash.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_data.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_dataContainer.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_marker.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly/_scatter.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly.egg-info/dependency_links.txt +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly.egg-info/requires.txt +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/src/tikzplotly.egg-info/top_level.txt +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/tests/test_heatmap.py +0 -0
- {tikzplotly-0.1.7 → tikzplotly-0.2.0}/tests/test_markers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: tikzplotly
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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)
|
|
@@ -30,9 +30,11 @@ Keywords: plotly,latex,tikz,figure,conversion,graphics
|
|
|
30
30
|
Classifier: Development Status :: 5 - Production/Stable
|
|
31
31
|
Classifier: Programming Language :: Python
|
|
32
32
|
Classifier: Programming Language :: Python :: 3
|
|
33
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
34
33
|
Classifier: Programming Language :: Python :: 3.9
|
|
35
34
|
Classifier: Programming Language :: Python :: 3.10
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
38
|
Classifier: License :: OSI Approved :: MIT License
|
|
37
39
|
Classifier: Operating System :: OS Independent
|
|
38
40
|
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
|
|
@@ -45,11 +47,15 @@ Requires-Dist: pillow
|
|
|
45
47
|
Provides-Extra: dev
|
|
46
48
|
Requires-Dist: pandas; extra == "dev"
|
|
47
49
|
|
|
48
|
-

|
|
51
|
+
|
|
49
52
|
|
|
50
53
|
[](https://pypi.org/project/tikzplotly)
|
|
54
|
+
[](https://pypi.org/project/tikzplotly)
|
|
55
|
+
[](https://pypi.org/project/tikzplotly)
|
|
51
56
|
[](https://pypi.org/pypi/tikzplotly/)
|
|
52
57
|
|
|
58
|
+
[](https://github.com/thomas-saigre/tikzplotly/releases)
|
|
53
59
|
[](https://github.com/thomas-saigre/tikzplotly/issues)
|
|
54
60
|
[](https://codecov.io/gh/thomas-saigre/tikzplotly)
|
|
55
61
|

|
|
@@ -142,8 +148,7 @@ To correctly compile the document, you will need to add the following packages t
|
|
|
142
148
|
|
|
143
149
|
* This module is in development and new features are added bit by bit, when needed. If you have a feature request, please open an issue with the plotly figure you want to convert and the desired output.
|
|
144
150
|
You can also submit a pull request with the desired feature !
|
|
145
|
-
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers.
|
|
146
|
-
* More details in [doc/NB.md](doc/NB.md).
|
|
151
|
+
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers, more details can be found in the documentation.
|
|
147
152
|
|
|
148
153
|
|
|
149
154
|
## References
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-

|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
[](https://pypi.org/project/tikzplotly)
|
|
5
|
+
[](https://pypi.org/project/tikzplotly)
|
|
6
|
+
[](https://pypi.org/project/tikzplotly)
|
|
4
7
|
[](https://pypi.org/pypi/tikzplotly/)
|
|
5
8
|
|
|
9
|
+
[](https://github.com/thomas-saigre/tikzplotly/releases)
|
|
6
10
|
[](https://github.com/thomas-saigre/tikzplotly/issues)
|
|
7
11
|
[](https://codecov.io/gh/thomas-saigre/tikzplotly)
|
|
8
12
|

|
|
@@ -95,8 +99,7 @@ To correctly compile the document, you will need to add the following packages t
|
|
|
95
99
|
|
|
96
100
|
* This module is in development and new features are added bit by bit, when needed. If you have a feature request, please open an issue with the plotly figure you want to convert and the desired output.
|
|
97
101
|
You can also submit a pull request with the desired feature !
|
|
98
|
-
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers.
|
|
99
|
-
* More details in [doc/NB.md](doc/NB.md).
|
|
102
|
+
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers, more details can be found in the documentation.
|
|
100
103
|
|
|
101
104
|
|
|
102
105
|
## References
|
|
@@ -109,4 +112,4 @@ You can also submit a pull request with the desired feature !
|
|
|
109
112
|
|
|
110
113
|
## License
|
|
111
114
|
|
|
112
|
-
This project is licensed under the MIT [License](LICENSE).
|
|
115
|
+
This project is licensed under the MIT [License](LICENSE).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tikzplotly"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
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"}]
|
|
@@ -13,9 +13,11 @@ classifiers = [
|
|
|
13
13
|
"Development Status :: 5 - Production/Stable",
|
|
14
14
|
"Programming Language :: Python",
|
|
15
15
|
"Programming Language :: Python :: 3",
|
|
16
|
-
"Programming Language :: Python :: 3.8",
|
|
17
16
|
"Programming Language :: Python :: 3.9",
|
|
18
17
|
"Programming Language :: Python :: 3.10",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
19
21
|
"License :: OSI Approved :: MIT License",
|
|
20
22
|
"Operating System :: OS Independent",
|
|
21
23
|
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
|
|
@@ -166,16 +166,16 @@ if __name__ == "__main__":
|
|
|
166
166
|
file_directory = os.path.dirname(os.path.abspath(__file__))
|
|
167
167
|
|
|
168
168
|
functions = [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
("1", fig1),
|
|
170
|
+
("2", fig2),
|
|
171
|
+
# ("3", fig3), # texttemplate not supported
|
|
172
|
+
("4", fig4),
|
|
173
|
+
("5", fig5),
|
|
174
|
+
("6", fig6),
|
|
175
175
|
("7", fig7),
|
|
176
|
-
#
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
# ("8", fig8), # Not supported
|
|
177
|
+
("9", fig9),
|
|
178
|
+
("11", fig11)
|
|
179
179
|
]
|
|
180
180
|
|
|
181
181
|
main_tex_content = tex_create_document(options="twocolumn", compatibility="newest")
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# From https://plotly.com/python/histograms/
|
|
2
|
+
import plotly
|
|
3
|
+
import plotly.express as px
|
|
4
|
+
import plotly.graph_objects as go
|
|
5
|
+
from plotly.subplots import make_subplots
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import tikzplotly
|
|
9
|
+
import os
|
|
10
|
+
from warnings import warn
|
|
11
|
+
from tikzplotly._tex import tex_create_document, tex_begin_environment, tex_end_environment, tex_end_all_environment
|
|
12
|
+
|
|
13
|
+
def fig1():
|
|
14
|
+
df = px.data.tips()
|
|
15
|
+
fig = px.histogram(df, x="total_bill")
|
|
16
|
+
# fig.show()
|
|
17
|
+
return fig, "Histogram of total bill"
|
|
18
|
+
|
|
19
|
+
def fig2():
|
|
20
|
+
df = px.data.tips()
|
|
21
|
+
# Here we use a column with categorical data
|
|
22
|
+
fig = px.histogram(df, x="day")
|
|
23
|
+
# fig.show()
|
|
24
|
+
return fig, "Histogram of days"
|
|
25
|
+
|
|
26
|
+
def fig3():
|
|
27
|
+
df = px.data.tips()
|
|
28
|
+
fig = px.histogram(df, x="total_bill", nbins=20)
|
|
29
|
+
# fig.show()
|
|
30
|
+
return fig, "Choose the number of bins"
|
|
31
|
+
|
|
32
|
+
def fig4():
|
|
33
|
+
warn("NB: This example is quite not working because of the high number of different dates present in the data set")
|
|
34
|
+
df = px.data.stocks()
|
|
35
|
+
fig = px.histogram(df, x="date")
|
|
36
|
+
fig.update_layout(bargap=0.2)
|
|
37
|
+
# fig.show()
|
|
38
|
+
return fig, "Histogram on date data"
|
|
39
|
+
|
|
40
|
+
def fig5():
|
|
41
|
+
df = px.data.tips()
|
|
42
|
+
fig = px.histogram(df, x="day", category_orders=dict(day=["Thur", "Fri", "Sat", "Sun"]))
|
|
43
|
+
# fig.show()
|
|
44
|
+
return fig, "Histograms on Categorical Data"
|
|
45
|
+
|
|
46
|
+
def fig6():
|
|
47
|
+
df = px.data.tips()
|
|
48
|
+
fig = px.histogram(df, x="total_bill", histnorm='probability density')
|
|
49
|
+
# fig.show()
|
|
50
|
+
return fig, "Type of normalization"
|
|
51
|
+
|
|
52
|
+
def fig7():
|
|
53
|
+
df = px.data.tips()
|
|
54
|
+
fig = px.histogram(df, x="total_bill",
|
|
55
|
+
title='Histogram of bills',
|
|
56
|
+
labels={'total_bill':'total bill'}, # can specify one label per df column
|
|
57
|
+
opacity=0.8,
|
|
58
|
+
log_y=True, # represent bars with log scale
|
|
59
|
+
color_discrete_sequence=['indianred'] # color of histogram bars
|
|
60
|
+
)
|
|
61
|
+
# fig.show()
|
|
62
|
+
return fig, "Aspect of the histogram plot"
|
|
63
|
+
|
|
64
|
+
def fig8():
|
|
65
|
+
df = px.data.tips()
|
|
66
|
+
fig = px.histogram(df, x="total_bill", color="sex")
|
|
67
|
+
# fig.show()
|
|
68
|
+
return fig, "Several histograms for different values of one column"
|
|
69
|
+
|
|
70
|
+
def fig9():
|
|
71
|
+
df = px.data.tips()
|
|
72
|
+
fig = px.histogram(df, x="total_bill", color="sex", marginal="rug", # can be `box`, `violin`
|
|
73
|
+
hover_data=df.columns)
|
|
74
|
+
return fig, "Histograms with pattern shapes"
|
|
75
|
+
|
|
76
|
+
def fig10():
|
|
77
|
+
df = px.data.tips()
|
|
78
|
+
fig = px.histogram(df, x="total_bill", y="tip", histfunc="avg", nbins=8, text_auto=True)
|
|
79
|
+
return fig, "Adding text labels"
|
|
80
|
+
|
|
81
|
+
def fig11():
|
|
82
|
+
np.random.seed(1)
|
|
83
|
+
x = np.random.randn(500)
|
|
84
|
+
fig = go.Figure(data=[go.Histogram(x=x)])
|
|
85
|
+
return fig, "Basic Histogram"
|
|
86
|
+
|
|
87
|
+
def fig12():
|
|
88
|
+
x = np.random.randn(500)
|
|
89
|
+
fig = go.Figure(data=[go.Histogram(x=x, histnorm='probability')])
|
|
90
|
+
return fig, "Normalized Histogram"
|
|
91
|
+
|
|
92
|
+
def fig13():
|
|
93
|
+
y = np.random.randn(500)
|
|
94
|
+
fig = go.Figure(data=[go.Histogram(y=y)])
|
|
95
|
+
return fig, "Horizontal Histogram"
|
|
96
|
+
|
|
97
|
+
def fig14():
|
|
98
|
+
|
|
99
|
+
x0 = np.random.randn(500)
|
|
100
|
+
x1 = np.random.randn(500) + 1
|
|
101
|
+
|
|
102
|
+
fig = go.Figure()
|
|
103
|
+
fig.add_trace(go.Histogram(x=x0))
|
|
104
|
+
fig.add_trace(go.Histogram(x=x1))
|
|
105
|
+
|
|
106
|
+
# Overlay both histograms
|
|
107
|
+
fig.update_layout(barmode='overlay')
|
|
108
|
+
# Reduce opacity to see both histograms
|
|
109
|
+
fig.update_traces(opacity=0.75)
|
|
110
|
+
return fig, "Overlay Histograms"
|
|
111
|
+
|
|
112
|
+
def fig15():
|
|
113
|
+
x0 = np.random.randn(500)
|
|
114
|
+
x1 = np.random.randn(500)
|
|
115
|
+
|
|
116
|
+
fig = go.Figure()
|
|
117
|
+
fig.add_trace(go.Histogram(x=x0))
|
|
118
|
+
fig.add_trace(go.Histogram(x=x1))
|
|
119
|
+
|
|
120
|
+
# The two histograms are drawn on top of another
|
|
121
|
+
fig.update_layout(barmode='stack')
|
|
122
|
+
return fig, "Stacked Histograms"
|
|
123
|
+
|
|
124
|
+
def fig16():
|
|
125
|
+
x0 = np.random.randn(500)
|
|
126
|
+
x1 = np.random.randn(500) + 1
|
|
127
|
+
|
|
128
|
+
fig = go.Figure()
|
|
129
|
+
fig.add_trace(go.Histogram(
|
|
130
|
+
x=x0,
|
|
131
|
+
histnorm='percent',
|
|
132
|
+
name='control', # name used in legend and hover labels
|
|
133
|
+
xbins=dict( # bins used for histogram
|
|
134
|
+
start=-4.0,
|
|
135
|
+
end=3.0,
|
|
136
|
+
size=0.5
|
|
137
|
+
),
|
|
138
|
+
marker_color='#EB89B5',
|
|
139
|
+
opacity=0.75
|
|
140
|
+
))
|
|
141
|
+
fig.add_trace(go.Histogram(
|
|
142
|
+
x=x1,
|
|
143
|
+
histnorm='percent',
|
|
144
|
+
name='experimental',
|
|
145
|
+
xbins=dict(
|
|
146
|
+
start=-3.0,
|
|
147
|
+
end=4,
|
|
148
|
+
size=0.5
|
|
149
|
+
),
|
|
150
|
+
marker_color='#330C73',
|
|
151
|
+
opacity=0.75
|
|
152
|
+
))
|
|
153
|
+
|
|
154
|
+
fig.update_layout(
|
|
155
|
+
title_text='Sampled Results', # title of plot
|
|
156
|
+
xaxis_title_text='Value', # xaxis label
|
|
157
|
+
yaxis_title_text='Count', # yaxis label
|
|
158
|
+
bargap=0.2, # gap between bars of adjacent location coordinates
|
|
159
|
+
bargroupgap=0.1 # gap between bars of the same location coordinates
|
|
160
|
+
)
|
|
161
|
+
return fig, "Styled Histogram"
|
|
162
|
+
|
|
163
|
+
def fig17():
|
|
164
|
+
numbers = ["5", "10", "3", "10", "5", "8", "5", "5"]
|
|
165
|
+
fig = go.Figure()
|
|
166
|
+
fig.add_trace(go.Histogram(x=numbers, name="count", texttemplate="%{x}", textfont_size=20))
|
|
167
|
+
return fig, "Histogram Bar Text"
|
|
168
|
+
|
|
169
|
+
def fig18():
|
|
170
|
+
x = np.random.randn(500)
|
|
171
|
+
fig = go.Figure(data=[go.Histogram(x=x, cumulative_enabled=True)])
|
|
172
|
+
return fig, "Cumulative Histogram"
|
|
173
|
+
|
|
174
|
+
def fig19():
|
|
175
|
+
x = ["Apples","Apples","Apples","Oranges", "Bananas"]
|
|
176
|
+
y = ["5","10","3","10","5"]
|
|
177
|
+
|
|
178
|
+
fig = go.Figure()
|
|
179
|
+
fig.add_trace(go.Histogram(histfunc="count", y=y, x=x, name="count"))
|
|
180
|
+
fig.add_trace(go.Histogram(histfunc="sum", y=y, x=x, name="sum"))
|
|
181
|
+
return fig, "Specify Aggregation Function"
|
|
182
|
+
|
|
183
|
+
def fig20():
|
|
184
|
+
x = ['1970-01-01', '1970-01-01', '1970-02-01', '1970-04-01', '1970-01-02',
|
|
185
|
+
'1972-01-31', '1970-02-13', '1971-04-19']
|
|
186
|
+
|
|
187
|
+
fig = make_subplots(rows=3, cols=2)
|
|
188
|
+
|
|
189
|
+
trace0 = go.Histogram(x=x, nbinsx=4)
|
|
190
|
+
trace1 = go.Histogram(x=x, nbinsx = 8)
|
|
191
|
+
trace2 = go.Histogram(x=x, nbinsx=10)
|
|
192
|
+
trace3 = go.Histogram(x=x,
|
|
193
|
+
xbins=dict(
|
|
194
|
+
start='1969-11-15',
|
|
195
|
+
end='1972-03-31',
|
|
196
|
+
size='M18'), # M18 stands for 18 months
|
|
197
|
+
autobinx=False
|
|
198
|
+
)
|
|
199
|
+
trace4 = go.Histogram(x=x,
|
|
200
|
+
xbins=dict(
|
|
201
|
+
start='1969-11-15',
|
|
202
|
+
end='1972-03-31',
|
|
203
|
+
size='M4'), # 4 months bin size
|
|
204
|
+
autobinx=False
|
|
205
|
+
)
|
|
206
|
+
trace5 = go.Histogram(x=x,
|
|
207
|
+
xbins=dict(
|
|
208
|
+
start='1969-11-15',
|
|
209
|
+
end='1972-03-31',
|
|
210
|
+
size= 'M2'), # 2 months
|
|
211
|
+
autobinx = False
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
fig.append_trace(trace0, 1, 1)
|
|
215
|
+
fig.append_trace(trace1, 1, 2)
|
|
216
|
+
fig.append_trace(trace2, 2, 1)
|
|
217
|
+
fig.append_trace(trace3, 2, 2)
|
|
218
|
+
fig.append_trace(trace4, 3, 1)
|
|
219
|
+
fig.append_trace(trace5, 3, 2)
|
|
220
|
+
|
|
221
|
+
return fig, "Custom Binning"
|
|
222
|
+
|
|
223
|
+
def fig21():
|
|
224
|
+
df = px.data.tips()
|
|
225
|
+
fig = px.histogram(df, x="day").update_xaxes(categoryorder='total ascending')
|
|
226
|
+
return fig, "Sort Histogram by Category Order"
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
if __name__ == "__main__":
|
|
230
|
+
|
|
231
|
+
print("Tikzploty : ", tikzplotly.__version__)
|
|
232
|
+
print("Plotly : ", plotly.__version__)
|
|
233
|
+
print("Test histograms")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
file_directory = os.path.dirname(os.path.abspath(__file__))
|
|
237
|
+
|
|
238
|
+
functions = [
|
|
239
|
+
("1", fig1),
|
|
240
|
+
("2", fig2),
|
|
241
|
+
("3", fig3),
|
|
242
|
+
# ("4", fig4),
|
|
243
|
+
("5", fig5),
|
|
244
|
+
("6", fig6),
|
|
245
|
+
("7", fig7),
|
|
246
|
+
("8", fig8),
|
|
247
|
+
# ("9", fig9), # Trace type box is not yet supported
|
|
248
|
+
# ("10", fig10), # Text template is not supported yet.
|
|
249
|
+
("11", fig11),
|
|
250
|
+
("12", fig12),
|
|
251
|
+
("13", fig13),
|
|
252
|
+
("14", fig14),
|
|
253
|
+
("15", fig15),
|
|
254
|
+
# ("16", fig16), # Layout of this example not supported yet
|
|
255
|
+
("17", fig17), # Text template is not supported yet.
|
|
256
|
+
("18", fig18),
|
|
257
|
+
("19", fig19),
|
|
258
|
+
# ("20", fig20), # Subplots not supported yet
|
|
259
|
+
("21", fig21) # Category order not supported yet
|
|
260
|
+
]
|
|
261
|
+
|
|
262
|
+
main_tex_content = tex_create_document(options="twocolumn", compatibility="newest")
|
|
263
|
+
main_tex_content += "\\usepackage[left=1cm, right=1cm, top=1cm, bottom=1cm]{geometry}\n"
|
|
264
|
+
main_tex_content += "\n"
|
|
265
|
+
stack_env = []
|
|
266
|
+
main_tex_content += tex_begin_environment("document", stack_env) + '\n'
|
|
267
|
+
|
|
268
|
+
for i, f in functions:
|
|
269
|
+
print(f"Figure {i}")
|
|
270
|
+
fig, title = f()
|
|
271
|
+
data = fig.data
|
|
272
|
+
save_path = os.path.join(file_directory, "outputs", "test_histograms", "fig{}.tex".format(i))
|
|
273
|
+
tikzplotly.save(save_path, fig)
|
|
274
|
+
main_tex_content += tex_begin_environment("figure", stack_env)
|
|
275
|
+
main_tex_content += " \\input{fig" + str(i) + ".tex}\n"
|
|
276
|
+
main_tex_content += " \\caption{" + title + "}\n"
|
|
277
|
+
main_tex_content += tex_end_environment(stack_env) + '\n'
|
|
278
|
+
|
|
279
|
+
main_tex_content += "\n" + tex_end_all_environment(stack_env)
|
|
280
|
+
|
|
281
|
+
main_tex_path = os.path.join(file_directory, "outputs", "test_histograms", "main.tex")
|
|
282
|
+
print("Save main tex file : ", main_tex_path)
|
|
283
|
+
with open(main_tex_path, "w") as f:
|
|
284
|
+
f.write(main_tex_content)
|
|
@@ -371,6 +371,28 @@ def fig15():
|
|
|
371
371
|
# fig.show()
|
|
372
372
|
return fig, "Filled Lines"
|
|
373
373
|
|
|
374
|
+
# https://plotly.com/python/log-plot/
|
|
375
|
+
|
|
376
|
+
def fig16():
|
|
377
|
+
df = px.data.gapminder().query("year == 2007")
|
|
378
|
+
fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country", log_x=True)
|
|
379
|
+
return fig, "Log Scale"
|
|
380
|
+
|
|
381
|
+
def fig17():
|
|
382
|
+
df = px.data.gapminder().query("year == 2007")
|
|
383
|
+
|
|
384
|
+
fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country",
|
|
385
|
+
log_x=True, range_x=[1,100000], range_y=[0,100])
|
|
386
|
+
return fig, "Log scale with range"
|
|
387
|
+
|
|
388
|
+
def fig18():
|
|
389
|
+
df = px.data.gapminder().query("year == 2007")
|
|
390
|
+
|
|
391
|
+
fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country",
|
|
392
|
+
log_x=True, range_x=[1,100000], range_y=[0,100])
|
|
393
|
+
|
|
394
|
+
fig.update_xaxes(minor=dict(ticks="inside", ticklen=6, showgrid=True))
|
|
395
|
+
return fig, "Log scale with range and minor ticks"
|
|
374
396
|
|
|
375
397
|
if __name__ == "__main__":
|
|
376
398
|
|
|
@@ -394,7 +416,10 @@ if __name__ == "__main__":
|
|
|
394
416
|
("11", fig11),
|
|
395
417
|
# ("12", fig12),
|
|
396
418
|
("14", fig14),
|
|
397
|
-
("15", fig15)
|
|
419
|
+
("15", fig15),
|
|
420
|
+
("16", fig16),
|
|
421
|
+
("17", fig17),
|
|
422
|
+
("18", fig18),
|
|
398
423
|
]
|
|
399
424
|
|
|
400
425
|
main_tex_content = tex_create_document(options="twocolumn", compatibility="newest")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.0"
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from ._color import convert_color
|
|
2
2
|
from ._tex import tex_begin_environment
|
|
3
|
-
from ._utils import sanitize_TeX_text, option_dict_to_str
|
|
3
|
+
from ._utils import sanitize_TeX_text, option_dict_to_str, get_ticks_str
|
|
4
|
+
from warnings import warn
|
|
5
|
+
|
|
4
6
|
class Axis():
|
|
5
7
|
|
|
6
8
|
def __init__(self, layout, colors_set, axis_options=None):
|
|
@@ -15,9 +17,8 @@ class Axis():
|
|
|
15
17
|
axis_options
|
|
16
18
|
options given to the axis environment, by default None. Can be a dict ({option: value}) or a string ("option1=value1, option2=value2").
|
|
17
19
|
"""
|
|
18
|
-
self.
|
|
19
|
-
|
|
20
|
-
self.title = layout.title.text
|
|
20
|
+
self.layout = layout
|
|
21
|
+
|
|
21
22
|
self.options = {}
|
|
22
23
|
if isinstance(axis_options, dict):
|
|
23
24
|
self.options = axis_options
|
|
@@ -31,41 +32,14 @@ class Axis():
|
|
|
31
32
|
self.options[option] = None
|
|
32
33
|
self.environment = "axis"
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
self.add_option("hide y axis", None)
|
|
35
|
+
self.xticks = None
|
|
36
|
+
|
|
37
|
+
self.treat_axis_layout()
|
|
38
|
+
self.treat_background_layout(colors_set)
|
|
39
|
+
self.treat_bar_layout()
|
|
40
40
|
|
|
41
|
-
# Handle log axes
|
|
42
|
-
if layout.xaxis.type == "log":
|
|
43
|
-
self.add_option("xmode", "log")
|
|
44
|
-
if layout.yaxis.type == "log":
|
|
45
|
-
self.add_option("ymode", "log")
|
|
46
41
|
|
|
47
|
-
# Handle range
|
|
48
|
-
# In log mode, the range is the exponent of the range : https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-range
|
|
49
|
-
# For more information, refer to documentation https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-autorange
|
|
50
|
-
if layout.xaxis.autorange is False or layout.xaxis.range is not None:
|
|
51
|
-
self.add_option("xmin", layout.xaxis.range[0] if layout.xaxis.type != "log" else 10**layout.xaxis.range[0])
|
|
52
|
-
self.add_option("xmax", layout.xaxis.range[1] if layout.xaxis.type != "log" else 10**layout.xaxis.range[1])
|
|
53
|
-
if layout.yaxis.autorange is False or layout.yaxis.range is not None:
|
|
54
|
-
self.add_option("ymin", layout.yaxis.range[0] if layout.yaxis.type != "log" else 10**layout.yaxis.range[0])
|
|
55
|
-
self.add_option("ymax", layout.yaxis.range[1] if layout.yaxis.type != "log" else 10**layout.yaxis.range[1])
|
|
56
|
-
if layout.xaxis.autorange == "reversed":
|
|
57
|
-
self.add_option("x dir", "reverse")
|
|
58
|
-
if layout.yaxis.autorange == "reversed":
|
|
59
|
-
self.add_option("y dir", "reverse")
|
|
60
42
|
|
|
61
|
-
if layout.plot_bgcolor is not None:
|
|
62
|
-
bg_color = convert_color(layout.plot_bgcolor)
|
|
63
|
-
colors_set.add(bg_color[:3])
|
|
64
|
-
opacity = bg_color[3]
|
|
65
|
-
if opacity < 1:
|
|
66
|
-
self.add_option("axis background/.style", f"{{fill={bg_color[0]}, opacity={opacity}}}")
|
|
67
|
-
else:
|
|
68
|
-
self.add_option("axis background/.style", f"{{fill={bg_color[0]}}}")
|
|
69
43
|
|
|
70
44
|
def set_x_label(self, x_label):
|
|
71
45
|
"""Set the x label.
|
|
@@ -125,3 +99,79 @@ class Axis():
|
|
|
125
99
|
self.options["ylabel"] = sanitize_TeX_text(self.y_label)
|
|
126
100
|
options_str = option_dict_to_str(self.options, sep="\n")
|
|
127
101
|
return options_str
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def treat_axis_layout(self):
|
|
105
|
+
"""Treat the layout of the axis."""
|
|
106
|
+
|
|
107
|
+
self.set_x_label(self.layout.xaxis.title.text)
|
|
108
|
+
self.set_y_label(self.layout.yaxis.title.text)
|
|
109
|
+
self.title = self.layout.title.text
|
|
110
|
+
|
|
111
|
+
if self.layout.xaxis.visible is False:
|
|
112
|
+
self.x_label = None
|
|
113
|
+
self.add_option("hide x axis", None)
|
|
114
|
+
if self.layout.yaxis.visible is False:
|
|
115
|
+
self.y_label = None
|
|
116
|
+
self.add_option("hide y axis", None)
|
|
117
|
+
|
|
118
|
+
# Handle log axes
|
|
119
|
+
if self.layout.xaxis.type == "log":
|
|
120
|
+
self.add_option("xmode", "log")
|
|
121
|
+
if self.layout.yaxis.type == "log":
|
|
122
|
+
self.add_option("ymode", "log")
|
|
123
|
+
|
|
124
|
+
# Handle range
|
|
125
|
+
# In log mode, the range is the exponent of the range : https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-range
|
|
126
|
+
# For more information, refer to documentation https://plotly.com/python/reference/layout/xaxis/#layout-xaxis-autorange
|
|
127
|
+
if self.layout.xaxis.autorange is False or self.layout.xaxis.range is not None:
|
|
128
|
+
self.add_option("xmin", self.layout.xaxis.range[0] if self.layout.xaxis.type != "log" else 10**self.layout.xaxis.range[0])
|
|
129
|
+
self.add_option("xmax", self.layout.xaxis.range[1] if self.layout.xaxis.type != "log" else 10**self.layout.xaxis.range[1])
|
|
130
|
+
if self.layout.yaxis.autorange is False or self.layout.yaxis.range is not None:
|
|
131
|
+
self.add_option("ymin", self.layout.yaxis.range[0] if self.layout.yaxis.type != "log" else 10**self.layout.yaxis.range[0])
|
|
132
|
+
self.add_option("ymax", self.layout.yaxis.range[1] if self.layout.yaxis.type != "log" else 10**self.layout.yaxis.range[1])
|
|
133
|
+
if self.layout.xaxis.autorange == "reversed":
|
|
134
|
+
self.add_option("x dir", "reverse")
|
|
135
|
+
if self.layout.yaxis.autorange == "reversed":
|
|
136
|
+
self.add_option("y dir", "reverse")
|
|
137
|
+
|
|
138
|
+
if self.layout.xaxis.showline == False:
|
|
139
|
+
self.add_option("axis x line", "none")
|
|
140
|
+
if self.layout.yaxis.showline == False:
|
|
141
|
+
self.add_option("axis y line", "none")
|
|
142
|
+
if self.layout.xaxis.categoryorder == "array":
|
|
143
|
+
self.xticks = self.layout.xaxis.categoryarray
|
|
144
|
+
ticks, ticklabels = get_ticks_str(self.layout.xaxis.categoryarray)
|
|
145
|
+
self.add_option("xtick", ticks)
|
|
146
|
+
self.add_option("xticklabels", ticklabels)
|
|
147
|
+
|
|
148
|
+
if self.layout.xaxis.categoryorder != "trace" or self.layout.yaxis.categoryorder != "trace" or self.layout.xaxis.categoryorder != "total descending":
|
|
149
|
+
warn("The categoryorder option is not supported (yet 🤞) for the axis environment.")
|
|
150
|
+
|
|
151
|
+
if self.layout.xaxis.showgrid:
|
|
152
|
+
self.add_option("xmajorgrids", None)
|
|
153
|
+
if self.layout.yaxis.showgrid:
|
|
154
|
+
self.add_option("ymajorgrids", None)
|
|
155
|
+
if self.layout.xaxis.ticklen is not None:
|
|
156
|
+
self.add_option("tickwidth", self.layout.xaxis.ticklen)
|
|
157
|
+
if self.layout.yaxis.ticklen is not None:
|
|
158
|
+
self.add_option("tickwidth", self.layout.yaxis.ticklen)
|
|
159
|
+
|
|
160
|
+
if (m := self.layout.xaxis.minor) is not None:
|
|
161
|
+
if m.showgrid:
|
|
162
|
+
self.add_option("xminorgrids", None)
|
|
163
|
+
if m.ticklen is not None:
|
|
164
|
+
self.add_option("subtickwidth", m.ticklen)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def treat_background_layout(self, colors_set):
|
|
168
|
+
if self.layout.plot_bgcolor is not None:
|
|
169
|
+
bg_color = convert_color(self.layout.plot_bgcolor)
|
|
170
|
+
colors_set.add(bg_color[:3])
|
|
171
|
+
opacity = bg_color[3]
|
|
172
|
+
self.add_option("axis background/.style", f"{{fill={bg_color[0]}}}")
|
|
173
|
+
|
|
174
|
+
def treat_bar_layout(self):
|
|
175
|
+
if (barmode := self.layout.barmode) is not None:
|
|
176
|
+
if barmode == "stack":
|
|
177
|
+
self.add_option("ybar stacked", None)
|
|
@@ -140,6 +140,6 @@ def draw_heatmap(data, fig, img_name, axis: Axis):
|
|
|
140
140
|
axis.add_option("tick align", "outside")
|
|
141
141
|
axis.add_option("tick pos", "left")
|
|
142
142
|
|
|
143
|
-
code += tex_addplot(img_name, type="graphics", type_options=f"includegraphics cmd
|
|
143
|
+
code += tex_addplot(img_name, type="graphics", type_options=f"includegraphics cmd=\\pgfimage,xmin={xmin}, xmax={xmax}, ymin={ymin}, ymax={ymax}")
|
|
144
144
|
|
|
145
145
|
return code
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from ._axis import Axis
|
|
2
|
+
from ._utils import get_ticks_str, option_dict_to_str
|
|
3
|
+
from ._tex import tex_addplot
|
|
4
|
+
from ._color import convert_color
|
|
5
|
+
import numbers
|
|
6
|
+
from warnings import warn
|
|
7
|
+
|
|
8
|
+
def formalize_data(data, axis:Axis, row_sep="\\\\"):
|
|
9
|
+
"""Formalize the data for the histogram trace.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
data
|
|
14
|
+
data from Plotly figure
|
|
15
|
+
|
|
16
|
+
Returns
|
|
17
|
+
-------
|
|
18
|
+
formalized data
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
data_str = f"data{row_sep}\n"
|
|
22
|
+
if isinstance(data[0], numbers.Number):
|
|
23
|
+
for x in data:
|
|
24
|
+
data_str += "{}{} ".format(x, row_sep)
|
|
25
|
+
|
|
26
|
+
else:
|
|
27
|
+
flag_axis = True
|
|
28
|
+
if axis.xticks is not None:
|
|
29
|
+
flag_axis = False
|
|
30
|
+
data_names = axis.xticks
|
|
31
|
+
else: data_names = []
|
|
32
|
+
|
|
33
|
+
for x in data:
|
|
34
|
+
if x not in data_names:
|
|
35
|
+
data_names.append(x)
|
|
36
|
+
data_str += f"{data_names.index(x)}{row_sep} "
|
|
37
|
+
if flag_axis:
|
|
38
|
+
ticks, ticklabels = get_ticks_str(data_names)
|
|
39
|
+
axis.add_option("xtick", ticks)
|
|
40
|
+
axis.add_option("xticklabels", ticklabels)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
return data_str
|
|
44
|
+
|
|
45
|
+
def draw_histogram(trace, axis: Axis, colors_set, row_sep="\\\\"):
|
|
46
|
+
"""
|
|
47
|
+
Draw a histogram and return the TikZ code.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
trace : plotly.graph_objs._histogram.Histogram
|
|
52
|
+
The histogram trace object containing data and style information.
|
|
53
|
+
axis : Axis
|
|
54
|
+
The axis object to which the histogram will be added.
|
|
55
|
+
colors_set : set
|
|
56
|
+
A set to keep track of colors used in the plot.
|
|
57
|
+
row_sep : str, optional
|
|
58
|
+
The row separator for the data table in TikZ, by default "\\\\"
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
str
|
|
63
|
+
A string containing the TikZ code for the histogram.
|
|
64
|
+
|
|
65
|
+
Notes
|
|
66
|
+
-----
|
|
67
|
+
- The function currently does not support 'percent', 'probability', and 'density' normalization for histograms.
|
|
68
|
+
- Text templates are not supported.
|
|
69
|
+
- Only 'count' aggregation function is supported; other functions need pre-treatment of data.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
code = ""
|
|
73
|
+
|
|
74
|
+
plot_options = {"hist": None}
|
|
75
|
+
type_options = {"row sep": row_sep, "y index": 0}
|
|
76
|
+
hist_options = {}
|
|
77
|
+
|
|
78
|
+
if trace.x is not None:
|
|
79
|
+
data_str = formalize_data(trace.x, axis, row_sep=row_sep)
|
|
80
|
+
axis.add_option("ybar", None)
|
|
81
|
+
elif trace.y is not None:
|
|
82
|
+
data_str = formalize_data(trace.y, axis, row_sep=row_sep)
|
|
83
|
+
axis.add_option("ybar", None)
|
|
84
|
+
axis.add_option("x filter/.expression", "rawy")
|
|
85
|
+
axis.add_option("y filter/.expression", "rawx")
|
|
86
|
+
hist_options["handler/.style"] = "{xbar interval}"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if trace.nbinsx is not None:
|
|
91
|
+
hist_options["bins"] = trace.nbinsx
|
|
92
|
+
|
|
93
|
+
if trace.histnorm == "percent":
|
|
94
|
+
warn(f"Sorry, I did not found an equivalent for histnorm='{trace.histnorm}' in Tikz. I you need this feature implemented, please open an issue, if possible with a general pgfplots code that would plot this :).\nFor now, the histogram will be plotted without normalization (as if histnorm='probability density').")
|
|
95
|
+
hist_options["density"] = None
|
|
96
|
+
elif trace.histnorm == "probability":
|
|
97
|
+
warn(f"Sorry, I did not found an equivalent for histnorm='{trace.histnorm}' in Tikz. I you need this feature implemented, please open an issue, if possible with a general pgfplots code that would plot this :).\nFor now, the histogram will be plotted without normalization (as if histnorm='probability density').")
|
|
98
|
+
hist_options["density"] = None
|
|
99
|
+
elif trace.histnorm == "density":
|
|
100
|
+
warn(f"Sorry, I did not found an equivalent for histnorm='{trace.histnorm}' in Tikz. I you need this feature implemented, please open an issue, if possible with a general pgfplots code that would plot this :).\nFor now, the histogram will be plotted without normalization (as if histnorm='probability density').")
|
|
101
|
+
hist_options["density"] = None
|
|
102
|
+
elif trace.histnorm == "probability density":
|
|
103
|
+
hist_options["density"] = None
|
|
104
|
+
|
|
105
|
+
if trace.cumulative.enabled:
|
|
106
|
+
hist_options["cumulative"] = None
|
|
107
|
+
|
|
108
|
+
if bool(hist_options):
|
|
109
|
+
plot_options["hist"] = f"{{{option_dict_to_str(hist_options)}}}"
|
|
110
|
+
|
|
111
|
+
if trace.texttemplate is not None:
|
|
112
|
+
warn("Text template is not supported yet.")
|
|
113
|
+
|
|
114
|
+
if (m := trace.marker) is not None:
|
|
115
|
+
|
|
116
|
+
if (c := m.color) is not None:
|
|
117
|
+
colors_set.add(convert_color(c))
|
|
118
|
+
plot_options["fill"] = convert_color(c)[0]
|
|
119
|
+
plot_options["color"] = convert_color(c)[0]
|
|
120
|
+
|
|
121
|
+
if m.opacity is not None:
|
|
122
|
+
plot_options["opacity"] = m.opacity
|
|
123
|
+
|
|
124
|
+
if (f := trace.histfunc) is not None:
|
|
125
|
+
if f != "count":
|
|
126
|
+
warn("To the best of our knowledge, other aggregate function than 'count' are not supported in pgfplots. Please pre-treat your data to display what you want. Sorry for the inconvenience.")
|
|
127
|
+
|
|
128
|
+
code += tex_addplot(data_str, type="table",
|
|
129
|
+
options=option_dict_to_str(plot_options), type_options=option_dict_to_str(type_options))
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
return code
|
|
@@ -3,6 +3,7 @@ from .__about__ import __version__
|
|
|
3
3
|
from ._tex import *
|
|
4
4
|
from ._scatter import draw_scatter2d
|
|
5
5
|
from ._heatmap import draw_heatmap
|
|
6
|
+
from ._histogram import draw_histogram
|
|
6
7
|
from ._axis import Axis
|
|
7
8
|
from ._color import *
|
|
8
9
|
from ._annotations import str_from_annotation
|
|
@@ -45,11 +46,6 @@ def get_tikz_code(
|
|
|
45
46
|
axis = Axis(figure_layout, colors_set, axis_options=axis_options)
|
|
46
47
|
data_container = DataContainer()
|
|
47
48
|
|
|
48
|
-
if figure_layout.xaxis.showline == False:
|
|
49
|
-
axis.add_option("axis x line", "none")
|
|
50
|
-
if figure_layout.yaxis.showline == False:
|
|
51
|
-
axis.add_option("axis y line", "none")
|
|
52
|
-
|
|
53
49
|
if len(figure_data) == 0:
|
|
54
50
|
warn("No data in figure.")
|
|
55
51
|
|
|
@@ -84,6 +80,12 @@ def get_tikz_code(
|
|
|
84
80
|
continue
|
|
85
81
|
data_str.append( draw_heatmap(trace, fig, img_name, axis) )
|
|
86
82
|
|
|
83
|
+
elif trace.type == "histogram":
|
|
84
|
+
|
|
85
|
+
data_str.append( draw_histogram(trace, axis, colors_set) )
|
|
86
|
+
if trace.name and trace['showlegend'] != False:
|
|
87
|
+
data_str.append( tex_add_legendentry(sanitize_TeX_text(trace.name)) )
|
|
88
|
+
|
|
87
89
|
else:
|
|
88
90
|
warn(f"Trace type {trace.type} is not supported yet.")
|
|
89
91
|
|
|
@@ -101,12 +103,12 @@ def get_tikz_code(
|
|
|
101
103
|
|
|
102
104
|
code += tex_begin_environment("tikzpicture", stack_env, options=tikz_options)
|
|
103
105
|
|
|
104
|
-
code += "\n"
|
|
106
|
+
if bool(colors_set): code += "\n"
|
|
105
107
|
color_list = list(colors_set)
|
|
106
108
|
color_list.sort()
|
|
107
109
|
for color in color_list:
|
|
108
110
|
code += tex_add_color(color[0], color[1], color[2])
|
|
109
|
-
code += "\n"
|
|
111
|
+
if bool(colors_set): code += "\n"
|
|
110
112
|
|
|
111
113
|
code += axis.open_environment(stack_env)
|
|
112
114
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from ._color import hex2rgb
|
|
2
|
+
from ._utils import sanitize_text
|
|
2
3
|
|
|
3
4
|
def tex_comment(text):
|
|
4
5
|
"""Create a LaTeX comment.
|
|
@@ -186,12 +187,40 @@ def tex_create_document(document_class="article", options=None, compatibility="n
|
|
|
186
187
|
code += "\\pgfplotsset{compat=" + compatibility + "}\n\n"
|
|
187
188
|
return code
|
|
188
189
|
|
|
190
|
+
# Pushed by error, not used yet
|
|
191
|
+
# def tex_add_fill_pattern(name, pattern, color, options=None):
|
|
192
|
+
# """Create a LaTeX fill pattern.
|
|
193
|
+
|
|
194
|
+
# Parameters
|
|
195
|
+
# ----------
|
|
196
|
+
# pattern
|
|
197
|
+
# pattern name
|
|
198
|
+
# color
|
|
199
|
+
# color string
|
|
200
|
+
# options, optional
|
|
201
|
+
# options given to the pattern, by default None
|
|
202
|
+
|
|
203
|
+
# Returns
|
|
204
|
+
# -------
|
|
205
|
+
# LaTeX code for the fill pattern
|
|
206
|
+
# """
|
|
207
|
+
# print("pattern: ", pattern)
|
|
208
|
+
# code = f"\\addplot[color={color}]\n"
|
|
209
|
+
# code += "fill between[of={name} and axis"
|
|
210
|
+
# if options is not None:
|
|
211
|
+
# code += f",{options}"
|
|
212
|
+
# code += f"];\n"
|
|
213
|
+
# return code
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
189
217
|
|
|
190
218
|
def tex_text(text):
|
|
191
219
|
"""Convert a string to LaTeX,
|
|
192
220
|
escaping the special characters %, _, &, #, $, {, }, ~.
|
|
193
221
|
"""
|
|
194
|
-
|
|
222
|
+
text_san = sanitize_text(text, keep_space=True)
|
|
223
|
+
return text_san.replace("%", "\\%").replace("_", "\\_").replace("&", "\\&").replace("#", "\\#").replace("$", "\\$").replace("{", "\\{").replace("}", "\\}").replace("~", "\\textasciitilde ")
|
|
195
224
|
|
|
196
225
|
def get_tikz_colorscale(colorscale, name="mycolor"):
|
|
197
226
|
|
|
@@ -41,10 +41,36 @@ def replace_all_mounts(text):
|
|
|
41
41
|
return pattern_mounts.sub(lambda m: rep_mounts[re.escape(m.group(0))], text)
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def sanitize_text(text: str):
|
|
45
|
-
|
|
44
|
+
def sanitize_text(text: str, keep_space=False):
|
|
45
|
+
"""
|
|
46
|
+
Sanitize the input text by removing or replacing unwanted characters.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
text (str): The input text to be sanitized.
|
|
51
|
+
keep_space (bool, optional): If True, spaces will be preserved in the sanitized text.
|
|
52
|
+
If False, spaces will be removed. Defaults to False.
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
str: The sanitized text.
|
|
57
|
+
"""
|
|
58
|
+
return "".join(sanitize_char(ch, keep_space=keep_space) for ch in text)
|
|
59
|
+
|
|
60
|
+
def sanitize_char(ch, keep_space=False):
|
|
61
|
+
"""
|
|
62
|
+
Sanitize a character by converting it to a hexadecimal representation if it is a special character, non-ASCII, or non-printable.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
ch (str): The character to sanitize.
|
|
67
|
+
keep_space (bool, optional): If True, spaces will be kept as is. Defaults to False.
|
|
46
68
|
|
|
47
|
-
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
str: The sanitized character or its hexadecimal representation.
|
|
72
|
+
"""
|
|
73
|
+
if keep_space and ch == " ": return " "
|
|
48
74
|
if ch in "[]{}= ": return f"x{ord(ch):x}"
|
|
49
75
|
# if not ascii, return hex
|
|
50
76
|
if ord(ch) > 127: return f"x{ord(ch):x}"
|
|
@@ -113,7 +139,26 @@ def option_dict_to_str(options_dict, sep=" "):
|
|
|
113
139
|
return None
|
|
114
140
|
return options.strip()[:-1]
|
|
115
141
|
|
|
116
|
-
def get_ticks_str(data, nticks):
|
|
142
|
+
def get_ticks_str(data, nticks=None):
|
|
143
|
+
"""Get the ticks and ticklabels for the axis.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
data
|
|
148
|
+
data to be plotted
|
|
149
|
+
nticks
|
|
150
|
+
number of ticks
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
tuple
|
|
155
|
+
ticks and ticklabels
|
|
156
|
+
|
|
157
|
+
Examples
|
|
158
|
+
--------
|
|
159
|
+
>>> get_ticks_str(["Sun", "Sat", "Thur", "Fri"])
|
|
160
|
+
({0,1,2,3}, {"Sun", "Sat", "Thur", "Fri"})
|
|
161
|
+
"""
|
|
117
162
|
indices = np.arange(len(data))
|
|
118
163
|
if nticks is not None:
|
|
119
164
|
data_ = data[::len(data)//(nticks-1)]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: tikzplotly
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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)
|
|
@@ -30,9 +30,11 @@ Keywords: plotly,latex,tikz,figure,conversion,graphics
|
|
|
30
30
|
Classifier: Development Status :: 5 - Production/Stable
|
|
31
31
|
Classifier: Programming Language :: Python
|
|
32
32
|
Classifier: Programming Language :: Python :: 3
|
|
33
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
34
33
|
Classifier: Programming Language :: Python :: 3.9
|
|
35
34
|
Classifier: Programming Language :: Python :: 3.10
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
38
|
Classifier: License :: OSI Approved :: MIT License
|
|
37
39
|
Classifier: Operating System :: OS Independent
|
|
38
40
|
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
|
|
@@ -45,11 +47,15 @@ Requires-Dist: pillow
|
|
|
45
47
|
Provides-Extra: dev
|
|
46
48
|
Requires-Dist: pandas; extra == "dev"
|
|
47
49
|
|
|
48
|
-

|
|
51
|
+
|
|
49
52
|
|
|
50
53
|
[](https://pypi.org/project/tikzplotly)
|
|
54
|
+
[](https://pypi.org/project/tikzplotly)
|
|
55
|
+
[](https://pypi.org/project/tikzplotly)
|
|
51
56
|
[](https://pypi.org/pypi/tikzplotly/)
|
|
52
57
|
|
|
58
|
+
[](https://github.com/thomas-saigre/tikzplotly/releases)
|
|
53
59
|
[](https://github.com/thomas-saigre/tikzplotly/issues)
|
|
54
60
|
[](https://codecov.io/gh/thomas-saigre/tikzplotly)
|
|
55
61
|

|
|
@@ -142,8 +148,7 @@ To correctly compile the document, you will need to add the following packages t
|
|
|
142
148
|
|
|
143
149
|
* This module is in development and new features are added bit by bit, when needed. If you have a feature request, please open an issue with the plotly figure you want to convert and the desired output.
|
|
144
150
|
You can also submit a pull request with the desired feature !
|
|
145
|
-
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers.
|
|
146
|
-
* More details in [doc/NB.md](doc/NB.md).
|
|
151
|
+
* Some feature can result in different output between the plotly figure and the tikz figure, for instance the size of markers, more details can be found in the documentation.
|
|
147
152
|
|
|
148
153
|
|
|
149
154
|
## References
|
|
@@ -2,6 +2,7 @@ LICENSE
|
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
4
|
src/tests/test_heatmaps.py
|
|
5
|
+
src/tests/test_histograms.py
|
|
5
6
|
src/tests/test_line_charts.py
|
|
6
7
|
src/tests/test_markers.py
|
|
7
8
|
src/tikzplotly/__about__.py
|
|
@@ -13,6 +14,7 @@ src/tikzplotly/_dash.py
|
|
|
13
14
|
src/tikzplotly/_data.py
|
|
14
15
|
src/tikzplotly/_dataContainer.py
|
|
15
16
|
src/tikzplotly/_heatmap.py
|
|
17
|
+
src/tikzplotly/_histogram.py
|
|
16
18
|
src/tikzplotly/_marker.py
|
|
17
19
|
src/tikzplotly/_save.py
|
|
18
20
|
src/tikzplotly/_scatter.py
|
|
@@ -24,6 +26,7 @@ src/tikzplotly.egg-info/dependency_links.txt
|
|
|
24
26
|
src/tikzplotly.egg-info/requires.txt
|
|
25
27
|
src/tikzplotly.egg-info/top_level.txt
|
|
26
28
|
tests/test_heatmap.py
|
|
29
|
+
tests/test_histograms.py
|
|
27
30
|
tests/test_markers.py
|
|
28
31
|
tests/test_scatter.py
|
|
29
32
|
tests/test_tikzplotly.py
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import plotly.express as px
|
|
2
|
+
import plotly.graph_objects as go
|
|
3
|
+
import numpy as np
|
|
4
|
+
import os
|
|
5
|
+
from .helpers import assert_equality
|
|
6
|
+
import pathlib
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
this_dir = pathlib.Path(__file__).resolve().parent
|
|
10
|
+
test_name = "test_histograms"
|
|
11
|
+
pathlib.Path("/tmp/tikzplotly").mkdir(parents=True, exist_ok=True)
|
|
12
|
+
|
|
13
|
+
def plot_1():
|
|
14
|
+
df = px.data.tips()
|
|
15
|
+
fig = px.histogram(df, x="total_bill", nbins=20)
|
|
16
|
+
return fig
|
|
17
|
+
|
|
18
|
+
def plot_2():
|
|
19
|
+
np.random.seed(0)
|
|
20
|
+
y = np.random.randn(100)
|
|
21
|
+
fig = go.Figure(data=[go.Histogram(y=y)])
|
|
22
|
+
return fig
|
|
23
|
+
|
|
24
|
+
def plot_3():
|
|
25
|
+
df = px.data.tips()
|
|
26
|
+
fig = px.histogram(df, x="day", category_orders=dict(day=["Thur", "Fri", "Sat", "Sun"]), opacity=0.8)
|
|
27
|
+
return fig
|
|
28
|
+
|
|
29
|
+
def plot_4(histnorm):
|
|
30
|
+
np.random.seed(0)
|
|
31
|
+
x = np.random.randn(100)
|
|
32
|
+
fig = go.Figure(data=[go.Histogram(x=x, histnorm=histnorm)])
|
|
33
|
+
return fig
|
|
34
|
+
|
|
35
|
+
def plot_5():
|
|
36
|
+
np.random.seed(0)
|
|
37
|
+
x = np.random.randn(100)
|
|
38
|
+
fig = go.Figure(data=[go.Histogram(x=x, cumulative_enabled=True)])
|
|
39
|
+
return fig
|
|
40
|
+
|
|
41
|
+
def plot_6():
|
|
42
|
+
np.random.seed(0)
|
|
43
|
+
x0 = np.random.randn(100)
|
|
44
|
+
x1 = np.random.randn(100)
|
|
45
|
+
|
|
46
|
+
fig = go.Figure()
|
|
47
|
+
fig.add_trace(go.Histogram(x=x0))
|
|
48
|
+
fig.add_trace(go.Histogram(x=x1))
|
|
49
|
+
|
|
50
|
+
fig.update_layout(barmode='stack')
|
|
51
|
+
return fig
|
|
52
|
+
|
|
53
|
+
def plot_7():
|
|
54
|
+
df = px.data.tips()
|
|
55
|
+
fig = px.histogram(df, x="total_bill", y="tip", histfunc="avg", nbins=8, text_auto=True)
|
|
56
|
+
return fig
|
|
57
|
+
|
|
58
|
+
def plot_8():
|
|
59
|
+
df = px.data.tips()
|
|
60
|
+
fig = px.histogram(df, x="total_bill", color="sex")
|
|
61
|
+
return fig
|
|
62
|
+
|
|
63
|
+
def plot_9():
|
|
64
|
+
np.random.seed(0)
|
|
65
|
+
x_data = np.random.choice(["A", "B", "C", "D"], size=20, p=[0.4, 0.2, 0.3, 0.1])
|
|
66
|
+
fig = px.histogram(x=x_data)
|
|
67
|
+
return fig
|
|
68
|
+
|
|
69
|
+
def test_1():
|
|
70
|
+
assert_equality(plot_1(), os.path.join(this_dir, test_name, test_name + "_1_reference.tex"))
|
|
71
|
+
|
|
72
|
+
def test_2():
|
|
73
|
+
assert_equality(plot_2(), os.path.join(this_dir, test_name, test_name + "_2_reference.tex"))
|
|
74
|
+
|
|
75
|
+
def test_3():
|
|
76
|
+
assert_equality(plot_3(), os.path.join(this_dir, test_name, test_name + "_3_reference.tex"))
|
|
77
|
+
|
|
78
|
+
@pytest.mark.parametrize("histnorm", ["percent", "probability", "density", "probability density"])
|
|
79
|
+
def test_4(histnorm):
|
|
80
|
+
assert_equality(plot_4(histnorm), os.path.join(this_dir, test_name, test_name + "_4_reference.tex"))
|
|
81
|
+
|
|
82
|
+
def test_5():
|
|
83
|
+
assert_equality(plot_5(), os.path.join(this_dir, test_name, test_name + "_5_reference.tex"))
|
|
84
|
+
|
|
85
|
+
def test_6():
|
|
86
|
+
assert_equality(plot_6(), os.path.join(this_dir, test_name, test_name + "_6_reference.tex"))
|
|
87
|
+
|
|
88
|
+
def test_7():
|
|
89
|
+
assert_equality(plot_7(), os.path.join(this_dir, test_name, test_name + "_7_reference.tex"))
|
|
90
|
+
|
|
91
|
+
def test_8():
|
|
92
|
+
assert_equality(plot_8(), os.path.join(this_dir, test_name, test_name + "_8_reference.tex"))
|
|
93
|
+
|
|
94
|
+
def test_9():
|
|
95
|
+
assert_equality(plot_9(), os.path.join(this_dir, test_name, test_name + "_9_reference.tex"))
|
|
@@ -28,7 +28,7 @@ def plot_3():
|
|
|
28
28
|
return fig
|
|
29
29
|
|
|
30
30
|
def plot_4():
|
|
31
|
-
labels = ['
|
|
31
|
+
labels = ['𝕋elevision', 'Newspaper', 'Internet', 'Radio']
|
|
32
32
|
colors = ['rgb(67,67,67)', 'rgb(115,115,115)', 'rgb(49,130,189)', 'rgb(189,189,189)']
|
|
33
33
|
|
|
34
34
|
mode_size = [4, 4, 6, 4]
|
|
@@ -62,7 +62,7 @@ def plot_4():
|
|
|
62
62
|
|
|
63
63
|
fig.update_layout(
|
|
64
64
|
xaxis=dict(
|
|
65
|
-
showline=
|
|
65
|
+
showline=False,
|
|
66
66
|
showgrid=False,
|
|
67
67
|
showticklabels=True,
|
|
68
68
|
linecolor='rgb(204, 204, 204)',
|
|
@@ -143,6 +143,63 @@ def plot_6(x=True, y=True):
|
|
|
143
143
|
if y: fig.data[0].y = None
|
|
144
144
|
return fig
|
|
145
145
|
|
|
146
|
+
def plot_7():
|
|
147
|
+
month = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
|
|
148
|
+
'August', 'September', 'October', 'November', 'December']
|
|
149
|
+
high_2000 = [32.5, 37.6, 49.9, 53.0, 69.1, 75.4, 76.5, 76.6, 70.7, 60.6, 45.1, 29.3]
|
|
150
|
+
low_2000 = [13.8, 22.3, 32.5, 37.2, 49.9, 56.1, 57.7, 58.3, 51.2, 42.8, 31.6, 15.9]
|
|
151
|
+
high_2007 = [36.5, 26.6, 43.6, 52.3, 71.5, 81.4, 80.5, 82.2, 76.0, 67.3, 46.1, 35.0]
|
|
152
|
+
low_2007 = [23.6, 14.0, 27.0, 36.8, 47.6, 57.7, 58.9, 61.2, 53.3, 48.5, 31.0, 23.6]
|
|
153
|
+
high_2014 = [28.8, 28.5, 37.0, 56.8, 69.7, 79.7, 78.5, 77.8, 74.1, 62.6, 45.3, 39.9]
|
|
154
|
+
low_2014 = [12.7, 14.3, 18.6, 35.5, 49.9, 58.0, 60.0, 58.6, 51.7, 45.2, 32.2, 29.1]
|
|
155
|
+
|
|
156
|
+
fig = go.Figure()
|
|
157
|
+
# Create and style traces
|
|
158
|
+
fig.add_trace(go.Scatter(x=month, y=high_2014, name='High 2014',
|
|
159
|
+
line=dict(color='firebrick', width=1.5)))
|
|
160
|
+
fig.add_trace(go.Scatter(x=month, y=low_2014, name = 'Low 2014',
|
|
161
|
+
line=dict(color='royalblue', width=1.5)))
|
|
162
|
+
fig.add_trace(go.Scatter(x=month, y=high_2007, name='High 2007',
|
|
163
|
+
line=dict(color='firebrick', width=1.5,
|
|
164
|
+
dash='dash') # dash options include 'dash', 'dot', and 'dashdot'
|
|
165
|
+
))
|
|
166
|
+
fig.add_trace(go.Scatter(x=month, y=low_2007, name='Low 2007',
|
|
167
|
+
line = dict(color='royalblue', width=1.5, dash='dash')))
|
|
168
|
+
fig.add_trace(go.Scatter(x=month, y=high_2000, name='High 2000',
|
|
169
|
+
line = dict(color='firebrick', width=1.5, dash='dot')))
|
|
170
|
+
fig.add_trace(go.Scatter(x=month, y=low_2000, name='Low 2000',
|
|
171
|
+
line=dict(color='royalblue', width=1.5, dash='dot')))
|
|
172
|
+
|
|
173
|
+
fig.update_layout(title='Average High and Low Temperatures in New York',
|
|
174
|
+
xaxis_title='Month',
|
|
175
|
+
yaxis_title='Temperature (degrees F)')
|
|
176
|
+
return fig
|
|
177
|
+
|
|
178
|
+
def plot_8():
|
|
179
|
+
df = px.data.gapminder().query("year == 2007")
|
|
180
|
+
fig = px.scatter(df, x="gdpPercap", y="lifeExp", hover_name="country",
|
|
181
|
+
log_x=True, range_x=[1,100000], range_y=[0,100])
|
|
182
|
+
fig.update_xaxes(showgrid=True, minor=dict(ticks="inside", ticklen=6, showgrid=True), ticklen=6)
|
|
183
|
+
fig.update_yaxes(showgrid=True, ticklen=6)
|
|
184
|
+
return fig
|
|
185
|
+
|
|
186
|
+
def plot_9():
|
|
187
|
+
np.random.seed(0)
|
|
188
|
+
x = np.random.lognormal(mean=0.0, sigma=1.0, size=50)
|
|
189
|
+
y = np.random.lognormal(mean=0.0, sigma=1.0, size=50)
|
|
190
|
+
fig = px.scatter(x=x, y=y, labels={'x':'log(x)', 'y':'log(y)'})
|
|
191
|
+
fig.update_xaxes(type="log", visible=False)
|
|
192
|
+
fig.update_yaxes(type="log", visible=False)
|
|
193
|
+
return fig
|
|
194
|
+
|
|
195
|
+
def plot_10():
|
|
196
|
+
df = px.data.gapminder().query("continent == 'Oceania'")
|
|
197
|
+
fig = px.line(df, x='year', y='lifeExp', color='country', markers=True)
|
|
198
|
+
fig.update_xaxes(autorange="reversed")
|
|
199
|
+
fig.update_yaxes(autorange="reversed")
|
|
200
|
+
return fig
|
|
201
|
+
|
|
202
|
+
|
|
146
203
|
def test_1():
|
|
147
204
|
assert_equality(plot_1(), os.path.join(this_dir, test_name, test_name + "_1_reference.tex"))
|
|
148
205
|
|
|
@@ -160,4 +217,16 @@ def test_5():
|
|
|
160
217
|
|
|
161
218
|
@pytest.mark.parametrize("x, y", [(True, True), (True, False), (False, True)])
|
|
162
219
|
def test_6(x, y):
|
|
163
|
-
assert_equality(plot_6(x, y), os.path.join(this_dir, test_name, test_name + f"_6_{x}_{y}_reference.tex"))
|
|
220
|
+
assert_equality(plot_6(x, y), os.path.join(this_dir, test_name, test_name + f"_6_{x}_{y}_reference.tex"))
|
|
221
|
+
|
|
222
|
+
def test_7():
|
|
223
|
+
assert_equality(plot_7(), os.path.join(this_dir, test_name, test_name + "_7_reference.tex"))
|
|
224
|
+
|
|
225
|
+
def test_8():
|
|
226
|
+
assert_equality(plot_8(), os.path.join(this_dir, test_name, test_name + "_8_reference.tex"))
|
|
227
|
+
|
|
228
|
+
def test_9():
|
|
229
|
+
assert_equality(plot_9(), os.path.join(this_dir, test_name, test_name + "_9_reference.tex"))
|
|
230
|
+
|
|
231
|
+
def test_10():
|
|
232
|
+
assert_equality(plot_10(), os.path.join(this_dir, test_name, test_name + "_10_reference.tex"))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import tikzplotly
|
|
2
|
+
from tikzplotly._tex import *
|
|
3
|
+
import os
|
|
4
|
+
import plotly.express as px
|
|
5
|
+
import pytest
|
|
6
|
+
import pathlib
|
|
7
|
+
from .helpers import compare_two_files
|
|
8
|
+
|
|
9
|
+
this_dir = pathlib.Path(__file__).resolve().parent
|
|
10
|
+
|
|
11
|
+
@pytest.mark.parametrize("axis_options", ["None", "dict", "str"])
|
|
12
|
+
def test_tikzplotly(axis_options):
|
|
13
|
+
fig = px.scatter(x=[1, 2, 3], y=[1, 2, 3])
|
|
14
|
+
if axis_options == "dict":
|
|
15
|
+
tikzplotly.save("/tmp/tikzplotly/test_tikzplotly_dict.tex", fig, axis_options={"xlabel": "x", "ylabel": "y"})
|
|
16
|
+
elif axis_options == "str":
|
|
17
|
+
tikzplotly.save("/tmp/tikzplotly/test_tikzplotly_str.tex", fig, axis_options="xlabel=x, ylabel=y, xmajorgrids")
|
|
18
|
+
else:
|
|
19
|
+
tikzplotly.save("/tmp/tikzplotly/test_tikzplotly_none.tex", fig)
|
|
20
|
+
|
|
21
|
+
def test_create_document():
|
|
22
|
+
main_tex_content = tex_create_document(compatibility="newest")
|
|
23
|
+
main_tex_content += "\\usepackage{graphicx}\n"
|
|
24
|
+
main_tex_content += "\n"
|
|
25
|
+
stack_env = []
|
|
26
|
+
main_tex_content += tex_begin_environment("document", stack_env) + '\n'
|
|
27
|
+
|
|
28
|
+
main_tex_content += tex_begin_environment("figure", stack_env)
|
|
29
|
+
main_tex_content += " \\includegraphics{example-image-a}\n"
|
|
30
|
+
main_tex_content += " \\caption{Test figure}\n"
|
|
31
|
+
main_tex_content += tex_end_environment(stack_env) + '\n'
|
|
32
|
+
|
|
33
|
+
main_tex_content += "\n" + tex_end_all_environment(stack_env)
|
|
34
|
+
|
|
35
|
+
main_tex_path = os.path.join("/tmp/tikzplotly", "test_create_document.tex")
|
|
36
|
+
with open(main_tex_path, "w") as f:
|
|
37
|
+
f.write(main_tex_content)
|
|
38
|
+
|
|
39
|
+
compare_two_files(main_tex_path, os.path.join(this_dir, "test_tikzplotly", "test_create_document.tex"))
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.7"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|